###############################################################################
#This is the SMESH change log. Do not modify because it is automatically
#created with :
-#cvs2cl.pl --accum -l "-b" -U users.cvs2cl --header header.cvs2cl -T -b --utc
+#cvs2cl.pl -l "-b" -U users.cvs2cl --header header.cvs2cl -T -b --utc
###############################################################################
-2004-03-23 13:25 tag V1_5_0
-
-2004-03-23 13:20 Jerome Robert <jerome.robert@eads.net>
-
- * INSTALL, bin/VERSION: Version 1.5.0.
-
-2004-03-23 09:53 Jerome Robert <jerome.robert@eads.net>
-
- * src/SMESHGUI/SMESHGUI.cxx: Add a MEDFILE attribut for selection
- in Efficas. Patch submited by P. Rascle on 2004-03-22.
- * src/SMDS/SMDS_Position.cxx: Fix bug SMESH5512 (Crash on DEBIAN
- woody, V1_4_0b).
-
-2004-03-16 12:51 Jerome Robert <jerome.robert@eads.net>
-
- * src/SMESHGUI/SMESHGUI_Swig.cxx: Fix bug SMESH5451: SMESH_mechanic
- script aborts.
- * doc/html/SMESHTutorial_1/: ControlFeature.png, ImportResult.png,
- MeshInit.png, MeshResult.png, MeshResult2.png, SMESHOverview.png,
- SMESHTutorial_1.html, SelectAlgorithms.png, SetColor.png,
- SubMeshContruction.png, SubShapesSelection.png: Add a small
- tutorial.
-
-2004-03-15 18:42 Jerome Robert <jerome.robert@eads.net>
-
- * Merge br_enable_import_mesh. Enable import mesh and save/load SMESH study.
-
-2004-02-02 16:43 Jerome Robert <jerome.robert@eads.net>
-
- * src/SMDS/SMDS_Mesh.cxx: Fix a bug (crash when adding an
- hexahedron from ids).
-
-2004-01-30 15:42 tag V1_4_0b
-
2004-01-30 13:18 Nicolas Rejneri <nicolas.rejneri@opencascade.com>
* doc/html/INPUT/: doxyfile, sources/static/tree.js: NRI : 1.4.0
-This is SMESH V1_5_0
+This is SMESH V2.0.0
Compatible with :
- GEOM V1_4_0
- KERNEL V1_4_0
- MED V1_4_0
+ GEOM V2_0_0
+ KERNEL V2_0_0
+ MED V2_0_0
@COMMENCE@
-SUBDIRS = idl src
+SUBDIRS = idl src doc
RESOURCES_FILES = \
delete.png \
mesh_info.png \
mesh_init.png \
mesh_length.png \
+mesh_free_edges.png \
+mesh_multi_edges.png \
mesh_line_n.png \
mesh_line.png \
mesh_move_node.png \
mesh_tree_hypo_segment.png \
mesh_tree_hypo_volume.png \
mesh_tree_mesh.png \
+mesh_tree_importedmesh.png \
mesh_tree_mesh_warn.png \
mesh_triangle_n.png \
mesh_triangle.png \
mesh_vertex_n.png \
mesh_vertex.png \
mesh_wireframe.png \
+mesh_points.png \
mesh_wrap.png \
+mesh_tree_group.png \
+mesh_edit_group.png \
+mesh_make_group.png \
ModuleMesh.png \
select1.png \
SMESH_en.xml \
+SMESH.config \
+StdMeshers.xml \
SMESHCatalog.xml \
flight_solid.brep
# test if SALOMEconfig.h has changed (contents)
salome_adm/unix/SALOMEconfig.ref: salome_adm/unix/SALOMEconfig.h
@if ! [ -a $@ ]; then \
- cp -p $< $@; \
+ cp -p -f $< $@; \
fi; \
if ! cmp $< $@; then \
- cp -p $< $@; \
+ cp -p -f $< $@; \
fi; \
include/salome/sstream: salome_adm/unix/sstream
$(INSTALL) -d $(includedir)
@for f in X $(include_list); do \
if test $$f != X; then \
- ($(INSTALL_DATA) $$f $(includedir)/. || exit 1); \
+ ($(INSTALL_DATA) -p $$f $(includedir)/. || exit 1); \
fi; \
done
else
AC_MSG_WARN("Cannot find compiled Geom module distribution")
fi
-
+
AC_MSG_RESULT(for Geom: $Geom_ok)
])dnl
AC_SUBST(MED_ROOT_DIR)
else
- AC_MSG_WARN("Cannot find compiled Med module distribution")
+ AC_MSG_WARN("Cannot find Med module sources")
fi
AC_MSG_RESULT(for Med: $Med_ok)
CXXFLAGS = @CXXFLAGS@
CXX_DEPEND_FLAG = @CXX_DEPEND_FLAG@
+# BOOST Library
+
+BOOST_CPPFLAGS = @BOOST_CPPFLAGS@
+
# JAVA
JAVA_INCLUDES = @JAVA_INCLUDES@
OMNIORB_IDL = @OMNIORB_IDL@
OMNIORB_IDLCXXFLAGS = @OMNIORB_IDLCXXFLAGS@
-OMNIORB_IDLPYFLAGS = @OMNIORB_IDLPYFLAGS@ -I$(top_srcdir)/idl -I$(top_builddir)/idl -I$(KERNEL_ROOT_DIR)/idl/salome -I$(GEOM_ROOT_DIR)/idl/salome -I$(MED_ROOT_DIR)/idl/salome
+OMNIORB_IDLPYFLAGS = @OMNIORB_IDLPYFLAGS@ -I$(top_srcdir)/idl -I$(top_builddir)/idl/salome \
+ -I$(KERNEL_ROOT_DIR)/idl/salome -I$(GEOM_ROOT_DIR)/idl/salome -I$(MED_ROOT_DIR)/idl/salome
OMNIORB_IDL_CLN_H = @OMNIORB_IDL_CLN_H@
OMNIORB_IDL_CLN_CXX = @OMNIORB_IDL_CLN_CXX@
CORBA_LIBS = @CORBA_LIBS@
CORBA_CXXFLAGS = @CORBA_CXXFLAGS@
-IDLCXXFLAGS = -bcxx @IDLCXXFLAGS@ -I$(top_srcdir)/idl -I$(top_builddir)/idl -I$(KERNEL_ROOT_DIR)/idl/salome -I$(GEOM_ROOT_DIR)/idl/salome -I$(MED_ROOT_DIR)/idl/salome
+IDLCXXFLAGS = -bcxx @IDLCXXFLAGS@ -I$(top_srcdir)/idl -I$(top_builddir)/idl/salome \
+ -I$(KERNEL_ROOT_DIR)/idl/salome -I$(GEOM_ROOT_DIR)/idl/salome -I$(MED_ROOT_DIR)/idl/salome
IDLPYFLAGS = @IDLPYFLAGS@
IDL = @IDL@
idldir=$(prefix)/idl/salome
sharedpydir=@libdir@/python$(PYTHON_VERSION)/site-packages/salome/shared_modules
-docdir=$(datadir)/doc
+docdir=${prefix}/doc/salome
#
# begin of package rules
#
-.PHONY: all lib bin inc resources tests install uninstall dep depend depend_idl cleandep mostlyclean clean distclean
+.PHONY: all lib bin inc resources docs tests install uninstall dep depend depend_idl cleandep mostlyclean clean distclean
.SUFFIXES: .cxx .cc .c .f .o .lo .idl .py .i .ui .po .qm
ac_cxx_partial_specialization.m4 check_opengl.m4 python.m4 \
ac_cxx_typename.m4 check_pthreads.m4 check_cas.m4 \
ac_cc_warnings.m4 check_qt.m4 check_med2.m4 \
-check_swig.m4
-
-#ifeq (@WITHNETGEN@,yes)
-# ACLOCAL_SRC += check_Netgen.m4
-#endif
+check_swig.m4 check_boost.m4
$(top_srcdir)/aclocal.m4: $(ACLOCAL_SRC:%=@KERNEL_ROOT_DIR@/salome_adm/unix/config_files/%)
cd $(top_srcdir) ; aclocal --acdir=adm_local/unix/config_files -I @KERNEL_ROOT_DIR@/salome_adm/unix/config_files
-THIS IS SALOME - SMESH VERSION: 1.5.0
+THIS IS SALOME - SMESH VERSION: 2.0.0
AC_CXX_HAVE_SSTREAM
+echo
+echo ---------------------------------------------
+echo BOOST Library
+echo ---------------------------------------------
+echo
+
+CHECK_BOOST
+
dnl
dnl ---------------------------------------------
dnl testing MPICH
CHECK_MED
-echo
-echo ---------------------------------------------
-echo Testing Netgen
-echo ---------------------------------------------
-echo
-
-CHECK_NETGEN
-
echo
echo ---------------------------------------------
echo Summary
echo
echo Configure
-variables="cc_ok lex_yacc_ok python_ok swig_ok threads_ok OpenGL_ok qt_ok vtk_ok hdf5_ok med2_ok omniORB_ok occ_ok doxygen_ok graphviz_ok Kernel_ok Geom_ok Med_ok Netgen_ok"
+variables="cc_ok boost_ok lex_yacc_ok python_ok swig_ok threads_ok OpenGL_ok qt_ok vtk_ok hdf5_ok med2_ok omniORB_ok occ_ok doxygen_ok graphviz_ok Kernel_ok Geom_ok Med_ok"
for var in $variables
do
fi
# make other build directories
-for rep in salome_adm adm_local doc bin/salome include/salome lib/salome share/salome/resources share/salome/doc idl
+for rep in salome_adm adm_local doc bin/salome include/salome lib/salome share/salome/resources idl
do
# if test ! -d $rep ; then
# eval mkdir $rep
dnl excluding .in files (treated in AC-OUTPUT below) and CVS
dnl directory
-cd bin
+mkdir -p bin/salome
+cd bin/salome
for i in $ROOT_SRCDIR/bin/*
do
local_bin=`echo $i | sed -e "s,$ROOT_SRCDIR,.,"`
case "$local_bin" in
*.in | *~) ;;
- ./bin/CVS) ;;
- *) ln -fs $i; echo $local_bin ;;
+ ./bin/CVS | ./bin/salome) ;;
+ *) /usr/bin/install -C $i .; echo $local_bin ;;
esac
done
cd $ROOT_BUILDDIR
merge_1_2_d: 2003-01-20 11:25
Branch to merge Release 1.2d of Salome Pro.
-
-V1_4_0b: 2004-01-30 15:42
- Pre-release of 1.4.0. Include the merge of the branch merge_1_2_d.
-
-V1_4_0_branch: 2004-01-30 15:42
- Maintenance branch for 1.4.0. This tag is equal to V1_4_0b.
-
-br_enable_import_mesh: 2004-02-16 10:00
- Branch on head after V1_4_0b. Development branch enable import mesh and save/load SMESH study. Initiated by Jerome Robert.
-
-br_geomclient_colocal: 2004-02-23 10:00
- Branch on br_enable_import_mesh. Development branch for colocalization. Initiated by Francis KLOSS.
-
-V1_4_0: 2004-03-23 11:40
- Release 1.4.0. Tag on V1_4_0_branch branch.
-
-V1_5_0: 2004-03-23 13:25
- Release 1.5.0. Tag on head. Include mesh import/export, save/load study, tutorial, bug corrected in V1_4_0.
srcdir=@srcdir@
VPATH=.:@srcdir@
-SUBDIRS=html
+SUBDIRS= salome
-doc:
+@COMMENCE@
+
+docs:
@@SETX@; for d in $(SUBDIRS); do \
(cd $$d && $(MAKE) $@) || exit 1; \
done
@@SETX@; for d in $(SUBDIRS); do \
(cd $$d && $(MAKE) $@) || exit 1; \
done
+
+uninstall:
+ @@SETX@; for d in $(SUBDIRS); do \
+ (cd $$d && $(MAKE) $@) || exit 1; \
+ done
#---------------------------------------------------------------------------
# General configuration options
#---------------------------------------------------------------------------
-PROJECT_NAME = "SALOME - SMESH - v.1.4.0"
+PROJECT_NAME = "SALOME - SMESH - v.1.3.0"
PROJECT_NUMBER = id#1.1
OUTPUT_DIRECTORY = ../
OUTPUT_LANGUAGE = English
-foldersTree = gFld("<b>SALOME v.1.4.0 </b>", "", "")
+foldersTree = gFld("<b>SALOME v.1.3.0 </b>", "", "")
insDoc(foldersTree, gLnk("Main Page", "", "main.html"))
aux1 = insFld(foldersTree, gFld("TUI Reference Guide", ""))
--- /dev/null
+%!PS-Adobe-3.0
+%%BoundingBox: 0 0 595 842
+%%Creator: OpenOffice.org 1.0.2
+%%For: nadir
+%%CreationDate: Tue Dec 9 10:49:18 2003
+%%Title: Proc?dure de rajout de DATA dans le produit SalomePro
+%%LanguageLevel: 2
+%%DocumentData: Clean7Bit
+%%Pages: (atend)
+%%PageOrder: Ascend
+%%EndComments
+%%BeginProlog
+/ISO1252Encoding [
+/.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef
+/.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef
+/.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef
+/.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef
+/space /exclam /quotedbl /numbersign /dollar /percent /ampersand /quotesingle
+/parenleft /parenright /asterisk /plus /comma /hyphen /period /slash
+/zero /one /two /three /four /five /six /seven
+/eight /nine /colon /semicolon /less /equal /greater /question
+/at /A /B /C /D /E /F /G
+/H /I /J /K /L /M /N /O
+/P /Q /R /S /T /U /V /W
+/X /Y /Z /bracketleft /backslash /bracketright /asciicircum /underscore
+/grave /a /b /c /d /e /f /g
+/h /i /j /k /l /m /n /o
+/p /q /r /s /t /u /v /w
+/x /y /z /braceleft /bar /braceright /asciitilde /unused
+/Euro /unused /quotesinglbase /florin /quotedblbase /ellipsis /dagger /daggerdbl
+/circumflex /perthousand /Scaron /guilsinglleft /OE /unused /Zcaron /unused
+/unused /quoteleft /quoteright /quotedblleft /quotedblright /bullet /endash /emdash
+/tilde /trademark /scaron /guilsinglright /oe /unused /zcaron /Ydieresis
+/space /exclamdown /cent /sterling /currency /yen /brokenbar /section
+/dieresis /copyright /ordfeminine /guillemotleft /logicalnot /hyphen /registered /macron
+/degree /plusminus /twosuperior /threesuperior /acute /mu /paragraph /periodcentered
+/cedilla /onesuperior /ordmasculine /guillemotright /onequarter /onehalf /threequarters /questiondown
+/Agrave /Aacute /Acircumflex /Atilde /Adieresis /Aring /AE /Ccedilla
+/Egrave /Eacute /Ecircumflex /Edieresis /Igrave /Iacute /Icircumflex /Idieresis
+/Eth /Ntilde /Ograve /Oacute /Ocircumflex /Otilde /Odieresis /multiply
+/Oslash /Ugrave /Uacute /Ucircumflex /Udieresis /Yacute /Thorn /germandbls
+/agrave /aacute /acircumflex /atilde /adieresis /aring /ae /ccedilla
+/egrave /eacute /ecircumflex /edieresis /igrave /iacute /icircumflex /idieresis
+/eth /ntilde /ograve /oacute /ocircumflex /otilde /odieresis /divide
+/oslash /ugrave /uacute /ucircumflex /udieresis /yacute /thorn /ydieresis] def
+
+/psp_definefont { exch dup findfont dup length dict begin { 1 index /FID ne
+{ def } { pop pop } ifelse } forall /Encoding 3 -1 roll def
+currentdict end exch pop definefont pop } def
+
+/pathdict dup 8 dict def load begin
+/rcmd { { currentfile 1 string readstring pop 0 get dup 32 gt { exit }
+{ pop } ifelse } loop dup 126 eq { pop exit } if 65 sub dup 16#3 and 1
+add exch dup 16#C and -2 bitshift 16#3 and 1 add exch 16#10 and 16#10
+eq 3 1 roll exch } def
+/rhex { dup 1 sub exch currentfile exch string readhexstring pop dup 0
+get dup 16#80 and 16#80 eq dup 3 1 roll { 16#7f and } if 2 index 0 3
+-1 roll put 3 1 roll 0 0 1 5 -1 roll { 2 index exch get add 256 mul }
+for 256 div exch pop exch { neg } if } def
+/xcmd { rcmd exch rhex exch rhex exch 5 -1 roll add exch 4 -1 roll add
+1 index 1 index 5 -1 roll { moveto } { lineto } ifelse } def end
+/readpath { 0 0 pathdict begin { xcmd } loop end pop pop } def
+
+systemdict /languagelevel known not {
+/xshow { exch dup length 0 1 3 -1 roll 1 sub { dup 3 index exch get
+exch 2 index exch get 1 string dup 0 4 -1 roll put currentpoint 3 -1
+roll show moveto 0 rmoveto } for pop pop } def
+/rectangle { 4 -2 roll moveto 1 index 0 rlineto 0 exch rlineto neg 0
+rlineto closepath } def
+/rectfill { rectangle fill } def
+/rectstroke { rectangle stroke } def } if
+
+/psp_lzwfilter { currentfile /ASCII85Decode filter /LZWDecode filter } def
+/psp_ascii85filter { currentfile /ASCII85Decode filter } def
+/psp_lzwstring { psp_lzwfilter 1024 string readstring } def
+/psp_ascii85string { psp_ascii85filter 1024 string readstring } def
+/psp_imagedict {
+/psp_bitspercomponent { 3 eq { 1 }{ 8 } ifelse } def
+/psp_decodearray { [ [0 1 0 1 0 1] [0 255] [0 1] [0 255] ] exch get }
+def 7 dict dup
+/ImageType 1 put dup
+/Width 7 -1 roll put dup
+/Height 5 index put dup
+/BitsPerComponent 4 index psp_bitspercomponent put dup
+/Decode 5 -1 roll psp_decodearray put dup
+/ImageMatrix [1 0 0 1 0 0] dup 5 8 -1 roll put put dup
+/DataSource 4 -1 roll 1 eq { psp_lzwfilter } { psp_ascii85filter } ifelse put
+} def
+%%EndProlog
+%%Page: 0 0
+%%PageBoundingBox: 18 18 577 824
+%%BeginSetup
+%
+%%BeginFeature: *PageSize A4
+<</PageSize [595 842] /ImagingBBox null>> setpagedevice
+%%EndFeature
+%%EndSetup
+%%BeginPageSetup
+%
+gsave
+[0.24 0 0 -0.24 18 824] concat
+gsave
+%%EndPageSetup
+%%BeginResource: font NimbusMonL-Regu
+%!PS-AdobeFont-1.0: NimbusMonL-Regu 1.05
+%%CreationDate: Wed Dec 22 1999
+% Copyright (URW)++,Copyright 1999 by (URW)++ Design & Development
+% (URW)++,Copyright 1999 by (URW)++ Design & Development
+% See the file PUBLIC (Aladdin Free Public License) for license conditions.
+% As a special exception, permission is granted to include this font
+% program in a Postscript or PDF file that consists of a document that
+% contains text to be displayed or printed using this font, regardless
+% of the conditions or license applying to the document itself.
+12 dict begin
+/FontInfo 10 dict dup begin
+/version (1.05) readonly def
+/Notice ((URW)++,Copyright 1999 by (URW)++ Design & Development. See the file PUBLIC (Aladdin Free Public License) for license conditions. As a special exception, permission is granted to include this font program in a Postscript or PDF file that consists of a document that contains text to be displayed or printed using this font, regardless of the conditions or license applying to the document itself.) readonly def
+/Copyright (Copyright (URW)++,Copyright 1999 by (URW)++ Design & Development) readonly def
+/FullName (Nimbus Mono L Regular) readonly def
+/FamilyName (Nimbus Mono L) readonly def
+/Weight (Regular) readonly def
+/ItalicAngle 0.0 def
+/isFixedPitch false def
+/UnderlinePosition -100 def
+/UnderlineThickness 50 def
+end readonly def
+/FontName /NimbusMonL-Regu def
+/PaintType 0 def
+/WMode 0 def
+/FontBBox {-12 -237 650 811} readonly def
+/FontType 1 def
+/FontMatrix [0.001 0.0 0.0 0.001 0.0 0.0] readonly def
+/Encoding StandardEncoding def
+/UniqueID 5020945 def
+currentdict end
+currentfile eexec
+E98D09D760A3C22CF119F9DC699A22C35B5B35ED6AA23593C76D54CABB5E942BF7D6DD84F1664B89
+699C74B472DE9F8E6DF925F6C4F204E9F1C639B4DBA988ED2AC419FF2B2BDE605B8EE3264EDD6641
+2D4F21C64AC522BDFC7C5502F9C3F3E5592B3B2093D33C9BFAEDD2D49E89AABAA832E23F062E91A2
+5032519D1868816E44B4E0747795003D7930299D6E1E2A5BFE0D595DC97E140989CE81D8D7F852FF
+9CDC7A1B1B598C69131DEE005B415805A16D8A123E6A2261C63C769D2F4B60FA2C438AD7D199D8E4
+5F7E7C9A605C8CA14E21FCD81C9A515FB8DB6F99604534D06EA9D87FE0FAA852899C9D0595C7A97E
+6C55F79FAC45CD38E87B10D210CE7501E88C8FCD3444354365FB893A12F596AE2C1E70D5819EE0D0
+87D10BF8DA96F3DABD5405D28C4228C6C31BA4052464859640933FEEFD8071C0C84CDD829A9B1D0B
+A01F25A4D50EE2EA2B45160CA6333B2D2800306ED2BEFDFE155E9D9F9342EB8D5B0ADBF2460CCC98
+643FB1287CCD28ABA7B5CAB92EC39EE2E918990372B16F8487EBA30EAE88708B6CF33B6C015D8096
+C7CFE2F139F52052E3925C0D50FD64CE68236D59CB83EF56BFC584150EC38065059F3308AD6F9A99
+F83EF4E6CB13855C8175E31417D190D036B387D3952344A950F4D8C7781B307A094DF1ECAEE4D2C2
+FD747BC6F7F9C6BD0E90C19294F96C8C5CFE88FB34C477574A1B1630B8CC591529E59B20794DA32E
+61DECDA8ABBD1AE956CF74012AA01D42EE01E861B0AA6897C864788AE59DEF43C493246FDB1ACA55
+4C12594BC7B33657A9ECC9E3D1472EF826073F632BE540C35FF6FB40566773F3BB2204D3A579A08C
+CBC844C14B18C350F003B9DA23A570C362D6003893CA32F86F59B829C78EE3188B6E3F7FA81D7F62
+2825C639638DFB78B7AF1F500F5B450FA54DBFA5CBA277C794ECE93275A3DE0B452FDC8DDC2993BA
+A42F28A636008CDCB03EBF71BDCAF35019778993443F88412AD2AD0D7155A3944606463266322DBC
+0244B07DA1E9C27A27B59664E8566D7A54CC03E995AAD008B0A17E2C3EF61F720CE7F7788599C4E4
+4C709CD5C31B11107F16AD70B17B9AFE2E8CD922A7428DAC171427FFAF51067307FAB0ADB530E701
+FD22DA22C4CD3064067BD4F6089C4B2C87937DD426E4E9D2F60E608288BAC9056554D04947E69200
+61E379CF5E81BFD32FD37EFAC1F61CEBEE551B0851516471A7472C60DF89DAA9EB1DC5A67E479745
+3E69B9E22BAF4E3CCA4192D603295B018C4AB69D18DE52DFDF15E96B557F290A4B8C5B1E7A6CACA8
+1F2351B97ADFC36995ABA43803A6E5AC04A3C93495F6D38106B8B144449C07D1358210F9176E1565
+72363CFBDE576BFDF99FA329DD1346E83F79E06CF68250CA57A68931BC7F342AD295D0CBA17AA95B
+B8EEB53EA6E8E660B814E9F857CECB14F44A43288B69A9E7908D55BF19E844359879D28CAEF1C38A
+36420185D20DFB32C2E002202800E8EF3D67C5D50E919657CA958B538D537D503444865331D79BFC
+40312068D72364503BD0CC84B5F30A74D8B5B6A26AF2DB764564FB65A6BA8F9051AE2B4EA458D46A
+4569F30C6E77DC097356770362E6CF3F1661074778EBB44FF7D1E3B64FF75E77E11FE525BB121C65
+46CFD13300CA1F02D571B82A5825E6226D14FDCF27F06D87452A8B6C5DCA658535CEE2A795E58137
+D48E566B69D53A0C3B766E84C51EAA221C46999CC8065ADB2F129D5B630FAB1814C0C33B5AEA0EFB
+B6E994D80941B53079AF96D90A0B924F9B0E319BED9836B8F9053F868363D3CA554CBB181863301F
+8CB940872ED5FA7BD18CE39218B5AD8AC57D0F752D941076B1C64D99BE0DB86D7A6D96510D772EB2
+4C587F11779BD21CFE5BDE1F29C1EF9022B2B8BCD7F91153C845906722477829C40111D810480F3C
+F62DE8DBA7FD86CD236E656618CAF6FC46827FBC4898EA7672F8C9971AFE43E0E01EC8B77D4AF48C
+BF1210E98C1DB15C16D149BFF58AB0270CF015B107A3A50F5DC8F37FFB92EEC8CB6778DDB7CE4AAB
+C464C4AFF654223006A550EB52485A23D2B4AA7198D3CD54418102F1E9A4FBDE37B841E56F5C2C53
+966DB9B66B000E4588282E3FB80C2C519339F0002D2F83C979EDC5827A3B3C8EF8810A0F9DACB6B9
+998E9AF6551F56313DC4011904CB979AA2D32B11A811BC248141E4B9734D9FB7982A5671002D8279
+CAB93ABE057474628DEFC95D43890DB1ED34CFA8A20BDC3D874E7679A396158E522ED0AB969A4E3E
+C7E4474E192590504D54DEB7B260B7935C4E56548A7D121AC1F741F8CDF259EA1B5813175A77A1D2
+D30BA26F65EB765A04C09ED51F69F41551ADF399E6AA2FC09788137BEA4913F17B8EB838C38FB272
+1FDCB55FD65697FF0B850E7D3D1CE266BF90F7EC06A9A0876BDFE767D3A918B092FC78C775F945CF
+1F96E859C03DBF630D9A940939654C3549D8F7921CB94EE23D5A0535DE9DF31EA0F937F860B4F220
+A99ADDFC343D7CF7BFA0B803C12C26403F0DCFFC8EA786D0D8A8D9C367419CA8AE41190CE93A8086
+583A1E6C9D70B612C84D87D2EEAA71EC2DC12F4CDE6A821303D5F6A9BBDB7EEDCD289E80FA3B75F4
+7F481B50719DCF4A142069393593B9AF9CCEEAEC56A35B8787193D7C88113E9E1E221D151E093B01
+9EF89F6118BEC4735103CC8003CC5AD1B6727B3226CD44C497DA7052DD681695DBEC3397F9598C91
+77701C73BF0594CE93F23D50EC5BEE2FB9DA1FC966DF148B27B28EE3C89526DD6625E2887F9FA076
+7C127C609EE315626BC14D274FBEA56528DC06A27B2D476D46E9E7916590B156A5DF04A6CB15E362
+45D77021767B6E5BDFCC679670263FD891446C3371B11BB6E1DF60F960AAB4149D7753E6A5C33810
+C42C8BFF4E935003388506F8278BD7CB672F132E065AE684DCA0B9064D01DD620E7FFDFE04F14277
+EFE8E60159BA0FCA3FE2F28B902D4AC275D19F0AC6971EBE827C4A232D87650D2688345BCA78F879
+077114F0463C5F058107B669566F8171E4E284D278405580F04BFFC9902784216E0C9A17AA9B2935
+E66E18A783F723BE044389B7E9D62AA36818FF2EA406C3C1A9D2F3436F3EE7DB8BE86AFA8DAA6A4B
+1B84611350D8D27605509612B515E16AA843164D5D0805E36A2B9EF74C5F6A0B9D59A04B55697123
+27F4B1B30E9587CD103337639967CBDC655AA46E80D2CFD24BEB50815B5338E522B3A7AFE8362AB4
+F05D8BC52BBA9C5089ADA8C89529B0275AF422EB540D31A938B8740860756325B966B36817115213
+FAAF92DE63F6BAE1E0064BFBC5588098B61EB83C71F1C2082436D37DAF1ACBE186FEDC4BE7C1233B
+6F18BEC5F99002D21CB7864E4811F7AB3C03003E1E4490AD1AC793BD28FCD5EF0E6CC30EF39A08C5
+2F71939B0CEF620DC69E31E39D6DB969049031B0C92EF2DB653D97F370141456A52985076B268652
+FA2648C792780BAD637C4D7581FB2D62011D57E293719487CF2D1F013CFAA532E1C2D39178D51272
+A6AF041440BCA174B5CC902BD7390C7D3695056CB4BD7791F9FB6D88E7A70DEF2C97869F5DBC5BD8
+23C517C7B7C39D624DF627DC9653EA5347BFDA80B723F05F6DBB4C9EA501D862ACE05B9DBDF21B70
+56FBCD8C6D4B85873DCEE6166C8B5ADC0316CA12D9639F361B15A42F00E1D62EDBCA1111972FA0F4
+5758BECB31DB38316F3CDFE1B41748C93ED58B67E9B57ABBED5924A6D53E99FBC9A994A6489A8BDF
+13EB685548B4DC6D62DA7426C22227D4D43B6FFC7B5EA91C896730253E8941AFEE588359C2BECF6F
+FC415B9EB6D31CCB0F6C7F85853E6449FA6D627A97A3CE8303F148393ADCCCDFA2FE085C6908BE5C
+3C05AF00A6F02840206C3253A559AC5C049BDDFD11AD9B118403B84DA10AE3C470CB9A9A2D1D7B73
+2F59F5FE146DEDA60AE750F551AAC934621B4470E1BC324C436303E25F81D0DC3188BE0D6FEC5414
+C20E4CB18952E12CB6423DF7124627ACDE145500D77A97A8BFD9CB50D1FAA008E2CE2B2505A4749F
+1EBBB092C347023714055A9B63353AF9E7FEE05BB54C9843698101F79888A91531773830C2C967B5
+88D3ACD2192883D5CE3962D51084FC653EAE2C5FB2DA41DACEFB5C76812D2EDB5B109677289CD199
+8D457FB1023A19AC67295BBC1A9A20A426B06A368DF3C5DD083CB1180D287F5500F2C635EDE157EE
+FCEEC5503447382D15C748C1E35F68753992E5C90F900DE54D18F8E1B355D1076ADFB1F3590135FA
+D1A36F028E44F48ABB149B80CA9A54614D467F8D71CB310BBC7AC7100261092DB8C5BFD39E0AC6BC
+2C9D6CBC3A8C05FF8A74CB21608EC4A4CFE4CBAA2D056DBA14206106044DECF59F957EF8A9CADE4C
+9B19D8D30DD4FDE6A9548E50DB51ACA73330142153FC36B69C1C8D5B26D0C689B7040E81AC2C864F
+D7C097C99BE5953843E172C97AB5684F35FB03A725A89DBF371F08DDF40A1531FC1B676DB0E1543A
+EC6E97D3D2E4AA3D5831D8B3C952ABBFA112352814FB6FAB61A0D680E6640F6AEC8426200CF61286
+F7422CB2F78C61EBAA36D47EC16D7FAF8B4AF31D090CDFA255D9D7C61D46CFB22A7D6E1758E71ED5
+67E00CBD8E8F468DDFB477F091A2F915627F22FF47B876544BC1F03B6BBB98385F009C20BB1AA2A7
+A78674692B8EAC2E3C8069B79E679338DA57F72976810F845BEB6B9ADD32B95D78E5E60F16DD1668
+9C05FD82D36A3115BE8ED494A74DD211D58A2CDF983FCB9CDC29BF7F0E29988FA23560EDF514BC1D
+183F3B2A22C09FB179B47E05ADEF48DF02F31C29875D1915037B19407764A4292FE44E741651A8E3
+BEB5F0D972B6327090F664417C84F84FFBF0AFFF8B1D85C822D90730AB4140C42A51AA8B1DBE4398
+4EA8566040EB8B341CCE23FD3F69DD235A080BA5C69AECB9BC732BC2D7D40617DDA6B79FB6EE40C3
+556C7DF9B23DAD89E94054B1345DB8402AE679FC4655A4A776C0150463F8DB2BFC0608EA1F124E22
+1DDAE6026B5E5D007A7E4A0D6B3B0CF3A2669E67C5E4F01551966A7BC48F2F4B6A87E740D8095E63
+F77C7A027F26B52F2299DE5B8A2F6209BCF3D31CB0235F998F781E5CC81E31DC424E008D46EC0920
+2951E5684804A0592EA47D6C788A20487BEA2EC8F2E6C1D7F378B62DB43CA43C4B366F8B4319631C
+FE9854F0E10321CFA3B01C873584863BBEFC23C72C05E695B56E8A52E89AA2DAB543834D34DCAC5F
+ED08DC51825C5257AE59850D101D84F4CAA1D29FC932F9E0EFFBF7A9A7F3685F61F0490CD3CC8988
+2DB52A757A6AF4C4E67B407BD2316B1C0FFE7DC54E43C87B874F57E4903334E2140B011484863CDC
+ACA331175F2CF3D72E0042855983AAF8853D3015E870FF0807014C31D55060DF3FE1FCE157324481
+2744AB51322444632F9AFDA6706E320FFE82B8CBE242A19DF00CE73EE48E25FF49D5871BD3E60652
+298FE3E8D400609E232E0DDC794C0579ACEF89E841B2EDCA50D51151F65E8C1CC3B01EF1870558F0
+BF5743718C3E068617E81BFE120C6CA16E0924BFC2541177D53671CAA3AB641C41557DCDAE1A3461
+47B5E999C4541B08B4AFCBC187AFD653D5B5F8386DF6AD8FE69E21BD0567DF494F736C6A184FA4DE
+48DC9F347787CA96E2E00A296C2DA05C2AD9BC423E9CA428D7F1FA12DC9353A302FB8C529AF8688C
+BB543B45B2717EBF8F6C497935F4F3BFFD285E0402AB7544B3CA4643AE5A8B5250ED987A95FC1F27
+5B9707ACD0641BD0EE2AE9758494F8D8A51DCE408A38AC20EAF0852D72D84D0C6BE973326793AEB9
+55EAC6FE0A2813A355DCD22F6F2CE56588D1C055CDDFA98878BCEB6A018DB22922D2B600A20F8184
+2E665DF41013CA0947C4237C2BD60A75E2FD1A3FB8C8FA19485730B87461AD466ACB02DF8CA24091
+4FB090B3D2B41EB6B8FF05E1A59D9FD668AF70BA5BB72778953BA55FC5F9F626043450E1D09BC83D
+8605098ABEF884639A37809A32565CBEFB3FF39EE53D6C18C58C272BB928E4410E361E59A50F242D
+69747A032617C52DEBBF62364AB5A96EFAF642D9D82BA679B1D70FAC10A4EB62FA5CFC308E86368A
+AAD7E75948F43598CD1C544A0D4091374D7E88D4522CBE902391641327E888E7748FA889DCE67ADE
+61699E7D77763681CAEE9B1CA8837B2F7EF9C18CBCC538C465C8E2DD34616953CCB6030A222C728B
+834911C1A179E2C770289407AB28B303E724D97F747D6134B425216A64C6E0B60F633E2B85300047
+E4C90339CE030A0FAE31E830C8ABA5AB3386A3B69267351A7BFDD66356AE5E57FB2994452993E90D
+E7C4E260ABAB93C37831856A650D56E44172FECA01D6C7C380F250B82473960D2A2A5FB6B4DA668F
+46E624ACF7FA0FD4490F485D640A3ADFC9F8652E7A38CE5799F770C3606DB4B8B947F93967F779E3
+A3C0572F13A5A187D31D7BD12A5C7BE23CB6ED6192086241B76C5BA6983DB9C93E4B208D707D3760
+F03CD6272EF3A4CE89B8E52E6AC5871A3D03EB975759AB4BE239E5EC7842CBB333E692CC607C722E
+185D3C39164DD320C6945629C70FF66A5237C0A9520A1FAD6EB9816069351AB0F135D90CC0982B14
+7D2294AE4A38A527EE40BE9CDE2512AAEBB590E134388BB171D0956A7C4566D65A9A041BE6C4F883
+6B3EC3D2ED1B48B566A783292B15B6127920D247D494F070BB20BEFF60640B11B276DDEEE49706E8
+B2B21BB40B7F00AAFC594C492C25DCA774E0B80D82E927448DE2E74A9D0DC7AC9260096EAF187B6C
+D6AEAA6D1DC4205B4411122751A5B22688404EA7C5861730371FFAC10F5AFD4727A0E402AB5EA757
+606B75EB86A05E8F774D6E430A1A3FE2A37EBB06700474239FB1CFA05EE44B91B82244C575B52E7F
+AF934B04EEB0D933FEB57EBE326D75821C8B23EAA85B583AED4320B7F04B9F2DC591091216FDE52E
+064BAAA9C2C9D9714B95A4558C21F3CEBE624B5403B31508F178581AF6863083ED762F1E2E34A45C
+FDD71660D626FF8648F5D6C5E580D4765A67FB6159EC8077A9F0A88038C8D3D7C77FF0926E2123BE
+874F7BCAF129D55A5B5960F824BD1728ABCFCC51D23936DE9A25C408D786E44C3A2BAFA4423177AD
+060D21D38E15E23EB6FFC0B4120E814695D423EEFC2744A1FC81B4DF89D76F0A6803D8B14E75538C
+AAD03A72517B86514F6952F6FD619D9E910D980F00964DB325318C045BDF79647F453D4A5CF4E61D
+D5359782827229310405FBCF6107C3AD9DDEF9A9A339D5D5A6EB2E7838A0A43221BD62CBDF732DB0
+A638A52016FB35BA7761AEC846A023D3BF2D1BB183543E81EB7CAC1E5970CDC6F068C5EA118C7AAE
+528D1396E6DC939112DA4460C890EAD5C01BDC438F5BB734218BA6270ADD0DC1778FD8AB16831D6A
+302B814A1A44B07EDC65956C9E6CF4875DF521F3CE5B422F71081B6D69BD270F739095C9E81C0377
+934A8BC6390C420C4E4CDD9CF7E32544C68D884E15ACA3BCC07FC8C132D8FB9D752C15D75C52C288
+57E2EA461A6FCAD90C56843513F74461F18D7164BC597A28AE4BA7C86EE1703535A9B9ED50122627
+71FC12F102E800E0E1AF7BB46681BD2B14B614CEA91B7B2AAA35235DE76C0E113C92688F8EC81277
+D58C3406778E1EC1CC15F1CD9A137C8FFDAAB99ACE3BFC782916F1A877170589A92DC921E6740A22
+B84DC6BACDABCC76E64C79E3A588D80F8F4D376E1B426F15751CF7391102102F0AFAFD8B22DFDEB5
+48AEB5F30B1673023D22054A13391A0EC08DE6E7B685A0D031AABF20B7C62187C0284892D5EAADF1
+21BA28263EB863D5E36EA9C06A77CCFC0E17F593961591F84D82AF823EFE41044C8D606FEF83CCC7
+B0E961E7994DF8A3CC36B209D953E250ADAB8D22D7F2B4E2C9CA39EFA2D93E56195C1560E30A5190
+CC5B17FAEFCF250DF79F6B624A4B917E11C332222FCCFEC4F6A47BD9E75DA9854FC3F7AE554E91ED
+DE144D7AEF38A0E3EDB5E5A5626374DB94F022C8CF549093041DE00D7269B7CE544E748439BA2870
+718C08E58FB4A77D93EBC04B7957D272AE1601D41BF85A2BADAA0DF73B0D3841D4839C85677FB2E1
+5F1D6CE592669FF4BBC9C69DBA334DC37706F2F6BE83D5863E8CD6A30C08640AAC4C233684E66B4F
+E6B62D4A8BE9D531E47BEF5640D9B5C27D990092BE1597F6995C8A77BE9C18AAE6C1CF130775DDAC
+41D34438FC7AD8E042CB56CBF2944932EBA7D053E9376FF398367450E35A1945FE23E05C921096A1
+5454721FFD0F429A3E06DC3ED36F1C170BE79C66996EF8337AFF85B90C5D3A4A94455AE9FA32E211
+7A63E59001F052D5F6223125BFAFA40901E98960ADF7BB886729DCA82FC3B8CC52B37FF2517299E1
+D769057F8154FB95582F02CB0BECC873A9C71796ADBD3E91324FAA94F2C41CF57C30B5897D031C02
+D256C909E080E70BFD1F32E69EF67031138C2DDCD1A8E4B65E485C23C3E450ABDD9815512D6F34A8
+4B9DB715DB2C7A93BFB424316E1AA44397749CB01088428F149A3B4324737ED9957FD388248462AC
+1B2610D72BF5C073ECA567E7385CC959E37CAC7E05470160FFA5A9F63B8E9B082937E911586EA165
+374938F492EDF28CE6020953A5B5CCEC7737F9D9CC8538C4339567AAED3794ABA3B9F4EAE65466E8
+E326F6C399B36355935FBDCB9972F10B13494DC25097FCEC5A6398F275C8C151558E74C5175F7BAF
+4155E36B733F75CF9D5C5979B0764F14D8306E06BA24BF791141E404C69F3F8FCCD91B9C58C2C671
+AAE7D4F9E5D6414E46ED633A5F78AA5BF04E652246A066EAD9E582B181CC196EA2D3CFAA383B5D0E
+4CAC9336E119C08CC6AC55CBFBAE147C623B400453BBF447E96DE036FC025624384359EED7C7D5F7
+858DC0521377CF647A157FC3F188DE5EEF094DBA125510FDE34C570D7BE76AB5DF0A28BF45DDAADB
+EA7EEEDB936332DFE93081E0AFD3FDD46BED08D6914B2EFCFDC41662A33B90B03D76D34F48D30FC6
+BBBB600E90E6AC7243FDF026762A44B4D6E4ECBEF48C9D7B696AF29EEE063E557D8FCF0F09E0136F
+45D17E608DA36E59F2AECF8493F8D62536119B5F7E1554DFE3F6E8D7C9A2C6F557D18B4AF92C9F6E
+050975C3B5C54F9B5F4E39D600B6FA2CD6DE203A174028CBB2A201AF126D1013C229BB82CFD013ED
+199D01E51EE2780FE896E01C63C655087A3E61A7F1029FA5E97EA1872F1B45F22282DDC317E17926
+7368CB52DA9444F6055A3C653659CAD2A1D8712BC2B1B32C1DC6906D957FB88524EE066156ED6BDE
+B8D832F9338F9912E29A250A8C4674E667C1C278B677AEC9972BE83CBA3FB779893FCB8F81A323AC
+91474BA2A2334A07BB5628E905C518E634F6761A3289056F83D5DD7B3890987EEE1C18FB2D379CC1
+905F1AEB3B3D2AD578F0D6C845D2D40C4BCEE3F71C90E68E5417BB8CDDD878D83BA80AD8485F4067
+E5C3CABF28AB56CBB219C0AAB8FFC6C7E192BEC8CBCA1459AE4450AFCC81B9548F40CE2622E5A7C2
+81F74DCC02DAD57EFD92D072318DDF05BF42F1EA8163071E23949B0179CF7DE64677CA99B23CB926
+B3E294194EC13397EA1DC9A5E1CDCD828156CD71F81B64167D4FB01E6002713BD8AC6F82B20CD369
+9C6CA4704DC5C65A2D66EB155B7AF1C9BB46469416FB49C1C7E17A30A5F045271D7DF3FFF2F42C6B
+470701C381E3456A500C6BB3D0E47B4D91C5F34B49BB6272F1F8698B307D89EDA3A1565DAD1C0864
+627560CF922DCF5B34C67860352390B282F95394AA2CDE0E97CE3ED39546A6AF1C52BFCF81A29BE8
+2C47C99E8050E4889E4575B75F39E662F2DB7420673797E2ED3D67CDA7AE2C15D0A0A794D57D168E
+BE13214E89E0209AB2C0EB7784E9491AEFA3C02D0DF3AE5365A0FC4AE023CAB528162C7A1B173664
+9DFADDACA8DA5FA18B7D6489E4229E9E24D38A620464A744A5C60F6F9D334B908706B738AED18669
+8A8B278341FA4D65A0A88680BA484694921512F7DE93337FC1C02BBE6E64AF2DAD07603279D87329
+1D1F4D39C1DD6D89C90F65240F4808F6F1115CA55B88E242565E59F3BBF1F10EC7B88872E9AE61D4
+4CAE185463EDFAF7DF63DE4D2207D307AFB61501892965170D2945846FCF5973A1D458607F50C15E
+06E5BEC715E0C156259AAA6C735593E5564F65F443B78CC7512EC35A56F126DF9D30974A40872E42
+65E1AE5FD483CFCBBBA26DEE426CDC4721F19C3FDA86ED7AD4FA1120F63669BEFE7002B128CEAFD8
+C63E8AC09943B6CBDFB3D2476A026C00A8FF81B1F651B97F310C82ABA5F388CC1DB5AFCFF5996D52
+52A6A42FA4D972E41EE56088F78CB966F9051171C472C774879AECFFF08BFD9CEA40D7C298922ACE
+64F28C14E0B81F4DCADE81D71DE3983D87D905192EF13CEE71B2D3FF1A88AEC671EC318917DF98A3
+C9054E372D22A3CEC82FCC217F47319A40900312F6E32B536B9E7A7FA0837EC65CCDB5FB0D414371
+17596CB39D9382262DE6E65379D3A9709B2CFBABF5FC5D5B352425F06F88CD31012A2A4147B112F0
+C1C0ACCC808CD625E0228EEF66661F70AF96D3DCFECD402700E4F6522AC9A856DA466D55C84F65BE
+2810A1565163872D62EB81333A698ED7B68352CACCA2D7AD38AB55C19E4F5582F75818302F5FDADF
+1DCED09D94872F2D48FB636C8E38C7563C72C771A08C6B1F041F3532BDB39006C89A33C09BE1E3E6
+03622D891F98010BF1DE5355F557A1E09448D486ADEF565705277B31B8BF2B86761E32631E3435B6
+88B79D566F1747BA456DDB43CD239FB47FF7B425EAA4C657C8EEC26EE01AED07CF916E77D53634C1
+37AEEA009C6B515B6342C54BE2C7B95955B1A9DA277A0ABCDA2346E88018C726F481F71D6011AA42
+F8852F2E5749518FE3B3AB668213FE1A05C10A1C53953D75312631D6BBBA01D418199DFEFF8CF548
+6109B099FE8E2F606165FE30F532C03567785D5362AA873C9D3EECEB20F1945D55F49B0CCAC84967
+59FCC7292E46938943C262D78F3212D3F9D0F7B103157F423D71B1ED54B2A603F4C269029918F238
+EC6828FFCEC66009DB9C9E59534EABB183F31D7AD4C57B1BDF0BD2CE5A421882BC10CC1BCE6A970E
+2B586BB221567CCA483989DD0B8DEC424C1D1FF042DCB7834423CF244EDA28D2D969B17440CAEAF0
+24A6119DB010CE366821AFA424D1B8299609C04148275AE6E5257A7ACB3C766C747CE99CBA2D703C
+F19B7CF301B634D8B613DDC4AFE4633A4D77BFF8E00CFB5E289EBBCAC90A24307E7941EC1685CBAE
+400CADD876FCEF7F6557EEE167D2035A05120293527700DC510B038A496BE1D5CBAEF24ED39F7421
+1A93AADF22214ED606A80582485AFE358E3A46D0671148998A3B3BE209467009B43400870359D418
+9A8CEB4D5866AB52D16D9CEB1EAB71C07E6CAA34B70E3096BF7604C22C40D5FBFEEA616DA3BABD59
+DCDB97D883FC8742B8267A16A99B7953225F7144568D566E64542C92E538AC140C851E5D295528EB
+7CBB49909B1CAF6409C9BCCEB325468FA0B5F7CB2987382616B477CCFE4F4AC79E4A6F7165363543
+F04DE5B6F6E1C2E910CDC3CDD6C4C92737198F892337DCB6647BD226C820AC99C65D8E7772BBB74F
+E65DCAA8A22C33BC168BF48E40A82700A3A7668C5A9A71E397ACDFEE7D556C5C19467B7AA69C260B
+727407AC837BDB7D67DEC055C1F45D8BAC61048C45BC9FB3CEFE7549EAA2992D2EDC126FF7A05EAE
+58613332A2BC1465B2BC0429162B907D65F793D236EDDD8D35405866D71B25F62DC4A7E06D4DEE82
+840ACCAABC0774F8A63E9C0F7FC980B3583E7A8B01C46590E3BC04EBA565C2EA94F057D964A78A90
+EA9F52ABFD70F84E44E434BD10A42E98C794065724341F907E35D3CB257161E01C7084E3A0166D15
+CED65DA7BA87DBB2EA33D39BD99AFB93D3548358D08330E807F8552CECF63C84F805205491BA3A1A
+622E70C232FADF3BF2DCFD6F0539158D3306506F150B0518371912A25EB96163D73E9EEED42EDC84
+D688BC7F7708D9DCA348FAB4DF62E5809BD094842D0A31DBB7C4B41F94D946810C5EC10B69AABC2C
+91A59500B2E5D37F4755DDFB7AE4ABF757F4C5BCF77C7F95E6A616646456FE8F18407080BCABBFA5
+7704287AD26222DF91AB2613951E2D679472F8ADF06EA2A20205EC19972299A78BAC52114334470C
+5F5890C2F846B4C6042D73945127F2E3910ECA1C4CD7A16EFE4B4BE38A15AAA710682C3836A8CA83
+FD384970139D8B46FB0AEBB002DD224199672FFA02250FBCFA4E649E335428FC71F50F45E498419E
+DB0E970F46894A48F65580881C9C4250FCEF65C9B28699408E18B26FE6DB7F1CBDB767564E73CB59
+54C6D639CE33220C894F36E70F71C9F9AA3FE2AE0AA0E3F2E304EC5ABC661675CDE2E70519E4220A
+E26FBACBD01D5169EB844750753E6CED53E3678FDCD08AB93E10067E9C64F38B40B76D99B6CD92BD
+F4155A1EA5CC824998B59AAD06E09E5F15EBB2288D66EA71B296616734FEF2796F07FF0D8B047074
+A1111D68B99C2B70FC56E74A51B062F4998ACC85B1943C9477E436E5CD7AB18DBC898D21BB93475A
+623BDDA71D7B895BA2D4C10F4B90BF335126F4FD57D73AFA50170F6B3C364922E551D40E35DA75FA
+891762FA23401D39260F2E92C7807C746F13BB35CEF9DBF2E76E66A72FEFF095DA482A4DE8A42091
+7065736CF4DE904FB52E649A32255E2030A7B31B686353492F31C064A3C4B0448C4BFD44B8E15384
+FD809B8761EE26A7DFA1758D57CE4F0BC376EB2B3833534B15A83436BA553955ACB5A7A66796AC5B
+92DB5388BC53EFA27508B08E82821E5CF669BCE52BB860780F749B4F38ACDF5FF12726BF3EC2743F
+01014CDE96FE6B4C40A034E9EAFCA2A35CCC776C2669E6AD138070A40F48ED79136D7FF57E993E09
+B81C543FBADD350FF5B5F7A46F060F88E30FE2D8233832D18B6C323EE017EBC1DF5C838321CDC8A8
+4CABCAB20B60A1A3AA028F36EA6E87C850AF8AF7CD50AA6359038BFA8818821D02CEE8F51DAB8C05
+F7AE9797814D97F3DB8CCDDE45B21DBB15CEE292FAA534A5F317B357F4091F3DA357325B8B9F5EDB
+45865415973C143E5E5BAA483FBF2D06CDD4246675EC58B84C6AE65CA743117FF00F229243772561
+31A7F2BA26A9115AFD96C18216CFDF41B7220ED0CB3FCC26C36380007B382A02AEAE428887DC8BE5
+FDD630AC57EE3DC156C7B8B29E687F24442E35CE10BA4087295A641F7139C831F7CCDA6CCEB5DAFE
+537CC1A97C5A337D3C48A6AE947F58A30DC08CC7B58DBBB4737AD52783C573FC1E9408F55495A80E
+7FDA61F0B9C4F090158F1A416249EBBA936C27BEFDEF19D1BFB839EB70576A010706D8B95657B218
+9C2AE04C11EF9E57FE09880273761FB4302C388BD608FA0C7F00F033C9C00F4E3D5CE2D903E0DA52
+E69C7745EE9FA75E2AD93DC6CB5CCFCD3782A699B807AFC36AD1F62B05856D5DFD6F88831B90EB3D
+CD523582A49732E3FD7253126D39E8AFB8458B5F7AD7F94A8DAC13365F433C857AF4A42C0A08C4DB
+9887C4957259ED22D13CFDF5995DA957EA5A0F620B0214FBFE08AB6D552DBF048D62CEF6EFF12F15
+3511ECA7833E0E3E95F85E6AC0F95438AC4C126E1F1ECF336ED31CCA7EB216D279877123FD9FCD8F
+B5E52B587CFFC4428456DDCA816819A8A4A211D8F1629E5D42BA4C5C356E580C8A22C61D987552FA
+A97893816DA73D423686E4EBD44375C257F031318865A20F22115E72BF1EB9F93AAA169C140A33A0
+6C35BD4526A38BE79CF40AD1EFA10411E8F3300A8A8B97AB140EE6734E1BEE6C8EE443D698D34159
+97649C6F10F20ACD80236422E215E146D744A262DA3FC88DC0D86FF66512F49D3F957D3C5CFFEB42
+4823509F33F155057A4C6F37B52F4667767BA94F6B8B62856B553F307E5D230C44CBFDC9A97A45B1
+39FFB2F2565EB0E22026972FAD0FB7B9576FB6F368B61979943A398773600E7EE1DFEFBF26D45D40
+BDA66EBB96A56EE9CAE0B2420C5DD83E24DBA9FF885BB844BF3D2BF93B07325DFF60C0CB5FDCCA0A
+C8FB5A2E119D5AF26E53AB8E3B428481C2871DDA26EF0B621CD8572B3C664BC7AAC01A1D05B98F79
+1A7080D294BE81099BDA7982432F3DFF4775C44D23F4F1B2E0162B61A8B2CB5EE8564BF98E2ED403
+2219085FE6194C19DAC98A421826CAED7F1AB1477AB327506010217283894235D7DBFC1153D5ECC4
+8AA7293F19592B4D7E95FE55151889BCD1D7FA7DC2370D2DFE11D7E4EA34B5C7A8E73BD3A348FD38
+9EF45B6167FB90BA44C23E912F9A4F2FC0427ED070592F7110183BFDB2C400393BA7569058227926
+351F07FED4F33633BA03A72AA2DC6B598E49B96021DD868DAD0F352E5722FB714F667C15C68D49C0
+3D822D82677EDFE86FE9668E537DA284068C9B0AED83074C92A5B939296D505B837E6A9DDAB1AEAB
+7455A08A114C2222B339284674B74BF4CA9EE0C020BF2A148B439C71C6BE51A94CB64FBE4A7EB295
+5A455047CF5CB348B062ED4F6471CBC3E9ADD9BE9B96879AC7BC71BCE02FD02F17C6063985A5E898
+3D205AA1489DA13C408990ABA1C54F2F501AA172F530480D789C848118C0A74EF98D5F607A067BAF
+F6030D887AC6A6497F9A0B38F9705F328AAD4BFBB634F739386177B07F22D5771282444E5EE17335
+B4D0EC86117C697E79A5F4F65FDC08E4904DAEDAB20067EAE2448FD4301849E456D085F392DD1316
+7ADF75CCFDB723E2904A9C0C976D6B84DDEF9D92B0E15FB246C3ECC2D0BF314CFB957757B3A3E8E5
+801F520644E4601D291DA0F7507C06F3B9BB36FC1C70EAA444E14E56C0CFF06C7F853DF36DA9D8B6
+AF2544B853DFFF535A7E5C6FC145250CDDA229956019659D0D253A19A7B51A4E538BDC01F74D7704
+9949C2C97C7EC6392C2E61CCC0992B66DAF1AB08551063E53180D2A67DE496716CCBAA45462D9F91
+B66A22545962DDAB120511FF08627131B95E5DEEB8B4DD9643E7B2AF65C0FDCE11F5F1E8DD468DA1
+8D41C8C4F00EA73836F4F70EC50FC3EC6D358C0658A4261C6D15A582A2C7C994E7882E661855B352
+014576858A265FFBC425160669CE159D07EDAC04D060B44E5800A7AAE8E339C29B929AA81D2F515C
+46229D2080D5917AB20AB6B34FDCA8E4AF64ED660A3173786FB1A1D005D575C2A5187D3F7CFDC94C
+CC44A38C5CD523E9DA726D8EFA6DA7B6131DFF3435FEE838B2C7D6B97934295F06202D307FF78D90
+6699CB9C5BBB10D1D4DEA5FDA5BFB094E704607083B646D37F5DA1FC7AD21B813F44D8C1AFEAB666
+55AAA19703BEA2E77DF3BF350E17C74B3447A452235919452B5175570A006C7680AC05E8950A62E1
+1D7E3ACA35A397D1E19630D094A86807593C97F4C484E4E06BCFF708B6DCA972E3A0009E1CAC0EA4
+141530F5C1B8AEF5E1B933F37FDDBC4BE22B74FE346D1A3F5FEC0818F8E61765568A2AC04713E828
+F98C449D9A1CCE52D10D61DD8BFD084C8D099A75D89DEA64D5A7CC68BD5B0593D97953DADA976383
+F5015915618AEC56D71D1DCD55B89736395C609B315A3F1E1255432FDBD37F38CC43C354FB4B7C44
+F1A7318B0B7E99C3C08C33B953727B6A6328051783A0A33E3CD9E498346A3CA6A77B517096EDD52A
+E443B87643A646C3A7BB97F742888D33F9B3127E61942F4103C1DBDCD8EAC8F9E259773066736CA6
+53CE57E8822651261D847C131321BB9D6626A1AC50D047C0BA47B411DF2A995545BD68EC0287CC9B
+31D5DDCA8755EBEB10ACCB3903AB0FD5788E984220443B8459E7C078DA4289F1350905881AD6DFDE
+C47302B0ACB0D4AF8CAED02B4B70DF3CF8FEC118F0FC2D3DDE3E494CD160E676E300BC464BD4400D
+B50EE43B314E0517037BF971ACD7CD327CB2134893B8A0410E68DDC518F5DEC966C7884CF5FDFE74
+723177F20DEDC039D879056CAAB4BF045062D3904F615C5CFE109AC7A35599C94024B41019B9AFD4
+04A80ACAA4837929F5C9317680A13D157A03B59A5588DF79D2E113F5F51021D6F6F90E8BBBA2C252
+FD10651BE80BAFD59C53A3367BA3C28DB6EB9DABF1EA99F47B503F627E15DCF3FD645FC52C5D5D0F
+2F07DB4C25C0D1E1C00146E1C4D973E613CCDBD3F9450CC0F5343D79F05E9492E86A1BB889ADF405
+03BD7F3E7543436859184A5B20BD8A172F350D846B7570803990ADAA48D4B9155A2B4C4BFBEF1E1A
+065C08E03928559735BDD442FF1E83E1FA20A5DA57D8BDB2FF5427C034CF0128AF111E6E73099E04
+6E0C240E80A73D7BE72B87834E45898D475521CA3306707631F5C6136199F354632D1A085F12A1C7
+C473868B62E534D15F5484323E63D0574196A19EF175214EB35A90873EFCFB92D6CF68761D45E37E
+AA61E1A1979A82009507CA193E44B36A806486665CEDBCF387053ACEAB979BD35D30978FC7659ABB
+E844F4ECAB3303318ECE80777A5FA5A9DD91B3D06804C4B4E9B4EFCF07EB89866D0DD8CA390CFD15
+98651417114D78776B1A1D36B4BA17746D6BE7FC123D473EF1EFED1C3BC1D555F914536869FD5B0C
+35F9C83F65B0E6BF7A627B9202D787D72C600DDB6BCCE613D88492E13CA0AAAB196E8A49928C62CE
+A4FFE2D0208EDA334ACF47F20BD793124D2C5546C03F4A364369A76A0425262F9D9118AF54E37D32
+E33AB25DD533A49DF5FBF1BAF4CEAC2D9D378CDCD13B00FDA432D9042F623DA41AFB80699B5538A2
+5403B0B3EABEC9E8EFCF42FEF3EA9F91766902CD206B0787C187D5370B60AD6DCD002DE2DE8DCDC0
+B4719A797C5E26BAA67665016DA0D967FA1346F9588AEDA174CA001B31213617FE19EA218EC23597
+79D979E2663166489C06993230B0D07973A117C4E3F4A4C93CF8428248DD5389414D679C69644142
+67C7FEA17E35B0CEE456667A9B1875C81B2302BDDEA2818D6019FC1622A82051F60584ABC904CD91
+8676305DC03FFBCC64FDDAC8D8AA9CE2EA00D6C97BC63C8A617DEDFC0E40775649438E9F61AFD179
+5E3B20560B01BE5E0983F136CF48AB206954E41DEE0D9DDD953DFD01CAEB569151D6BC0DFEF29D70
+FAE3E198E7EDD8922C0E0BCB8BCCF1C016142C1A8B337AFA7A05A9D7534B184BF3BF827F371E9BD1
+9A71244ECA1BA73D484CD2FAD54DB2F0EEFBD54B536EBCB5094E6BC2F5B2AAE41F05B4B311115876
+ED42C34F8E643B53372E3F6350DB8A38445822EA9A33E27FB0CC42CEDCD1FE2FDF723FC47C996EE3
+56C402112F24D0AF899B2D00BEA1CFD427998BD22B2A09046D6737814448ACFB10D387547D7009FB
+384AF0562C85694C071584236D0F1F3D3FCD0CFB38B77C81889061E668BA7AB37AA60F58A3967DE2
+6F939B79CBF10A9DCC42852561D8D6754F1B660D216AAB1E133FBAA321C56E2584BE5C9BAE20CCF0
+0E8DBE6D9C2FCEBEBAD945C3C04101D2387351F132628786F6D9D4CAB83419288D31F9BC600D9664
+12E6AA457CE6CAD26A4C0671097B98C2384C81DD8B9A3222D4F4BBDA7017895C3EDC26662779AEE7
+40D9D7E24185FB821970B0A3A94041A69E4805EC88EE1EE521981536F2844FB8F5EF645F67D42CE5
+148E2DDE43AD5AEF200EDB3A2C7866C98458A92666E5F9E070178BCC39F65A893102A10564AF4E8C
+AAA5075D2F8CD7FAB0401C03AF299EA3515CC93066744EB5AF7CF0ED06675BF049A6E3C211A89E16
+DE5BF0445A7CCA6EE8EB0347454950485D884606651E5887FE8B24323E2AA16DE22FC1FC8C4F06A8
+2A1FDE5758976024068197E1F4506E4D3D8A16D40461A4586338B374A592DC60334402F76388AD6A
+457DC3F54E6169CF7AE3959676E966A45609621055EC3AF80E182633300A4418E34A66DDFA6B569E
+5A13C9115B5FD3EC1CEBE50FBA247F60803AA83976F00117536342DC3D9890C49B2AC701D370E43A
+955118967827760F7091469C5406F08F18D7E3548148CF0E312B1DC71DF67A5E7A1656CF2F47F3AF
+F3DD50FFC2FCDAB7177285B29C17CA43019F62AC6FBA52D1493ED7C427526470ACC8389BAE827759
+4958908F517B2863B83292EB5AB3F57FFFB08393CA610FB1FE905D88A0A16AC395E2A2A6DD033D6A
+0D68992F830B2E1B95FE357BF672716E88FFB92FFC3D62945D1EAD22BC68C51EE0E10A43011DB94C
+44685A5C4576F6EF44CBFB45F2A4BF110A01657DB51FD499767E78058199B31DFD60813F1A344F86
+289F9378231D5B151C92385E3650B4FEB1DC91018EAB8474CBF69FDC1496A4D078D2C351C8196451
+247A9DCF8117E5B637371D8E22E248C64D999015C3FD2311E9950B8EE0922FBDD3D7BFF766BFE9E7
+CE0BE12F318FF2A7B5A9C6D00A54401609304ED2C55F5C1EAC3D4B38355BBD85D66D61636FA6E30C
+2E82829376BEC979A6FEEE040E452359768ECF90CC539A546F17AE906C76F14F86FF697797322B05
+1EB311A759FE260C1EEE5DACF383816AAF1294CFFA7BF87A4D9BC595EE8F2C2F86FEEE11AD959D86
+F22FDAF4CEC098942A57E57813A0FA99239E994FFF353C1E781D666B8928CFC648FCF0869FC68468
+BDBDA7D280DFAB8B0B3A4CA35B074B686DE8D372C61FB32305169A1A9912F6541DA16CD6316A6EA4
+51524757BE5CF6E820011BE3859FB8B8578C100FF029680E05F0E0BF11D33FE19460C85EA5E4C0EF
+28E29407C8AE6BE01CFA0D5022BF9FB01416FFF722A784DFC8FCE330EC95737A854471D334FDC58F
+AB42867A7B62836A8B56466E9A6C1247D46EBAFFB905CD4321970F59FB8D6FF65FDDD34BF913AD32
+2E68455C5FF2D23C1A5EAE687F259BC982B6A384D35440F7C693CF50B9ECAC0B5578CAEE87588B56
+2EB6B7F42034C9F2E545EC866316552354EB3728C7D26527ED75174EAF635E048B08DC5D23E88981
+070AD5641A652F2344956E9CF4C16E652A99F4A644D1787D6D36537489DA4D74E61B2FC4DFDF1D1D
+9D58F9C26C5EB63200526AFD168AC57D5611ADE4D4A382FC28BB60F9E7D626A6C67AFBCCD1183C5E
+3CF2EF210D0BF5CFA7BB10FA3887BDD4CD96EEEAA8F9219AA2F10ABC0A960C3B57C0EC0313AE10CC
+FF1F522124CFC8D2D49BFBB0C193EAFFC5B48FB3FF30B21CB76F0A4C0F1377C9223145BB0468A5D7
+1B9BC25873EA12E1C60334571C67385C00D0B570D3FFC6C7FF0DE62C183C76AEEB12DFFEE1459E0F
+C818C621B8D12FA1357E2B55D48935D70BF140B4CFFE8813DEFD479350B20DC2EB1D3CBB1A2D3DC6
+EE975D58C89D61FC50E6A0197DA9A586B72255023DE47DABEFB11E8AA02414C2FF6258A281219B9D
+DDFE41BA7D7977D0D6F18224FE22F7D4E9355FDB35BF7ED3418F4F68D093AC48F7D8FE4194FEB6C8
+0B9DC1F74E023C604DEA27089F98C3973FF9F4AD7BF7BAE601DB89B08D5D8139B95EDCF6C885FFA8
+B3E4B0477E7040225733826BACFD1EC4A0DD72DC41734856AB9FB700DF83CA2CE812913BD142D84C
+5C83C0B2583768198AF9E885F2BA74877A414233207234AA5F18840557CA11682AABDE8993533887
+7C6D404BDE4153C9827EB16D66C1D73A8143C8A2D3604FF72CE579FAA3C5224BAC48EA83BA848429
+9472007DE96466B5B29ACC7C03B05DCAA38A48BFF9F214DE43146AE4E04FA705421917F99BC54533
+F0EBC01849E396216B9F0794E6F6C6B61B52EF1B1950C0FB609895C3C55FF574163FC8B6B09E66AB
+AED1810E698FF37CC1F926B2CDA3B48C7D77790EBD2D514B6F385D397F713EC3AD3954EA9C846158
+6031D369E8B99E53408A79D64C34EB5A56DE8A67DE91837960E98A66FC04DFA0EBDE21DB003234BB
+78665B039D0A469A0221BD541AF7149A2A659C300132C14581EF766FFFBECBA8B58A5EB3F95446DE
+F49AF863A8113D17B2E7E6ECDEAFC3834D4DF900E3475596E86FBB4E2974C090DB4AD61A737D611D
+92B4535AC291C56AD8B1C031D2F9B505BB77517B737D70AB3723DB52AE2ACCD5DD2F617423ED3CC3
+9CA882EF41757BF7151806A9B8B0F312808863E3673FB54DE939B35CDECA7FBC4DC3BDF5A5F47D35
+E345916C39366C8B4F439CE1C6F1835C320BD1E67375B03B5DE18C93256F251761A4C8CEC01019C0
+68E34447BCC503B9571FE8000627A6B3DAD5854CBC0A2D69E5A8F46BC78F6A7B1422334EC7A98ABE
+FE9B83E01DCF3C6C9273B346F3240EA225AE4A4083CC7B0EA141A0773FDE940768358EB4B13D82AA
+304A1386D450C1C0C6A7D5A8FD2BD313F78F85248B5196241E31E5595F3BC01F37700A2DD3D4A0EE
+2DD01A36569CD507130E8F5B1E96CB560BB7DA15560CCADF3B2C9804A11D9E8055C9EC70E48C1D21
+3EB756A1376F2EDCB7189D78CD3D6CA5865537EEC31C17D801605EFD860B0B629472690588D02575
+02C6F7A75B9A1C1B397781329832CF3EC43C09F1559CD562C48FA9500295CD3B0A790DD3FCD4684A
+7C7AC49AC9BFFF36B39A9FB148BC28D37907433943CBBF0CBDAB46D3EA86DC8F81C859C52D15302B
+94A9B51C199B7104DEEC9D769C2634CECF8B700CE9C04152CC59C9326BDACBEC4312DEED92DD087A
+1C4840868D9F97CAC046581F762F75E8D24D6445370A3F1E0AE74A6478D9DAC37E7FA5BEBEC0A1E0
+81AF89C1BBF7F51E3E2E22C8C405E8671BA85F1BF0DF79A465DAC7EC07F731E00632E017D190A99D
+83E27E5C2E63D7DABBA23B2E88334C63721AC5A4CBC5D45F4C177259F34C2EADE01FA008AF65EBC6
+01D8DD16436D86AA94C99F3CC0A2F87134E73BF22F108B825A8963B49C6C685474AFE4A542C8641D
+C0375D7EFE9AC1168D9700459BE52D0DA399023E141969F25C0DAC4668534B6647EC85454BE945E8
+26B26DE6E3C4584B97A38E2B40A0D23481BCA78084FE80E00A71A790BF31DF468A435ECC88E60A57
+860BBCA3D65930186E9917CBD209C230E8F8255A7ABC7D3F043AE4D7AD63D9980BEDF062B7D5C298
+C40225B6D03F29A0339E0FCA02138E526F06B9EF47F5E7A8068A846CFDE2BFDEBD24F5A73A66C079
+18662AEC80B43246284FA4E2EE0D9AAB172B1E59A6CC46B801149D8C0DF6DEC9A55D8E1B0EFD9D30
+2FF618075944CCCB6831D336B11617107B0530D09885E5CA11A5F1FCC8D69D603DA16BEA51116D42
+CAB1AA1E4D7B9B4D79993F2BFE53EAC904FEB70B2D330A89780EAC10D12CC0C35B8399F218AC2976
+E57A26BAD20CE2FA2AE2363D3FD2A8A971747556F2959DA74A8963C20B504711AE1CB0D0C02457FF
+2E9BF696B159AF031DD5155F21C0F5549B0471A3C5DC8918B675CEBCB23E29322B959ABC05283A70
+2E878DE8EF25EA760F3C5C7B7B49D398283DE2ED837FD59F7C22D62C58FE4448B1049FDEBFC8787E
+67D7DAFE9774979BB3802254DA59BCC0219F98C219F84D995CA768B8B5D9D4A32525DFECE003675E
+E4BD5D8DFFC11025AF2B468F9207B5B2B42349B98232BAC0759758C1F4A283405815BD7145C93FA0
+8F3ED2826655053A3C2559073D8ACD199DEA2C5BA5F616A2E48548B4370EC73493BA07E197165DCA
+774438B0766867819C1154D1959FE6E01E6312E0AB91FC2E2BD240FC8652A2D456A1DE7F34EF372A
+53794D4C4E050BF3CA5B7BD2F1B8DE93B4C8002485CB219AD2D029739FD3C81CC6E78EDF38723576
+1A57143EEDE5CC887F282FECD261F6A25D0A7E154ECDF5DC38E426811BE86AAA458577E5E0C5F0F7
+5AAFA9C41E5D1DC9D91ECD79B514F8CDF7A5F1A189470D35FDF4F9B8788879CCBD91B427822ED658
+389E981E0EE5F7FB87692A3E3E931DF8A1D1573E3B0166204240B7080089A09EF7487C9AEE2D665F
+5A82F94C877FB5B0DC531CEBF1E71C6592CEA2401E4B5122E5091DF03D203DF979B9A6EFBA12E2F6
+B422FDF15D49AC0914D372D21E871DE65CBECD105FD4A3E4714B9CCA5C6803FA39DBB015EA8A88BE
+7913502E562E5B170B87BFC8572DC9DF49AD63694311EF1334444BDF0B4CA3245271C1F7A4D7FAF1
+703E3AA0E1EA8D5C6E821B28707EE0C9B4F22F23796FE87356C58AE2CADC191F4C58E1FB58DA03B4
+5A25AC95DBAE13A293474217BDB214742B9D9D6AF35F70FED2891942EACE3E625E55FFB820543FBB
+250A062D3D395BC0F219ECFE0D76686AC148BC41476A887BC494DDBD396BE200FD3E03CFA12EC9AF
+6B934A283C42AA05589AA6B4A8D16946BB51F50419CABECEAEC5AEF9085C9989289E9B46BAFB6FB2
+782D84DE2B068F91A9744AAB237CEB1BA513E57E4C307108E993C972A3E0A898D5A8D27833155031
+FDB98863C3BE7FEF3004CBAA5CB60A1F2E3EB4D7290FF5FAFA088B1CECCB6CF51A58DAAD998F0839
+6CDFD68F5ABC9C1CCB8F6514107773C69C26873E889D1F79D10E866910E4684186FCD71C965ADF62
+39BA3418B313A27AD632300969B6F284519366ED85E7CD968D64823F8C59B5911A72D0A20EB72B60
+3A61E36F52F256FFCDF706B4560B4DFA5D918FBC530D83A4B3C01BDD3CB4572E24242D141BF9E775
+36693A0407D002E09CDA5B195BF1CCF430AE9824C07928A050D0B460F2704BE8F9E647A4884C4567
+0A81EACF7CC038643EB0FF18A376FF6F32B6FE4F197273327FBBDEC6443A299CAD4B26F7778A99F6
+5A11BDE047153E764039EDB251936AA43DEE50DDFDF8856519056AAFC4C5AE6F2051AF0579A9ACD4
+1D00775D7DBE70022CC263DCA5E0A25B9C7C4F5C418587666B2FE24816B1E0EC92F9074F1403BB83
+AFC3F1D52CA79C387BDEF864366E34C90BE52F7AA09935373A07E4E026224E76F9EC3CB9E7EDE50D
+EFDA48248D61F3CEC880A3B8843306375D9711E58645F3625BDB8E87052DA67F9794EF4AF8DB0BCF
+E00677C3A26907DC651BC838C40EC39E2B5A5DC0DBD345944A6C32226089D63C52490FA10B215AE7
+03CFB663EB8A47793B84CE7364DA1C4E7FCE32DFEF09490121222774915BA59C78C2275F829D15CF
+4D8686B095C38C731B83D48738C25F40B8ADD487C350A2EBE846C3916AE384CB1050F9F5DFE09FCB
+D9129C6270FD86D55A459618FDFA4F907E6B4746196BB717865AB378414029017551161A52E9D24B
+E4F7EED553A927933D4ABC8F25DF607779A717909CB4D810DE8F5762581900E224E4B91598149BA4
+71CF8068ABE8744356B261600BFCC57FB8BE45036CF6571D9B2A95304933BD4F17215F8EF53F8E08
+1AF61FA7F9583C34EB5655CB0ECB82246959F09091F36989EBDD646BEDCA614B9A61AB7696B3FF18
+1058A150FA6EC1BE2EBC7F64357A3FF2A2B0491D2F4E0B970DE5B7788B467CA678039B5EF55C88A3
+84578D427FD2CB16C87B0BF0A3D37CE8ED43E0F049AF2436344D5F47C948C632C94A287509282561
+6C64C5D262FE5B24916FFEE982A69A6CCF888BD01D62EA591EEC51F4B7DDFAFFBEEA93FE08D736C2
+0129E345D06B10246A5F57151C198D407730713F32299638EFBDC01367E23EB59AAD42A83AB41B43
+2DB462652E29813740F4680A5D4BD47B18328FAE6BDF4200CFA4CE3773809B45E8887C9B2E423698
+9F6C48D64F5986F563D9A7538A8716082F81936AEBD0461E6F4BD470436D8B7656F0FDF89108E6DD
+02ABDEF907731D458D690BC608EA9CED09EB1E6E64C0790C7A2378201CE997FFE0317679EE1D4EE9
+F91157449323E53B4ADA8096CD628B5861BF794543A98F2FA2AB54FF0F25A13DAD43DAF9394329B9
+5AA53CA32749FECB0B2BC035DD1EBD53FF9FB5AD8BCE06CD89E5568091C1CC314CFB1D9821D7F9AC
+7C55F55E0A16E39A87D43148201B928F3C42B110FC056189DEF183745F3B637441DE8BD4C3C7EF12
+F4258E306B2877ADAEC63441010750DB4E6269A4C78A0AC01BB3603C386651FE814031CB5D8C1F14
+9EEAFF652A53E57BBD4C8C0CE36A84A319A53BC1E5FD3F1ED1EE72F4C1A9BF264B594062FCAFB22C
+C1FDE3F2E3D3C17DD3F7FE0E15EBD812D550227C06D01127385374A11438ABD50048E17255FCD2BB
+85122A6FB9B7DA9D5E9DE8A747FAE0DA45A1FCEFE92B9E70A5B2CAC668D4D07527A5C1403267D823
+048BE671F725CFC7474B44FC5AAA348420B2D7C23C6CA066666FD6F2208E329878D90CEF1C2E77ED
+22D3BEBB9D547810B189F08920A27E7107F208591A84D463CE2576C70C3DFE6643E4EA93F4E1DAEB
+41D46F0E2F56FC10C69AD5034FC9859D31CF27A3A1EE256C93111F81C11ACF1FC0CE20B90BAC9AA3
+27A5C85A7985B951519FD4B03C40BE637162AF41B2FDA68F0D1E9B7602FE2659D3D75955C579AC51
+DF6A552EB9581AC3F712F083F19B52A6C4F560F36C59CEEB0C996AAF1728A2AA45DCAD79BD7B23AB
+388D5B0B64A2B95154B6259B730B0F4A72C8C7F7CC93C7D64D9D8810D1F63FF8ABD4DB89824E2D26
+4FDEE916C41E299211DB1A53256E1DB5CDD04862F034D9404B73183A99D3D13D642A663F129B6D16
+7095BEB4EAEFD03DF2FF2F0B6B594C1EE90FDB203DA89FACEE23F1BA3901FECC75FE1811BD701259
+343011262B6A0A9707AAA6316BC3C17F787BB80AC8DA5AAC942D90F80C5A3BB59E47EC767244AA95
+C63E50BF809998957936D3BF6ABC24B0A397258F9EB4DC8F65692CB023D9091FB180C69498CD0C08
+BBEBADC84A7E0016E8F8BEA325D924EB0DF82E75D2CC2CCBF039B11934363D4332C5FBC5EC556BE8
+5EE4E707CC2753CCC43D2ED50558E51A104221C9323CDCB0199B7B83454DE3FDC810D0F362C0299F
+5DD981B31D8E3DDA284FEF9DC8F9C8DE138D3065437A7FE8C30572AD06D62E8527AD37AE39AAB0B2
+25F76A25F6C6505241ED73BA494CF923E919F688DDEBF193E188F8C4C154F21631080763B4D091E8
+AD1D2FD6649E0CD9360E8D1A67A5B5FAFC67547CA31C95A5EA8D4EB5D68B9F6D6532DB9B54584735
+9558542A2AE58C09F3BD2918EFBE1699E9C8F2C2A11EA4D224C726D2ACD4A8D8ABAEDC6588CF2AE5
+66528B94F55B823A2A1F7BE19000F3E7579D094E047075DF18C8C868760295533B26EB3ED90635B1
+29C17ACA679C3E88B06998CE5A7A2544B700229F5A6A504BD3E45B276471959C8A3F81917A534287
+39B5EF9E3D463B3BA7318448E2A3E79520D2D245A2A72F31FF7070B6E4624E3A5E216BD103640C8D
+F387E49D732529C611F8B971073F17EBD2F6EB18F9B74A67E1997926DF178D4C9EDED435B9682F1A
+279C81BB9F60DAFE125845A2FF3B02979E5481C78A45C479BEFB9FEF3CE2BA9BC46C77B50B03E48D
+A6D17B76F06F3AD118371ADC69E178C52B5FB4B261C9311874ED07DD6D5B3226A005FDD7A6D53848
+09E7063F036CDEA41619122635E835D2D74CBB6AA9B38CAA4D819C26E95115FE0DBAB4198FC5838F
+2C91B7A87B07D734C6D4F4F83444C1E90AA9BFC908A2BAC4B3DEF9157AFCA5248F2DA31CA87BD363
+AC25E9E77F741D4B2C6E02F04987A6F49D30E9038CEFC41BA172DD675AED8B392164411144E5B738
+F3210B0E66B17A13CB9631C33D44484E792A7C082DD0A5382F34C5637653261B1EB6D2035B08B4D9
+1FA9AB770CAF40A103629511F7B43F2743D7E583433DECFB19C21FD4FD0AFCC22A4119E77C87BFE6
+FE50068B22479015BE5A9F06BEAB4D37412E062A45E0CBCD7BB39FEE747E96306F79FC4F2E8942DF
+5D9DA0E55AACCDA547DA19D30B8404FA121298B44C9CCE198C708C69A8D6BF17591C5C50D3FC5BE6
+961F7ABA8F366DAE957A1C3730DA4A5B4F035A9274675EE3BBF0CA8CE9D8349F50CABB1C3EA4948A
+BE6F9F143592F1EA95404E6909A909168E3279A957AE1924245C356331A75E7008BEE92BEAA304BA
+40B7C3F48F74D9018B3247DF50EBD7CE541DA48ECCB1B0BE51A455C3C13C279D4D8676078C3EBE43
+08748D52C9B041D3E7244C745B1F2F742D010A9E60695F3EC4FDC1050AC082B905D6A57E8F407A3B
+472F731011A5798965B7B1A307E252FE02C8F79CEEDDEB6E165F1A94D7FFF18DDBDF79477F14E9E9
+3981ABD200FE7771B29D1D2D120EE79D28B9543818527039AC74085EAFF241B56D08220C958B5D9C
+87C0C04A14D52AFD475B542D391BC54FF33DEF8D9484AFF6873BEED32DDA4B371112B523B6CE22B4
+0D1B416B64C9370F1CDF2C548F4CCBE9E12E21C36CC3EA52DA232DCFB65F66B22B5E2EC04852510D
+5E264EE939BB67AEC4764B87062AEB7F680B40BCEE04AD45C7519EB3B6199C9E0E332661463647F2
+FB7EDF303EFEF84891CEBCF0FAC5F723A9D0476C3F8C092604C87FC69C7A90F4D64AE45A478EE8BA
+2DF50FB93F55A3546123F0B0E2C1C40C98EAAE9F0F26B8F80FFE6E6B94B7E27D2884D58B8A119662
+2DF6BE608C5569D7864BB756DF2EDD184B90812B44ED4A32D001C31383A40AEEE9743651F7950846
+15C48E402DBC01C818D477EAC0347795CB2792E9C11E8FD4A02E194EED1C919D4598FEC003B6D9A8
+A0BC7D456047A1C0579453FC1D7CB2D158D466939A23D7A7B8ABED7E2777EC7487973E73F2266D9C
+250CE30729E3C5223AD93B9AE8443B35711E446A3DC660123ED45CE1942A1A2AD0610467E081CE2C
+8B92A6C82F0B17B5D2429E99F1A6268072C6B5AAAA6EB6283A872C54D3694CD825EB2926E57DBBC7
+C1663075E687A144E4D61C225781D80FCAE1497B442342B4A3F1CD6BDB50E31791CC3928C30835FE
+F845B6BE5E2D7E3F2F5F085AA3FAEB45CAD0D76BCBB1ED859A9CEBB9F7457036F0BC3F195CB1A98C
+9C8648F6583CDBB23894BC719D68C2DBD8003B10D08C8CAA40BCE784D7BFB4EEC9EA5359AC056E57
+B8B0F2EBCB1F4CE40C87FC7861180133E0CB6CE2FC4FE690756D327A2B5AE063E3021C0C0BD420D0
+56F0B941E6B36088A55BA11D0C35FD0132D5F48E5D9673572347171B4328D4807B972831C0D74CFF
+A5638C145B89C989E6EC942148207D6DB82257585958034D9F9D4221C7C9F7013790DBD130F277E0
+BC88BB179DD09E27062379ED06F25EEA8B7FB33C35861A0034776E3813D2E9E5C10E227CC569AB36
+CB2D9DF2E7B7B44758F9DC4FFAD7A24AC7E9F47AA850C221048C3CB35A37CE8EA75632AE65FE3212
+175146FECD6334AE3D3C5F492F067F795E1E8FF386BA198CB74F0BB4DC0000DA383BC4CC3F070DE1
+7721431988D69C8B1A5AFDCCC83C22E16A87E01C6D3E79DC7AFA3DB0371B0866EFB8B6F88900472A
+FEF1C4A878243C52D4E02E82658979731C841C489A6B97E271C4C93800EC7D91F93EB9B9C659A554
+E1FCE42A5EC65AC39190EF4B66DEAF6FC0569A000A9E1495F42F706FBEA4D32EB7EF11A648910259
+6A65CF899C2F322F5679C6D123469192A9BF1A7F1F2C81C554ADB97BD19ADB746A4F81A4D5559E60
+AB94C483DBABF6CE2F28CDB412D50FF3FCFA3B3DAAACC6A83CFED910CCB3B8D2C19590AFF4D75303
+4A6CE7F4156896A13808E0DFEAC547E69D3C886691728E4A35ACD575B40D721E8FCC5385A2EB28D7
+08101DC50811529528F5CB0C009BA7E3C88468E37768FB0D83895AB54DB2DD5426562AF9D8AF304B
+F6EDA54E9C92643DF926F5C3578269750120302A37CB140A18BA56BA01108D4ACACE8FEAE640A6C6
+958EF156B588ADB0EA5F3B0F37BBA12B7BCB221C811415387B024B7076FA4403A3AD6EBB5D9C26EF
+EBDB7ADE7C60B444AB9F90EA493B658B7767AE2BE649BDBB3FE85F460F1ED137C61BD95F7CD3D8B0
+15CE45138538930AB62AA0E54B4CE1A5EC5FEC0A2B28B345B67089A4E4AE14D2E1F5A9C8848DA688
+CA298F93860649EC3AAFEF3E820D86988C8E3E5A4D4BB937791827994AA3E81D0BB3EE115EC36D5F
+B9A392D09E79AF514D11C7B3A03C9F9C13355CE79E119A19177FFDCA34704D38118A8976D1EE5AA0
+2D14FEB1414419F5E85244ADC5C0A765A522EEF36170064BB19FEE3B5F7B441E4DB967DAE0BAC2C4
+8FC6A836E0EF5A69F073BEE1699F55E9C757EBD6FD8B514E2B49D6333815B7DBD1E0694695FCA3D2
+1320A0C4B852D9706DADD8369A95FDD917328BE93DD33818954DBD2C212D2CA81560ED5BC284EB04
+7A5F389E24E43F4FA8C97FECF46589FA7341076555CF55B1C21B28E0C1CBB00AB8B6F67472F27BC0
+D11148F407824B0159B5188D4BB7386FBDBF1C0FAF34721B7BCB5C0FCB7C4010DCB6A1284E9D7883
+9E3C2111A05D29AB7997073B590A81C6168020F1D48951BC7D8476D5BA593F4F23CAC1F9BB0E091E
+84B4E99E5C584D1370DD12DEE8DF16AF8BC6B7B23E2FEABDB7F32779AF8E2B5094A6E9B7A7225F24
+C43A8E5D2B977E1E19E633C26771E23017ED233DBB02C64F8CF03992C6484528D0C8464B46F24F9E
+8380F385D5D01B8893C67FC103498983CF939432AA380CA576D09030CD52FD99BDC3BE16C7204CDC
+3365BF76294A83A1FC14A236F5FE5321904E779B13232A76F8FE521F425562678436359C2461BEA5
+AB27209541F557AE2AA60009C9CA0A9FC7898C14306CE35A50017BADEFDECBBF94EE2905220706DC
+806409EF87DB1D73EAB0698AD2DB72CDCDB293E7FB13C94D9FC87E74502E6927A212F0D7D2F2D194
+64F7A66AC07872E18CB1DDE8F11835DCBC5C4EF039333FFFC0FC1456DAADE7DAE3EC2EE0D3415B0C
+ABB69FC5006F4D14A4EE1A5CA99AD4D5E629C0DD1E0F097B5B93DE2DD001A8C418234C9C45E8C13D
+1AE04E9466DAB8CF1ECB88A4E059C111A6468D2DABB90DA79C7C79E94DB28F6968B1A632F8C57D9E
+565FF91C6916026FFAC0661856B9FB8DE9C81661816221B1FC159CFEF1751E7E403F5F2CE32529DD
+540792FC17A12A3DCD7C50D38EEAADBD10ADBF5D8A82442AA900CE6150EB7A4639DD9FB6E385B2FD
+093493DCCD9014B23EB172E21AA89643A6CAD1093343D85D81261972DE0ACB16A4C6B5F0BE4C978B
+FA12D3CAF0134F9EA49F6E9687C8F99A456745EA252F0BA9968C7F9586E3DD841AA92DC7705BDD68
+2DAE41518A09DF0E209F321D7FA3417202F4BA76A984DA3ADDBC58136885362F02F0A24EBC439B3D
+BBDACFFD8498EBD29F88F016B1FEABC10785438EAC860B554525F3266097A675299AA0967BD3B7A0
+EEEE3FC578D1BE99D3533BD91571AED904BFC9DA1A1451FDC5406E1CD614E0C7FBC733563CD6CE6C
+C31E9237CA153F1F0411114361D731636BCF98555ABF12848AD109371A42B63675A4130B81E97C2A
+2EE2BB5D8FAE2640156001AF0F55D9D5DF8FF23C8AEFE14F120000F14149A36E5C94CD9081DEC277
+C2C34870D05011F99D48B0875A5FF542F067F7E9880109F586BCF2B50522A1F23ECE44349E539E70
+F84E207DC9BEC7CDF856A046F1A03226AA41F541719AD1AF88FF211E57DD0C1275DD0B7B47440DA0
+89B98C6EE92A7D94700B83CEBE19EAEDD8A615F6587587BA8BBA3CE3AA5E8EAFB1FB0F486BE3609B
+169EFB178A4292F4C0378AFE5D24EED1CAAB514DDC66C696D8E37F294A6579131DDF5488E9436609
+ACD750C3DB0A940C84FE022B22ADC2676F62E91E8F891225F891FBA537679B24547BBBF35F04915D
+20B11739F620D18B5B216921D222F15044368569AA302980B9225BB839F494588481B94B0C724352
+B2DF600A22B062561D86CB8F81514FBDAA4F8A043A0265F992FAB71FC9124A45B8475E1EF3DF6B6D
+E35CF329777D45F08325E8505EC0D979F542807AE77E57E453525F23BC59A50740371EFA98678AEE
+6C425374AEB745B99DDB5D8D908FDB551FBC0DB15832107BBECC4E11A1A8DEC69358A574A2ED46CC
+31D564549EFF23102D92BFDCBB2BB985F78F36033E34F59C0EBAFA3BDD71338736464CEFDBA91398
+33995EDA4207BFD4A9867D32E867FBEB7DE60D132803EF9347CB17BD91315484EF6570892297DD8B
+7D966103339535E28A00CB1EECA4A9775F60A9F5FC9BD8B06D78FE8E6318C31DA2E847E3F9CA587C
+B01AE2BA0A2EBDE308314413F4F230A758184ED60D4F71F6CEC22A93A01B6C54E0449A3860FCA895
+4A347B7588329A80974ECBECDA1070FBC055666375229F13DD995E99265DF870BC8B8CC6347FADBC
+1A6AF64599271A475B9123493D46BEC41289BEEB67EB97A8DED7A9C9730D37C65164CFBDC22E5CA5
+89D2E7954C7136EF4E084C43A6C7F361A3E96989239BDDB9A593CC2A80BA16DE9EE90E95CD39393C
+212AB22EECB677FD36D34DEB46C4AD0D21BF7E6D7CBD0C8083842FCD87B18FEA7CECF939987E99BA
+34C214E44DD84C176C9CC5A4CEA76D380CB316BB4EF9DE73D73B4AFD4ADB54451591DEF86621D138
+D5A0A29441502BF6C2ADE671CEC3CB5CAB903A657EB2D70C943F976C110E46C5D9D29BC00A875F27
+38E5D22496A43E096E009C5D3CB724B4CABB32838DBE527F83B18CB457E57B092C302EE557FD4F00
+DB9C56E66C9FDF4EC9FFAAB85F60D02BA79694FABA476A199A0331C30A78A92E10417BA236E23364
+8174C826331DC1BAB87C5F95027846130C6A2B4027930EBF9A97BA1B039D386FC51C302648E25980
+212F6A582CDE2778C677A01FBFB3C5D1B8A374ADAF6ADBF7DC94075F25ED66D440B3922C5F255FB2
+3FD8F6E21EA65B1D93BB225684B50F11310E242B087575973345B229BA62C1E2C35BDAEC04D10148
+F5B2F3BCF7399BDFDF1F3F79119714AEA697245BC647316EA157484ECB951BE367234FD02E8B1F09
+1AAC3D29BF282DFF4011BC0CBA8E55234D943DB3017CC7A766720BBC29B2D097A956C0F1067177F0
+12D42ADCB473CDE8D1BA35B4030757FA1D8211989DF3BD22CE5D501C21EF8708FB3449DF47D88650
+9FF7B59B76C0DBAE443F336FEE2D615D7EED1C284F14335BC8A26BF4621E10DE9611FB2F1DBD52E4
+B7565D8C65B54EA36D508BCF0C578A49A2665227CDE1F9768EFE847F9D94F1BBB7DB83701C232198
+5C7283D47B2E40B27A268428AAEFE75F6B2F8764A8494E5827573758CB9CA46FA93208836BCCC8B5
+564A69F5AD882052AF1C1417C3FA7F580569528682C77080F3688B65E7FC24D2A3AEB61574B4A321
+5927281544DDD7A6EE0A3E9388F8F631CE7251724DF70726E5912DDCCC8C652DD6C9608F8462303D
+867F589DE0F2F71711B35142EE6EF93B64D6326C4DD7DC83278E057100EE772082E6BA368ED91A55
+53ECFE2293A481E42F83BC8F9148C70EACE91F7B7D9CB8A72415BDB3AF66F68EA733A17ABE9DB005
+3BF148629132969589F38D30EABFA96A01FAC72650B5A6FF3935670198A1EA33810A9B11E330EB8B
+451F24F93544263436F669AB5A90A53B16CCEEAC36B1445574EFA7E802DE73522BE725E68704822C
+B7D3912717333367895BBFBE06966A5CC653AAB5E9B3596702086BF0010085B900711932A95ACF15
+CA4DC45A754EA334E9EB84D6FC8E3FC4F897456BED64BB93B593549FF0D5352275D8E417172A6664
+C5E0ECED1019494A7ED49AB0B965BEC1A82E5873766BB38D7D856049CCE2FCA65AAF61E961B60634
+E2A69EF059754C9D8163D87F928C222772D070D83FEC6FA5AC734AF65E40BFDE521F7D9CB1650FDF
+64754BFF21EA3FF0AF7611A93D525EC9B28C51AFECB04E7FC8323DD6C9B0D8539A34FC3CD8CEB795
+8E8EBBFED4313C77ED469C199552A9FF70BA5423B03B6148D4EAAE17B71C5B39DC436AC53D6BA8A7
+AD81AA8B02335A8B2B11E9F4FA913159A725B8AB60F52F1A2EA50EAF4D56656E615BF382CC68A690
+BF83DFF24FE986570ADC0290ED1A37C1C2AD469CE789E0EA0BB5CE01020100E729721AF3B5BADD33
+A2DAA6C33EB8F9064F5292F715F820B4BBFDD56F76D42E7A1A068C1CBDCE4640082F6E7D582D1939
+990CE6EE8D270015A2C461798B37DCB5798EE9F7512168B76D26C28BE4A49A1BF96C89D235F21A1D
+B6A96E5DA474D0B19B808D13D7A11BF39EA8647499C410ED9894A1ADF33D41B6FC2E614D8087F4C8
+4E437B136F3CB32DB8393C49177A0675A0C9E7EECEF448A97AFDBE840FA01FC7E5F2E8FECEDC1884
+84C312E8635CD79195475DDBFDD4D38D5A0246DE2C7F21608F8D2C0DA1371D302E941572E5792A3C
+F4E51A33228B93A814D03FD4FC223C314CF3714BB3A34BD4F7ED6348577FEED9DEB082C4049E57B5
+D3CDB7F26629E9F3BA36893E09E3C7463D02A22D7056BE76B87763260E46E48BB832B7EE13F8DC05
+37EC8E81E9BDFEAD8C27EBDF1AD706933EFD11131E12814F236EBB01BE85B7F1B2D627413B324918
+D247604F56EC128909873FEC3857028BEF76A3494364C2A7002D104D486236C30B48E2B75D851C34
+EA50BA7FFEB4E19190898AE21768C157C0CAC628A2181A32796FBC1A7271D2473CD88E5395DDBDB1
+FC3AA8DF0F3D588637F19A8B833AFDEB5F655A8838EECD684E2315B72C75CEEFBCEF94344ACE8D6A
+DBE355008EC72FE7CEEAB01363A895F4E73F867639BE0A0BE67333848816B05B419221BE8F9066C3
+62C23FE85B7F392930BFE4C12B9526FF2FDEC38F23A159ED61A0718E7115C24597D849FA76369153
+54A40C965D4D72EC94DA61A03766AB39AAB684E134FD1407A5B1B19BFEBA52AA0DA5D99CBE5C82DB
+AA663711E6DEBA180E1D4A39C320516A4350D296BC19BF1BE054859A0889C7E9727A021F3176FE62
+0FB0C837E4141FECE531A950C03D319E3255703220B7185BD20FE5DBA673F8129AB211EFCF36EE39
+4C7E00EB0876624BC840FA86E58B2F584754CB6BFDFD76810E300741EBE4544E5AC17413ADEB21C6
+2F66CA4F075C32381796BA709782DE34A675B717A2C7F6D88104CB924FDE5DF775B4F0B68E0E2E5C
+2F788BBDEAF06D8E1FC2105CCBBD5827C0B03FD6CD64F0D073F3192D5F94839644E5EC6C5185BADC
+F04112A65F49A8C83174A9AE958E76A2F5AF469E8B76C833782C5FFB8BD7B1BBBB3EA0CB7C9786C3
+BE2ADE5E7AFA8C8F20892659A59BC421E28845A108E34EE17864042EF587A6D67DECDFB3F510EB40
+D2229585347A0035670FCC76C2837A4E4D68304FE113C539B35C1F0234B5079B8E32934546982978
+C5E4DF955A454EA263C3CA5D7101F31A318D82A3F9FCB5A8AFD7A65209663B0FC9DA400B26F285EF
+46D0E1EAF8ACB1F1CB805E3986D04BC585073FC64895E4DAE1CCB749BB439CB32EA91176D5C39C36
+50D10AFB9C9884D5FB90183424CEE67EF2175D01D2478D67511EC9F54F88763C152697B06D948BED
+49240096EEE3D06AB4575E8E8B2CB8263B5BCF4FA1608720F52B675309833071879DF52C3EC2871D
+20F398B5CAC8F8A4D41D0F1D47584DD90DCDAEA4A1CF160C4B3BF1AAB890B5CEB6CB3488672AA68F
+BD938281DBC1D8BCFE92FBF514DA5358443CB6E0147254E91B38CE6787B2BB0DEDD2D38F5938737A
+977B5EA42892520C58F8FBB53C994B57382379E9490F0D6970B980E1BDF8CF9F4C3C5E0A18F66E86
+EE93FFE7FE546DE50F41364BCB3721B637072571FA1779F1D672FAD260C16D7F13CBDF3E4376E7FF
+56D2A710AC5AC35FCBDBCE2C9C17E523BBE6218617B13C1FA6679B308979AE7C61DA6E68369324C6
+CBC7DDEC364E5A86707266C0B459EE7B2C03FE584E529BFFDCE98C90A2F3D9305AA74D3ED8430DBF
+3A49FE2ECFD9C4BC9FEFD22618FE9C8A973AD072AB6F713E4DF02DCDA7AC5359B2D652013E131B76
+B3ED6C75FD53BA58D862846264627F6B9E70D8800F6D9B32242B747A67BB2B45675840D34F852AA8
+062FA6B01E31ED24DAE02F6CF788A17F7B9368175195DB0072259CCE0FFB2C1035C1D26E1777CCA3
+D56A827C3242069E76D6DD69B653768614B9ACFF16567FEA61508D51454BC02F6C60F755AEF6AFAE
+3536BBFA1823F8E1A53C41124DE983E51CEC92AEF4F99785D554488A51C20885346D1F761DA79017
+940A0C557D93F1DB6B3D00FFD61D08E96FF3AFCE5FEDF545CC9F47A2B1BB26713431D6D1E47FD6BD
+6E3C668B0368241F0EBB5FA9C991DF79890E52E83A3675EE699B61BAF869DE91F67278F510061C6F
+E41DE2D883F48CD0E068E2A652B244128D82E5CD52F35F210DDAE3054691ED55A7D99088AAE8FB04
+F525C2084AC09F5EDF80A4EFAFE981F74C0DE9D194320709B3464F3FF2C0F6AAEA6D973D9C323F53
+DE3D741F698FBF01036716BBD62957CB32CD81D3A2674560FFBC5BDC5C6E4F547E589AD0B1CFE14F
+5E17FED1C4A8ABE4E67CCF8A49F32C4C6044F1431E1CC382E7758722A6D0DF9ED23E51F8AD14D11D
+7B6428E27443715EBA4E9C05D6F238378F9498AEF0E7EE4FE6856622CC8E6ED141EE5F109E343CB6
+695C4BE1E0F66601C27975983BF557C04ACFC19227A1AD7E6C44C00529FC7EDD7F886D24B7E029B9
+C395260088BBFB96972199A7B32796D27257DE83A7402291C14FECDF7998C5C96B1EDADE0280F856
+8A8F5007852EED303969180B3329917973C2D32C080C9765B6BAB0673BC7ECFDBBFBEA980C263843
+39B7F1052591D91667D4FEE413AFC23DE2D4B9DA742F4269C6C939F5FC32A38040730A018155AD73
+3F231E4D5B9D01C03A58EAE7B5F590CCFAF25EDC8552CFC8D95C60EBAE1837D7A97CA137E9D4A4BD
+2CD34AEFD68D64B3F4F62326AC429921D7FB3C235184FE0899690A0B775F1A566EC29D5830D32372
+6526F7E7F5AFDD71B77E07613DDC4FC63EDF49051AEB59E6337AC0A4B6DD872E776C9CD0CCB86130
+5322D816732124F5978A86C186BF0A0F88E733CE38E4D7C1BA5378C5629B1EFC97806059990ED42C
+5CD183BAD7E94070E4058569DA2E51831FFE0D080301AEAB4350BA290318AEC582C78D05DD92E5AF
+B4424EA808629BC972E68F4FF2489C245593F07555CA6A2B25964794CF31CBD3AE5C229AB9B8C298
+06C01D116EBD0FF0F159ED2D3D7DFC73EAB4910BFF5B0B0B587CD9EA6E6FC45D63C09766224D8346
+1F0588140B258B1729F70BAE7962189B1554483392988CF230AF4077193E53330519394DD99BA135
+6D4730AB221DC6A66019BFAE564893DDAD7B177DADD16ADD21D396CFA6C3DC818052E2F71149FD59
+4A16DE0C2FFDD366C99B486C55A6E991E4D22CCB15843F0C3363676AF2F5B2D1B7EF66CCF2F12DC5
+0D63776BFFB058D70A9C76DCE96C754872D72C82A0C33F90D49C935402CDD26B6D743B1F43BED5D8
+B539424849C1495DAE73044E885A7D0F307F1816DF6244A6F2D97BFD4E200E93F69B08AF39EA21E6
+E347A47CEEBF803F73B978ADBFCF056789BB8E6E2563DE87DD9A8C877157B934102DCEDAC54D487A
+1BB2694F0034093C48F10A17D32E2BDD0C723CAF59ADDD1BE373AF8C9BEB4415AA5AF36310C31F24
+354A53C0B962573148BEF91D994FE3F3D8450DD4D686725799F53C373A0A3E3C060C2E1A3E800504
+9F26D716E1F381B9F83125E4683264A07E2D8938F605978E2513DD2050B3D8A1012797CBA8961632
+BED260916338A812AE751C7B657E086A0C7DDCD3BFDDFF3E48B84751925736D1310C4910FC114387
+F3ED7FE163F91895EBF55FCB425CEF5729D99BD8F2C072E36C310523E75CD8E5DE49C031C4263410
+9D56E91A46C8C8E89FD92012A00C33D0DEC52597B5C6933291A7BDC5CEDA95DCDA5600F9AE1C8250
+54E7EE1067458CCB66610704C58E4A4FC0CB5FC933D0322A716B2CD430A3AD48DAB3D4CBE9D23F2D
+092368CFC4E1F5495C133A92942EC62118D45C17723646E69407B4A89DCDFD2AB3FFC099A21D9D29
+741D68270629AA3A414FE58658DC9170C247B6E23F35C4BC5FF83009F462F2EEF4DBAC5FD158A658
+57F9B6DC1F5192DFB169DCB65621CAB2F1B07BD22F4155A8E9E2B6388D430FDE5EC1C834D22EA035
+C52E1E34482EADC36B4CAE902AAE89A7284E62B3C84B608D6BD05F75BC31310B2DD3B2C08A00E073
+7F104F03A41989D5F6B9A2C38B22F1D1803EE5D7A4D8DE44E4ABD496A1DE0C0E12C4BC96D0122846
+3F0EA9CE9509FEE987139F3DD3F9D0DF4313F555BE85433718F6D05F197C41A9D9C7A8B0D2740196
+82D49F58DD5F66B12A6520D9F226D1DF1F1B65CDFA261F980CA25A92645B86B64606293F8BFDE364
+C47D2AF2C709BBE77A70A5712F2CC26F3D66F5BE2C307A48E6F887F681D30121E32BBD87271B5DC4
+615D28C309F15AD263FB37424E56DDA6E17B998B45BE6C7FC6C28E3394A8764C9EB2DF5C06626593
+B5C665D550D4600172791CD208AE9F37BC082B0B242B0A504B751B18F4D7495172B697EE217834A8
+A4FB7CC16D6F9E8BB400BE8AEB0850960283DCE725249FCC4DE97D9886745AB6066C3E2F64DD8AB7
+9AA11667F11188D7965DC11EB760B772E282DBF13249F31986AC6898FEBFE23E3E8B8D2C33E00EA6
+FC493850ECB2E6D831D1EFCA3C2EC8EE2E394599091ED58BEDE97D7A43B6F739EB0F845EAC1DF6B1
+EBFE876009CC5D804B15ED4B56761B3CE1AF59C07B49DC798A44532297AD73D5101ED47F36A3678F
+818297CC27F6AAA2AACCC9AA9B6F5459911D8C56CF499E390AE607F3790450B2B9C9BE0F006EDA0C
+715B5CA0481734CFB0597478E7602B0D2C1E4F78F03C68C17C70E4B42D7D2D3C95CF40F73488B371
+8E2CB05A549944D86944D78724E266C3319AF89AE430E777E95F0D792B1C654306E421F3D63A26B2
+1E74B6E8B21B2E2B9DC596D013CDA16D08E65E8F24A84B12B2BADC653E6E1110DE2E709C1C1BED13
+707B70A421B384F20CA7A9A9D20324DD383F28B2D3C7A9C53F5D4C6B7C378D26DF11CF55238BE1B2
+4FA70DCC178DAD3D35670FE4919085EB1CD905971D76A368FDFCF9D2F0A23739851A3A6D2E02D65D
+54DEE69ED5D81315D3EA5E356F94EF256DD267FD1E1A9EDC9CD63E743F299BCC4A4506233B8DD765
+2CA067F741603F93250C087D368F9E9CC4CC1A6DED567487C05BAA992B0056A77F630A72008E3946
+15A9DB24FE56A956650EC9DE90A6C2259189440247970541CA198748928215C0E132A81AA13208D8
+63C1FE817F70CA573B54577D10B73100AF8EA088208A44FB92ACA314AE5879706180788C17BB1D0B
+81B6B95A1C4E0F9EA66F9B39BFE12444A6446691A7BDB03E0F03D9F07A10A7598F2166F108529F34
+CD90E601FFED3479ABCFCBDE8F051C348E48C61D95B00C59EA1287423F05666C3D36288844067E83
+E14F6B5210842C742B89F13ACD126B9FC50ABE2CA7D7ED513D43B6AC7F41EEDA416BFFFCC5C844AB
+2D23D4DC09B2D510504CE98D02E72020D9E669DDAA344C63A1B75632F912A1C0DA3885DA4AF7E243
+E4A4C6493D6595BB6D56B0359106957259E59E336BAAF35BD1CEC5CDE735272EBCCAE8D4904AEBD2
+B32610C6FEA2B69941D6542ECB44D71092A3CF067708A3D087AE99FF29671AB7DD8758759B971A08
+AE1BAD78270D2FBEE37AA2DCB119D72F6C7B0C8509018A70D0B0BE2C6830EF8E0B24B1CE1141EF87
+3A4D7DCC501F808BFD94E4DC0F2915AA023076BCC8006490A43685EA25AAFC187302EBDE7FE1965A
+04A5A398985D29F08E085127B56B057334D88EB638A4DDE64AFD204974C3939536B1B66A54B4DB81
+151853915718F70813F096CC1B0EA25E363B49264C2AD17158A4489F91453FBEDBDE15D7B74D7F98
+E81DF23251785D58295BA297F295AA6248A912CDD4F1111E6B628EECBB5139709E76EA4AB743CEC8
+26621D08E6BC64691CC90B3C3C1778931A28D3D5B1E20E96C643316613FC487C9B604C43463FA453
+3BCA1236286E6F5A6EEB2F1D9C34BDDE4595495A365F88055D9268541CF1654ACF478D384A5496A8
+772EA1402751A093582A6625A0A44816B5FDBE166835D598644296249B92CC90AA3FD6445C9A19BF
+27F59CB0616C7306070F33C7DF4E1DE64AC8C5BB2FFAC1EF2B1B30E5A0275E6004CF64BBE2C6710E
+DCFC3AA4ADD60106334708862FFA6652825BC84842736E47AE6917180365C75B27505EED3C6108E9
+898A780E20C3F606A860229AC46D0471ACA0187D6D539A1B8820F620F72B41AD1D3BF3834BF48CA2
+AFEA8BF535AF74C4562DEADCB63D2F5C7585722B77C989342D190FF926C8A5263B4F25286F99CF6F
+C62EE6E2AD61C82B29D82468AC10FD27764278E5558CE8B41BA111CB2F040914451A480C93084237
+CAC8F66BB7C6689F340B8ABF0150E06D5B1177278A4C08742FE22F42C28680F190900344ADFA486D
+59718C25D37275BCE4DF981AAC35D2C7E85C72A0188B8953CFA516FD545AEE0BF4B8BA301CFDE214
+4241FBDF3D204E3D2823301572E23F204C97305A82401660E12926EE7BA6EA1A81FF5C007933AFC7
+3266FAC4C134ED818A48E7DA01C71A46335C845F9DA5E960B25339D551582B375814148D94CFB781
+FC56093827B78578A73D4FF67B6B87F40CFA5E3F4325D9108CDB64BD06427B88C84105187316FA29
+90B4E3E8EDB6C78ABF164F4A9717D523794B2FE772A04DABBE688CCA977090979B5F47CEB90A1DBC
+167D305EAB231C9F4260C4AD10889CB785169902FC0BED78DA15B8417453BB65856EA0BEA5245BA0
+573F623D215F6C0CF801851C305B355D26B52B0B343645FE25C78A3526841EDA480919A1BBE5F56F
+C10ABEAA3E1FCCA7C43EE560F067F1AA2AFD642F769D1ACE8E2AAAF38850F0D757CD808C921D716E
+96FBC07DA7860DFA70CEAE2888C0ED3CBF9586443532B68DAED9A926655C157A416C383A53D8F283
+2A4E67468112A09ADC837ED8EC95F70852921F50D4417239FC42EE3624CA97F682745CC5E76CC7C6
+7BD99F2180F8C0B7FB49539C8CC474C25C0DDE491671FF329E51BCFA779346D4686835A3AD6633FC
+B5E0F67E0CA9CED8F215BEF4D240453EB2EDD6ADB22278AA5B985FA140C9834D38753DF2014F8C0E
+E6DAD19E8FC54C03C1F6CB0F858986691D99592562CAD95FA0A5B2ABE4A8B54B457D42E8C33A2D19
+51C0419A72FB94FDA78ECD92BD2A1416459E9DECA9469F35E4C47DB531726DEE8F203D7042EDB32F
+025DF3D582547BB1D45F7A5B70D317DF4EBB16E36B0D798E0932FD2A85B04FD67143E4B287A50416
+2C1F5A037CCD780088C5476385AF8168E12D97D44B0630621759173C8F1E3006B5B1C6D7138B7EEF
+C3CC5F54E24B2C3CA7B41AACFD25E554880AAF406EA4C3C6E21D3B550B040FB1952598A7E8E6488F
+E38288B2AEB6C4718338598A2BFE4D2B9D14C65732DA304C16FF3E1F8F03046EF095B65FD609DA87
+EC24A69278BFE65C905CD0329F6A486B8525B7EEA4F7AE56C2633CD83543269E8ACD6D71F500D82F
+DFBDE7F7F7B1AEE67328549232E26CA55085B6E84D9E2E7F74068F93A90C4654F2F396E57C5F76F7
+E61CBBE523DBFBA6E76638BBA3064DA025A79E3A294FE7F1CC28A3B4C57DD6FDC48E541A85534B25
+E1BC11B4F78019457239EAEFD4BE9007D205F1D985F389DB22400B279C10948551A6B4A17FBDA0FF
+C9428B18B43DC76EFB15FC2182216F1B60B4E344A03AD6C00F141EF99F89F24C819C3E32877A927D
+84C2D006940F39CA8B71E5951673EA9BFD1749923219DE38929ECAA9CE43B06CFA7DA1BBEDFDA56C
+61FF6C24F40E59B13870D5FDEB82D981154FAE5D6D5152DE69339359461A41A9713B6BBE47E868C9
+33CD74C75DB71D13BAE4DEC85E02FAA14EAD6C0A253B16C79514657B15E68CCFF9EE6AA385CFF9E2
+C53D9AE40F85C793E4E8FF50B2B7420F4FE69807BC5F37C3E300E6B3C3549D1D3246A2E70F091054
+1135BDF805E0A698E236B6496702D061241687B7B8D1A0E517DF0476DA09D89667A7AB375FD2672D
+CBAB8124E511502DDBD08BA04D941DF1CEBDCCF7ED48405CBCC33774A68C5212FC6F132641FF413C
+984F8B43BDFD7B1A2A3435F15AF07EF4970D3E4A0BB947C181E9CA27CC14A35BD1BD096875B45873
+8CA244F88C28728B74E25CB8C4FC1095A56CA75E4569AD3082EF194ADD11350DB3B74B96761D4538
+596FF7243B1E1B724716A144106E080D42036444FD472998460CE9ABBD05B42AF9389AC452BDBBA3
+A13A96890025789F16B9D92251FD3B3BEB2C61EDDB370A20456E3BFE5F4039E2557C451C524F8087
+015BAF3FF05F51869FB97512968BDB2B49589C1C7AF1E085250A47657465F480B7023E24C76731AC
+0EAB6704123D77977D3A2C4C56B691346EBE589C619C04515D34F81FC6A17527D5D8319013C5D4FF
+27CC3925E24C99231AC7FB9EAF0BBA482D3B75807AC85D03CD09DE5D9AE0B07B7A813F0449786500
+0AE8A7E00080300F0AB8C399057EDDBA273DD2E1B2A0DCEFAD3B332E6D4AC1FFAD846167DFD70E03
+46DAF84AF292D4F424256ED5AC4E104F80697050D50844A708EAC9E7F7784FD01646F3BD0C595CA5
+1EE6BD607D254E78ADDC5E15C3B6AC4940EC865A5C23105B6BE09EA09F2C05D6D76960A843B81EE4
+33977FAAC3CBDA85CDD2F4DB7C28293A77825635992AF8F3B38B4480D9A139B1662345A8ABE1634A
+77496C3F57597D2985E9E54717AB2E99CA35789441BCDDEDE9A9E2106B401D9684ADBEFE40D607F0
+75C179E9CC03E59E65430DB70B441D43DF03F2AA6FF06F224B6E455B01C64FB89EEC9103E48453A9
+749B4D602808C7E408A8903091D85E06AAF635D0D529C3CDD1B8479AC0F4208C284BB678A547F2BD
+77BB17C86D4560434F7AD1937760A6AA55B614CFA9FF8C9C96561AE6C8F2121C4E20237428BC51DF
+2099B6C49E3EFA18E6D439E6E6981E746EBB1DC461259D8EA0F8099C47CCA27B2D982B72C9A07CF2
+1B3C05D6E26E6E286E348B8944078E24809F9C5F3D014B4CBA02533F5621BFBA1F0EDB776C634746
+703C9F73BA89B1960A496420C68F54E5B901A6D733D7ACC79F275FFFB253F389AA480084468BB34D
+A1E797E43B7F6E8CAF5E8C93069A3A2730E57EC39B677BB73E3F07C2055599F7062E53B37A5F0099
+907D2ED87FF7A82C95FBAEB888033BDFD67BA3A6031A4CDC56CB1E4CF5B06B46E16D988BECCEFACB
+9E1C037023D7BF5CCF5D65AA66A17AB361BE7981F132A578F3ABFB97960A6034F052D9D5AFDC0679
+782EC90F240F943A5F9A3D969ED7399254FF67D89DF668F7C56FCEA1FFDCF20481474AC8495D3AF4
+B6D7EE093E369C057F0B70858220693B398ACF8E8143558132E4391405E30A73937C53402E459F4A
+A3539CF7A99A3F51C0307D045DF8B77757E92EA2F51BF0BB4F77D3904DD355665870C2B59F1ED7F8
+4FC71FDD7F0B6C5D3182DB77827CA6A2060D2B8C83C4EA4A432EF43A4D0A952CC6CBBE52A9F0CD66
+1A538973DE41FFE9C5CF55F2506B9EFEE51FBAE5E63BDCF5528499A47C031163C88D3022606784DE
+2F46A9C9235AEE3D4F71D4959B0CFDC5B7E78C8C0A8F9DC99440C2263DBACB343C5C648577F5610B
+50EAB1CF7FD02419EF3941C7CA0B0E64EBAD4B2CB05A0793DBC38F1946D44767BD287F5E9779C611
+CA0DAAA1E7393DBE0683C8D3455CDFEBC0E64B54B737E298DDA605227C0C4BBA87AA3EC7FA6EBAEC
+39E6EF2537D5974391D31739D9FC42983D81AEE44711C823F35F8E2321AC74943871739D2DBE9748
+FE68592263E7713F27E0D49B9B5CB7A4E55DE54E6B800D15856450FFD3AE5F287B12AE4F438B20AE
+9E27E6CAA00F3EAEADBE08432684FDF9931E925544A680182602A3C1997DE5D0630BD5A010535E66
+E1C123013D23966B3545C7431C39B97295BFA4099D14461004C42C85095EEACB9B47C593BC6DB863
+533A8619BAE09095DE8ECA432D4DDD49AA600D277E75DC3F5C6631E2A05382CB007825FADB77438D
+CFA78E252D79B6A196D5164C2FEB85D75ECA25FF80B1D97FE10E87960CA0FC47C41D3A213BF141B4
+8BC3AAA93FA86245064668394665BFD52D12C3BE4CE39EFD8111754398A944C3FD1AFA98EC337BAA
+AF899D35E804CF416AD7FE45FFF13FC6354007501043F98FE8428DE8013901BA6A28711A2CA85A27
+0BB135B72F1D5026E8217581860729E94F2F1878A0E96C59E9F62714FB5F8F25003DFC7347E99007
+8A9A331CB3A6A535BC61866F02513DEB982C4A13ADBFBAC3FF70A7335F40D5489E48E5EDEDEF1619
+1973D932479C62183B0E25EE8C4F76D4F1AE45DAEA4A12AEDD9EF81D248E8D19F8C8A5BECDD1EA1E
+98783EB7A38149170851B1942C96C53DE06DEF80913BFC04E539EC67C110498D15B78268853E5C72
+F485F8A27B768569E54241F6115875E2973292CF48FF91D45EBED627AE9F0766D22201B20AFDD40E
+5B17CF337F2999E0BD15B86E46EB3C18FC12B7DCADCF9DD50C6C7E3F37E615A892DB3F57E250A072
+A49F7277DD6A2C8042698233D35A699B17ECA5DBDA6D250ED4A16FCC893BF0DC2E33FB1EBD7DEDEA
+3C1C39603C8B7E1A5A833A8FCDD5570BD088749BB232615366687962C7E56ED089CD7B092505CAFA
+5A80F503C4CF337F07ADF0D106937E25670839D491F7BFF7A523DB609D126328C16113ECBCBF9C40
+04904427A108618AE5D4ED809F8CCAF72251104C94EC5BEE21F91B179D31DBA79CEEE5EC7FF698EB
+84AB1D2D1A624F58B3622A78844CE51498B2CEF38EAFE259D22C7BA61104651A862008BC1DDDA58C
+C45F663EB26428DAA85E7785363A69D2790996EF5D9621D53042F42F794962FEA46E46F37B8AD1FB
+76FC8D5CF2146843F8CC625139C75FB42DDA71A752BAC48F294E4C0C8289FC46DA5EFD9C91BDA6D0
+27518B7E81E8B21F755A9615627D5812ACA674D1527A1185EED4E3C628196E7D0759B1CAE6B9B7E9
+01E9599A65230F1EE469CD33B9BD9C104C44E3C1AB966C9678BD0AD78111A4E0F2D07A01A038CEDE
+7036D0534D684A1562A17AD64A00F279200C0371B1CBA61747671D2A21D3F9646CA290F6B82418A9
+6FA177C6278277504B7FBA936325F5FA124AB018A15DC18D2C5E8F93CDEEA52BEEDB78A57828D81A
+3E6C38B9FAF3DC4EB7273ECE3EA4482A1C6242A335862C2C3717F9C9ED95F77B140C4E1569B2192F
+C7DCF702D0BC9A50428EC406F8BD0CAF886B4D979320D3E429816D88F7C7146D960AC12E70F2CB7A
+9F4E3E366665AB3F1B4B6440F55EEA26DC9EE0096BB7763731740A537766490C8C174723BF0EB40C
+53701AAD12B21D436ADCE22203C1053A9DC4E9F17AE617888C4B4E6F3A720E4E6366BA628221A387
+D8AB15E04AD69387C310D3528BD2FAA5B22BFF3FA494F5FBFAC4F771C9C7402B95580C5AC4BB3AF6
+92A70CB2C851FA5CF1173EEC3EC29B5A05A0B728BBBB51D3B7AD8B0AF17A1563E82FAFD93F8B7118
+1FB7AFE352874F4EC6D334AB6747519AB8E847B7BCED33EB5458A828E074E74BA621BDCD03FEA604
+7F7B6ABDA01FC7514BA1AFF0D4D0C0CB8F4E42D5A87E395D9ACDD02CCC220C157153422018725846
+009A3ACD8C8CDDB66BC6836B4026FD9F526AA275D06C813179E5924F26A25094E7BDA8BD26AFC4CE
+B41D8964D4FC4AF1DFB0595BC5D6714C32F15DC7194E9A3A73013C45D8FA55CC0550A12D9AAE8E9F
+F199FA28EFC2426D8D1DEFB93A65717AF3EA8E2D5B4AA8EF0EF38E9600F7D4E7D9F1D67A2E63ECE4
+789FA74B159BFE2F91C19B0378BA52E93DF12830D99553B6618645E26126842AB70262D96E35E5E7
+50ECA0CE3458B3E51BEE2F21191136DFDBCA39BDC07939E521E4F492F392DEBD029C1EA237BD89AF
+76BC89F618D530160AB16269FA6B693CF14BDC4EC7C630025703C5337F61458FA09104EB15C7CB20
+AA4C9BDB7CEF3A09F25BC7F3149951A7CD75372993B80CD2112F7674CEFD6AFA764AA3486730D2C1
+897A264D82A91709FEC4A21E30D812F558451804EE6F3DEE2C4C437846BCBDA07C5B6CBA1D94AF02
+9163B7383CAC6E088AB1DC14ED3743EE77E26EA7AD3119A76C0B5F925C4DE305CD7BB3A09A453947
+5B9BD79BE28FC462D8718CE05F9D94CAF3387BA55E6E447BF81A9EDDD3A34E17BE66BC52B0C0BB6F
+86F6F008829173816D205182ED2ECED319864A796AB65D4E3950288BADA94FA32B6F453AFDFC6C39
+A4FCFE60353A64627E2057D4B379D3240012B3BB0ED0C7876CB83C1BA5EFB6E2A03F340C2B576731
+F848F762A7E1CCAF267EE06D621BC33FC245D0E1547ADC12CC0EB58B26BABDB8EAE9CBFBAB93836F
+FF22BDA1831DD01B7346AD377AA298D84628BF1C07433284B0A90FC89F5AEB2651BA2CEA405D4F52
+DDC0E74B871D43F71EB4ACE0D2B401F9348EAC3A2EF0AD295036BF6CF6F870D58E00B619D50EA7DD
+77BC28DEF91D805CD527DCBCFDC16C042BF9B874E3B1567EBA4C1E70744B9E7E5BD1FDA6A5FF6E10
+1613FBE58DC46CFAC1A65ADAF65E49757E9304E2AC9A91E0588600C709A61D4231730073A36D473F
+518A145E141D0A5A494441B9EA99AC23F60F54F8127B477E1CE698BB4129B4B1DFEEDF10D9E665C2
+47A62F112F5CA30B0AE5DBF3E495FF06EB28EB438CE8AAAD84D5F50FB56A3AF002C23BCF66ABC270
+7AC233FC0F2723DB99D2CFE7D3B3667732A531F5DC315CE74EDB9050BF75D29E6430F57CB6778B2A
+CBD57DFCEF896E6766C8FC5C9F9FBD701CD62CACF33EE0FC95E78DADD205B5F42CC63024624BAA0A
+B4DD447832B4E1DBA77BDFADD223989F8E958C8D759AAA37930664C6EFEC708116248A2A7AF3D656
+DDEAFD009B7F5333854608E67E5E588A857167ADF9225CF6C641F5E19C3E08678A281199EDDAC831
+B57223B1BEEADFDCBC8F6F25D32FCA2336C808162E8F381656E847FB6CB13969572425AA05AC830C
+33DE6E030F86A3A85D2A66A77F103C7042C97205526DC882EA9A00EB8BD5519847EB424C15F808A9
+1652A6CC89B66A5731126DEBADE123C63D88A2E550FACDEB3886FF98646000C64B3A91078012CA30
+904B71737CEF6BECABD43DD702880538F5A70085E6CC6015D2163681067C3D513A8C66032C34A0FE
+17A58AD4BC97CA69BF41F11D5E910FDFE9729652D3EA21F8DD8CC19160A8FC77573B1E9CEF4E790A
+79D8AD6723B6804E9616466C935303E063DEE29CAA6C3BAEBF278B818C2EC2F13ED645AB452397BF
+00DB8B26E115026E256746CD0C78A959364FDE6DEDDCD0F441A61A1EBA32C7BC172BB09512148D1E
+BAC9E791B7D51B71CAD2DC9B83B2F99B3726607D9CBE58B499A13753CE87FCDCE21C0AD0528ED0EF
+B9B2C927F57C78C626248AA2B835A0791244C5896686A66173EC9F802C4C633A42B086334D2A4878
+0E53D00809247BE64E529F96AD2F8B3922A6097D414DDE1EC76F9552F9B8D58B8E34F359AD792B2B
+E50C26DB05035E7497162E7C49C38D3CD9B98D620AA67492BE5AFCA3A81A7080185C7F0B5105223F
+1FA77805502A2E8C5FEEA27699858D84A95842C5F2FB68686D59FE24091FCDDE139B6463BC6C7B1E
+0E90D20A83651AF00C85797BB9F53ECEC1675C7EE636D0D9E77DBD8F89670F855EE4D4800FF3F695
+0EFF09BBF8A0DAF6B8242840CFA5BA73BEB95115F4A78BCC02D85ECCE0C0F2EF6F328AD1DD6CC049
+5A3315B414A4D61DA50DA46D7ACCEFF6EE56451805D26B0359AF193531F95F6589CEAD6FA041AF15
+3067F88A0A2FECD135C56682DB2B45A71D1FA737C064EE9A4F404BB72A70B3AF0330359393247EC7
+81512482579865240A23CD8479F21C2C44A119EBC4E81B308DD8AA86E60C3DD8ADA50E0DFE8308EB
+1A7F201EDE8DCFDA405AEFB47E0E6CA7DDB376DCB21D37F7ACC4D3E9F26B03A8DE0E8940CA3A9E75
+963A389DF8038D2C486072F61C0CEAF500753C7A6352B1CD0338D9212B42A4D3DA23D5BDF44C27C9
+4B88A415A3242FFE2E1B332477A21D2B9CE075EE479C6E657A4D8874A8C53964229310E01ED4F3C6
+86FEF5258EDF3B464DD6FFD7F1CAF473BBE722D60FB14AB4918E93878A8AE4773930B8CEE110F476
+7F42A52D9304C55BE12846C911A10AB9B2E036BF9DFD597F5348D42233315FA80D0F563C388BC253
+2103F05E90DBF1923F229F980A2F4585C7A373511372D07DCBACA583099EA972C03E5AA67E663882
+6DB134564DB993CEEB6E7A6659C7C5C05C310267D5F8A24EEC2D5CC3E3F3C808E6D6068D1A57646B
+37FABD98ECB7BAF99E7D9AC4414A491A73CA34C52F394352F6B5A15F0FC4D88622DAC694699C2464
+84ADAC3B1D366AFEDE2A2CD2042C90516A666A19A91C80248B11224BEDDF1A320E230739E755D098
+B6A67315535F4C187CFA67ED817A035056353FC859BF286317996FFFB478A2248B908FF12ABDE705
+402224A3EE5F463DD3D243875C84E02DB968ECA1CC52C75171EA50D6A88CA91327A7AA5795019F36
+C0A19C093A1C9D3723C7568F9D41F2E4FFB712FD47F897703D7A620B586B81936C84AAED61D84332
+B3BEBC4F95B796B93EF7A1F565C494F8A65EDB21E2EE18DC025522EF8E599887CA2836069CDDD889
+88E5862977B7472584303198CCE97EF9F9E1446D1F1F5ED1CFC666A8A0C3A03E1792EFB60A9B4065
+49E0DEDF6ACCDBD98742568B4735A747D8E5DE21E630125AE0C691D054E42199C15B1F80CAFA6E7B
+B2005F374A9A5F9900ABB7409CCD50C3AFCCAB1214E6A856F7C7EBA89BC3291801E1343DA9DAD2C6
+ED075C8ECA1423B43E587AEC67E6145272814B3F191B3C285639F9E2D6E148A02DC2CBC0E054D629
+5CD05DBAC1950400A9189316F0265B86A732D302C5BEE8ED233768F237C62600CBAAFF3A110D5EFB
+6CC7CA3B92D965CA7C5E8D3E64ECF239FE2507FC797FDBE54C1112B28D4DA44C60AB09D994C5BA78
+D663A2591934CC052BC70CD1DCA3325C66C9CB982E2039F5DB70C848D3DCEF655B1C2CD0CEC8865F
+E8E1C0A267BE4F707ECE6F5A3DFCA3CC1EDF92C760439F51AA69A4C1801E96CA4D6EA4AD980258F3
+D15C893913ABCE09101984C61B91D603053E49A97CB82FBA707DAE8AF1D579FD69C8481CB7B712CB
+CDDB4D287BE995E32C02B399602A08B9DD849039B5673F1930BEC7BF366EB082D2CA5DB2385C8CC4
+5BE3FC0E31820191A814EBA7C4F23B1938E6C4D800732787CD2CB97F762DFC85D4B798809B5F2254
+D826CA42B32695428D120298B44CF38494E56240B75DF1E41E46E53C44DC505452256DFEC819408D
+605FF14D6C1F3F152F2FEA96EA0AB3B472D8704E06BE9F8C3E8395CAADD06D6DA033E81ADE5DC3B8
+3DAFF743C6E9E48716003D358DF63CD7FD3E2F727D1F2D0C29962F76D5C95ED44B6F08D052025A66
+5785F264A3D5F5593677B630E628B5EA81FB37CFFD7A30B7FAD226B6FDC82B0878AF4C0EC4F4243A
+807B9839EA62BCBDF7C2E9B30A623876E632E084EBF4A21EDA04FC88A1C07021D0C72EC3E969D449
+FEB08E5826EC20E55B21EA71EA59F6E3B0710B0DDAB3261B4A2029ECAB68C19ADD5174E55D5E984A
+4E5F38F592A302FEE6ECE732DDE841A28672C620CC5D687455A5C06FA9FE688394A04F96312ED025
+B7AA6FBCE2925F3AE559CC1886BEECDB70822E2E5CA3F732A87404B1536AAC469989E9610CFA440A
+CE43875A70CA51F36CB6F629D9424C1E35A88F92D5DA3CD8CBAE6E8425A36968E21F4F30349749E0
+205BFF8D552837D6FC39532525370BBAC833F75F1854C93FC533A4AA53ADF7008173A70D94A4EBF5
+38EA9E62BCDA7C20E0A073BEE2EFAC34D2EF1D03BABD5147659E50B557045B2EB89DB303749B04D3
+F54B43FED612FCC68206E001A7AFE90230D9C12F74A32C7EDB5D0241DC3A5D51481FD7C8FAE08FEE
+263FBCED7C7D911B3A303C835AF5FADFD218F61A9D6DE80485ABCA88200047B094441F7767B97A24
+E8C612590FA2407BAB1E8B56C71914EEF2355DD97CFAFCC192BC06FCE063D3D9D1A629AADC75E3BF
+207234C208E7E30663EDD691043065C9CBC473D97C6D4DD3DFF59D6A9ABCDD4412C3128F603160AA
+D8F81C6E7A4DCAF35F3A99B4EA10A34375B477C2BF846521A7EABD4D28078E9340452A198F3F5ACC
+3DB7E3908939FF6E3709C6A3FD9889439A4AE3E10B618CC92E14B68429A3AD2C80940A1079452EC2
+66F254657BE7D79A2A24084AF73F6DF71FBCD32BF6913A3FAB25F977787F7BB0C3A3E8BAB38D7A2D
+B0B4826950643DD1E03BD7DD1FB149A33862A89226B7CB454DAF613128C2075470E42E70A9444A8E
+6ECA526345AB48E6F5160BA23B5BDDFDA6049EC44ED1461C7E0DD514B16E2FB285F72039DE3C7982
+EFD40D7F6C8E8F4CF35AC71B467BFC578002E8D2239A2FD2C4BCCDD8AF3D7DB1F4AE7F2D2E0811DF
+9D0155BA6EDE50B5F052F14F6AB884FFF244D8806C07EBCB49ED22D85DF696995991A954AA97A1EC
+D86ACD76E061B7541E87997FEF0657A826BD88EF3A4A5920462C6595E7A156F453291CA044CED810
+860C3B0149BCE73BECA713040664AD0591304106129600AF71317B0D2907839CEAC99515D357E980
+B1937B6E1200AACADA205421001F1B2F91753E80D2263C56AA164A74701A8D5FD28E46480B0DD963
+A683A1F355D7FB4463C7347C94EA5E2CA40B60B56297CB22D972C5BB10E56715A955605256C1541D
+9F3BC5768A6F355CD3B863F0FA1A781EDB49368F51B29481CBB41D4AEB07AF9DBE8F52C5D0FF75F7
+FB6431D37D6AED84D78C778871CB0F715B4F07580F23B586C969C81B471FF6A6C7276F7E141E02A8
+584D4B9AB00E7BD643D2C3FAAA299B1F1E25048461952EA42D4882768A70DE46B213A287F8D31AC4
+6D5436F22A796C05D1FE50A9BC2A928066627A0D87DD57A3AD91DB446404B41557D1457873482005
+EA20916BBE46C613F456C849D46BA79D20627B446B2F49E3FA309AE14F8C420CFD94922CBC0FB9D3
+5A0F7DBEF577F1849A1A80E0011DA8AC082A8C6F61658E65AD177ABDF23EE17C8CF0D26B9FA3A6E9
+4837EB9E930336889767A8D7EA3CE980A8EA95528B004957BE6067CD9BD8E02A0F23CC1762CCA656
+D33412FF45E917FD4A03EB6E8C1F43FDB0A8965A33B4FD26BC24A20B304CA817E88495BA9B361A3E
+933717FFB0271F7F70C5D3CBA1E86D0F51BF3ABA194DAF32C35C796627D00C7B2271ACE2463E37E9
+7B3C826CF3DB60028F240F9452CBE08F7EBCC5FDB1BCBB3C327A9F450B9E5671916101D6E3E5E458
+CA31F04D12F592F83BADA2C3683D3886AA3B403963AB5DBE220FEC00037A745839F67A3635DFD3BF
+F08F367482962DED88ECF6322852D643A54D5D303EB04BFDDEE9BBA1EBCCBA7C653B3A613A8E719A
+DEBE3CE1BD7E754E5F4977E863E3C2D388A65227B451D4F3A4F94E06513CBA4AC1F2F511613FF035
+611684CCC461599000E546E4D972CA6960E095A526E4735A23421A4C9B597ECE08AFA2753592BD16
+DED93255A1E33DEECE3C5EB77B94670E8137F2A4A4B98AC193258E7DEA5DB8408A806188F2D1DDC4
+40CCF0E9A6E2F0C78FDBD7B68DD4939D2458C1965BF8BED4564B32462FFF3EC892C03B11D3EA813F
+AB4CFBE8D3016329C5B7E3DFED0F08284D44AA0B7A2F6BC96EA4503E8EF52A64C22BED6B452581AE
+8FF8917D53976471941A9116A2D878FB2541B561767ABD4E31CCD8A590CA03494C62AFFD64EA0A1B
+C779173DAD84999C7A8D844EB1259DE7BB5B25CD023537A474A524EBE4660B22568949E624D8FEA0
+AD37F4CE1EC75955EEFA49C6BF1803BE87E9C9865FF3F6B8525B8C15FE8835CA153D27E6C0FF0CA5
+1029A7A9185D25F0F14D86FC797DCC1F99EE97E2054B9C2A2E06FDBEB8DEF6CDD368BF23A858D9F8
+C1DEFDCEAF1B4A8DE5EAFC604CECCF0D285BE00AA912EAB66EFF4D37AD2EFE34853BBFD87CE09B18
+749B489943EECAE7887B006FB827D10191DAD18466CD1F86505879310A8B171F902EA0C26A388E13
+B53C700272CEE2BFB47ACB58247C13449C6BB9D01232C32517358F1A3DE064D43C18F8827D53789C
+CF3CE2EBE78949A6ABFA1A6B8414CE360A5E22AFB7D1DCE6F5A06182C3B984B4F9BB1A905A9D5A14
+83750A1DE0A857CD5C06945EB7D4A2A6BF1237F32A154FDC06D51A703D44FE052FD3C53E9E8F417B
+35D1C851F9203A8997521529F21AD8498F96930AA77EBAF82EE02A57BC77C792D9F220294B45F48E
+A8FD94E01CD25645D36D168923562F3FDC93CB79DD4760DA0C103C2675722D7A1B79FCB4245ED12F
+A0DB52492C9CCE58B333CFEE822812F7DCA68E802C451B5CFAEBAC608B950386B6C58239D1C62D62
+4DD5D15782FC552222CCA06DDF387B373E32C3C2864C63C768350C37283760F3515A5B0AFD66C48A
+B522EB3E808C061F5CD6BD96CD18C9839D30508E7D4EDB88E8F11E31E10919B16B7971F06D7877A0
+58D8A4944C84FC6CAEDF3341B48B6E0D3C7B85D710E0C35F5B5053CF4B4798B3778CC28B2DC7AE0D
+F3A49F9F3BCD8E95D746C35C3F47D68B8AA35D97AA08E711B5FBE70D1A623C82541EBDC51A827D0A
+69E6C049087AD26F256EB7577F58CCFFBCCBA5A95D093DC29464C9A38DE95BC6B1853963B2DEB0B5
+7AD1248D6F1625E115EEB9510B5772AAE4E3C866657DB0B3BF0E0AC345E116F8D4976B770876FFE3
+748C36165522991F46A36F193DD1A1C94713673C7E4C81582391B636C72DE94CE6254374F99B623E
+5686C13D8A8322E83E11BB0B0A896C6A8C2C4F756C5385CD7017F26D23F7C3EE97372C868C8C9155
+81723BB6B76B4C3CE8998E4FA6CA40B633DFDAA59BA902A4952DA90EC4FC3CF0F2676ACFA7F76F78
+236FA2DE10FD3545357215246BB7E527F277C28B353CC6D79DCEF21BCC8F77603CDD58A2CCDDBE3A
+9802F941CED8E035313875319548C41992A2BE939A17CC109426E33825AE59BCD17CB19F50D972FF
+CBE7D9B4B0BB095303D9DC9D406696C2508D6CE99E11CF00F6461147E97449ED5F486D480A86D3A7
+ACECB7E9A945984724EFC21C5079B1FD03ED803C2DEAFCE3327D2D7827715FD65D9506216C88B0FA
+26935E95C64114A51919D419038B1A7E9C1E829FBFB53275093752DF19891A97F3CBF7719C1FD6CB
+17019A6D2D25360ECA804C4B35172662CC4769D2B785C6C87E5A4ECCE31704E59F71263B7C3CAEC8
+ACB4C7426EC25F11A0042323EE6C3EEB04284DBAE2C770BC419DCE79BD4560AEA41571C3B595F525
+60191DC7A8FBF63D413A77A0905E517441B16C2B501EA2F9E99CC38D052679F288FDF1894542E3A6
+6989A0090185EB2E75134BFA3D9147C3DB8A621D9D35E37786853779E157B47F71626D6B3E633005
+9159C17596C1B87FE2B4FF47ED9D78FA4C2160077276C8B58CEF5DC030B4A5D83CF257096C047FE6
+4DE307C598B815058E72D5F57DF5C369E664E137DE29349E2F9DCD8C9F4EBA6E765B6327D7A20DFC
+B20711273FD8091CBA605C4C494248076F7E03DF65A6A50164980BBBB708741E5BF6056E6F996DC0
+7FFF408C5B8EAB8DCEC315E92873228C805D4440A6470E3EE3983758DD211C9CECDBFAA4C9300CBA
+00608A4B2404A3C7AF017A3B7E67F39F0B51ACF950D3E75CC7BC2B8D3480202FA958E8EE0B240501
+5232EE0D264C7CA02C18CA45CB3C2DE322D3EB7F00F9455DB6C5B1F4E59C3E95520EC36D7D903CBB
+625D70B54BF6F8255E412604BBB29FEE026CC660577F91DB1DB4A613EEEFB20CF7AE3CD89D565AC8
+38416B01B5DE4FFA5550D17FB51FBBEBE21CF1D56038863EE931B90DEC2E211ED42BA92EC244D4CE
+2C4EC5CA87A026992772DC2AF754FC982B94F36EA7B7BF75E0ECE90CBB2A6AA1A012E8898BD679C2
+3CB3827C35D5D02F0569C7AA82615D4AA67518ECF668D3B57D6EF1A8013424AC2268BA0D9A74D588
+79EDCF6382A89D397864940303EAEC45A38304BA8B1CB198967AE23EB81054BE74B16909A405E8A7
+799CEE3C270FE2A6DC50BD7370B6B2C8FDB9A87D88D5D40348D3984E39C693B6F4486D994778607A
+80A3122872DD65E40492107C71C3CF708A9717E9EEFAFBDDC239C53AA9645B711038E59C8B861B37
+411AB2039BEDF9CFD00F08D9C5D76154427FF5DD39878CECC5D7BFB3F1F035087185C0981F3C2139
+BE84872FFAD3408531C4EA9387B89F5E3EC779E8850D50992DFDCF9132BC551E985943B07618AC10
+D1150451F0844C0DC41D6E17EB508DC8689EC726400D5A7F6FEB3CC7BCE05F09228B7CB2C5393664
+D8DD9A4B96B1020EF25D70AA2D91CAE93AFB5F2BF0AA18CA5C599FA1A708EF35BF8F7FFEC9AFC1F2
+42870D028B2B1459063B493943EF1283829783E1010242E5CF4DA39D93D506F3892936E7D6CF1124
+70A521D397438733D053944CFF12D6FFAE8246F20618684F263715AA98E15D72A526383E05C23214
+B78338E5B476F0981D90056E6E5D0DB66B1DF2298E597B2ABE1D817E18BEB056E65EDB4234342D96
+00470B1420C9210419D834E431B82F58608C87AC361A02D0F1FE4B470A3D71E0D21BB87E1023D428
+E23D596CB9E1A2184403A16E36E644BCCF9BBDE27290485057E62827283E7380AF786BF395B3961B
+A5EA469C315763FA59E0F176EF81985F38B882DE56A74D128E256D1B89939728E55A92ABA21A6B78
+44FAC1BA7BBDD8B34A18194A2984B000380FE9F672E83EFDBF276FE797A325815B0F25CC95C97A9D
+ACF56D583486305D7C9E51A7E337D14E3B900333EB38FD93A99587DA2341B10C059C71CE080FE753
+3C0F059FA40E560AF9C4A41A4BE6FB45846FF8F78165E10B4AD40F264BCF5596A1E8EF8CB6EA4B1A
+3A5C69059AB1563843679ECB2511A90E8898F54295649CB73D277760D8D04ABACC7BCC6E777A0530
+E2067CCBC08673F9C8C178F9D672AC8A15E5367F0C5651B53E75E0CFA57C931746AE1A679C246D7C
+9417F1CD89DDDBD1173C2F880B7B3847CBCCEBF99F7122E832D7C9BAFE2B54CBAA1ED48158DE3F36
+238B76B0E67644A28AEA996DDC006F6AC0242E4B667639E7523CBC90A0561193C1AF34481C2EF402
+EE43A82E1EBF4E3D601BB36B2D95CD93550D61CEE7A94E72F6D30C32C8F91A61E964B1F66ACFC398
+7F95D4028F116E9A9A8474AA29C1C1A984BE0E393BDC41DCEF6A6F1018DB60D52024899D8EB5D55D
+324D73F39BFA47377B9E15B3B06A7585589FCF52A54684173E5183367E7B0952DC4BC2767C4C6247
+B1D6103E52BC7B7EA6298F454C5D97AC575F19C10ACDFF4E10C7D3755CFAB4200CAC545269FF1D8D
+B0D607C7AD47F40DDF257AB4E7D0750577003C13E4941960C3DD7B0774DDAC18E8ABAF8F53E03CBE
+F6D57B44F24CF821014C064278FD51B3427593D17694B4ABCE81F49CBB984C5878CDF0C38D1ED7FD
+99B0B9A3BD8D8FF6219588B3B8FA59D0CDD1D9B2F65122AB45E48F1757467B9204926140E3C350C5
+A927A2E700173053EC35D3F1DA2D7258714C97FAA857F0898917BD94625C6D1E2D77138EFCAAAF51
+7B17FE187A2212C24A881A2C6A647DEF6376ED80AE4175C5EE80921F001995B44E49F0D33DD9075A
+CF33BB03671C0BCC34AD5784AD1CDFED3A6D9BA103B3DDC1CC2DE74DBB576A0277715275218CD19C
+A8899209125266D8BF1286F881DCC2C383749D1E768D670F4099F7DE959EDFE852583183C9111601
+2881A56A24AAF020EA45CD5F39660DEBCE30AC1C7B8CFC60387B1B0C3E361BE612FDFA9F01B7E4B4
+A18839A2C7E0E393EBC5AD9A8A4EBC316A740C1C295D9EF5F4DFFA0667F9582C0BB837B142C4CFC6
+B1798E9476D0631111033B8BA75A10FDC800E2AB1E0E829632F869CFE4737BE9E2800759EE0831DC
+7D1195EAF80555771981DD6DC6606812D92CB8EF86447F5F6C6F626D0E265C67E52A6319189EE349
+D48E49DFE6A9E98F76C414A1E3217AE0A215A17E54AA498F4ECDC50242ACC7E2322F63BB2FF2189D
+057E7354E32A3ED1803116176B9B9D0129930F919E2FEC280B2C8924E49E7BB75768A2EE1DA8ADBE
+D4E3589906DF1B923AEF84C1BD327438B731012E69BB0D43A1842CB88BB54EA4516477F704CFEB28
+6E3EA483445AD4D74586FCF32E96D366901084365F693A53C5FB532FBFE7BC0CADC404C4985042D6
+8DBB90A6DCDA3531EE324D558A214F935CD9FCC9A0CEBE9B5FB0323F4B3820529599EF48EE068B5A
+CE85004FEA2984F0A86F5AC9D56163BBFE1142B774148F1EB0A4DC89C3349052533A7DE66729DB24
+41B82F8F7360111DACF69293C9B281A0534F3E9E9224A75C49A832F28B2E497262475507B6DDFA9F
+01CA0A6696E3F5AC7EA68595EBA0C2EB8A47813FF936D84AC1B23ECA7AA2862B793CCBB0DF9FDD49
+31BEF354CEC12FBF478559FEC29F81ADF4452E83963E56541D31F3691C93A50F0BBA5E9552C4F2A2
+3A6E53060729854A3DD71CC4308B91957DB19E66AAA18FA67055A950F1C2CFF78A03BC1A588CF624
+696068068719AFB1001C4581EE072113882D9052B21E355D401ED8CD24D067B99E616BDA5A0A5A93
+36FC499632B79FF2FD0DEFB096EF46B75E2D4E0F48DAEA239719FEC4D9A29818F5875FC5041A9EDB
+D26CAF0ACE14CC80BA49BBA59E918EB3D8F1E541AA16026585A2F72DF7D83541816DE46981FB3EFD
+0C30E458CFAD04C79421AB7C4925E23AEA07F9F018431C790002596D26BD9663B51B699DF53E4882
+CBC34EDE88EB55045B889B6062E35FD1E018BCE785157B85EC3B9CA6C85D4B16238275385B8285DB
+012D8FB7C9F5B946A41D7A0FB878FF72C39683144D8A007CFF631B43748F2D5FC690300F9BC0C837
+006B92ECEBE0605E8C3A4A400E18AE8997D1B45FEE10068E247C647CF82C6DFBE5E881D511FFA687
+B7AEB78546BFD07D5F7EC242DCEF4930D8AAAD8C6152B6642AAC325963FD147F236BB850A9966573
+9D06CDBD7CA79A527DCF461E33F22BC9C5DB00DA2BD3DDDD8C99D99793BC98282AA8872FF96C3942
+85D82D9419EB78B6AE37A5F519397700F75D624A09BD255B576E955A323E784E8FC31131F003B0E3
+024A4F58FEF2A6C043796201FC425482E1155E229D1B2D43EF7B0D22322B22EF5C9A1BE026A1C3D3
+75EDAFF99597E1E5477952A4E8D2ACF5D014BC00DC2A272FA62B6983E27D228881E2EF2B8B95A681
+CBE90C5FDE16331C85222FE2A16F0A3C3000A63E2E21666C0C119F8AF89A543D37977069A5ACF155
+6324F05204CE8CAD50FF4FB630D9CBBFC324DEDA584AA56A99D3A76FF55BDC2C2EA3A021361CCD4A
+83C7A5E2768D210FA6DE889FD48A39D679C94EC3C99A8D33FF11377DA7F6F1B71A2A05B302ECDE95
+4F26773F39AC881542F0D0969C3995C3519A8EF70B4220D86BF01BEECC6462855E7B686E1AFF1CA9
+1FB8FD8B4A69E10EE0C2AD94ADD44449506F9B6EF43641F2026EFF6E605C670560C2B74706FB949A
+A7E8CC6A2D0D6207E457E7FD87EC1B9092DC68B9143947CC8ED14AFDDCBF8FDDA228A76847F96802
+E561F67CEEFDE45AE587673983FC04C96744DBAA83F2DC838D633943C75DCB9E6410474EB27B348F
+26E505F0AB90878940E846C5E9F3C5FE8C3558C3236B1B88C405716949B8506841CABE1717474BB7
+C30DB91CDEE33B0F844811762FAEC535BDCF84C1C747CEF9B1FA61D2AFB5A81335BC42C06A94D7D5
+9B7EDE55BCF6F9867AEE107555CDD084B7684C2C87087475A39A9DA6347BE281CE5635A4D07865BA
+98CE26C1465B1AB0343F49FF37B4D0CA9F3BB693D78DC3B21925CB996A038DCC172527FE57C07460
+EF39C07D4396E7FA970D9F22ABD21A9C794B64AD96762C7428F59A8757C36D6C4FFB23216195A04C
+2A2C2E7B10EF7193931544D782FEE4B91E01119C5553BBC6252270A8D8C56DD62D448F5AD8DC69CC
+B45E1F17F0AA1E445129DD00F000005B23D38DE93A3BE55A4C041947F36B4E4536E307D0180553F9
+2E46B743881CB5D5386C48C7D5F84C2BCD06B9C501F78C7EE61FA23516791FCF4DB278AF688A2E60
+10A56692AD92008497487EDFE4BD5FA083FA544138B20D6940020887E35D46E093B71F7A04A67460
+DC8116B4D4839625D7CA6959D6831CD93F81AC4EA2709036DD738364FDE71113BF22EBF13DFE1642
+E564701E6F0FFE7511EDF03FE448C2B28C64FB7D54B94CA576E481FA56B2B18AF10C71F699B6BFD4
+7459CDE1869D0FD306BF489A6F42E5B2F05CCF55BB6B9526973D19CB134CA7F13F1DB3716F8CC217
+73A832568C16250B5CDB16DF24BF81D49F5B37018BD310262EA7078107868AB0216CEC83CEFCAB1E
+9F2C665A31585CA04DC01879CAA79AAA5AB201B516F7052B01B16BEE5606098393B0E5D9F9E5E3F4
+EB20F63C958E796DF41CF28839F5C62A0431648745D7837B519F3AA36BC6C08EF040CCF53D9B6D8C
+0C7D1A84D707EC57A3C6AC9A62AB37251A01A5ED40FDEC6F5BE6E34C6A91D058319439778A2EE5D0
+363E2E1F33463C33327D05FFC0CBF08D5BC457C7230448972FB9B4D0D782BA7DBF10D3FFEF8BF523
+6EC16D4DD6D0D870D9D5EB5C64C9A46A4F583D4F831FEE74B0E5B33A09ABFD4444929BD8F638CD72
+EAB99CF2E9551DF427683964A592E49D186F285258C5D5F62196A98532421D73E3495F82695FEEC6
+E1952C562D546B28618FFAEEBEFF03A57F4D855021F85B0C7BC37FCC6DA9AECA099B646B99D41896
+09D3FF2D56422F8C37E97640293EC7C90E3380887836F4938FBF495CAC14FBA5648D89282D8D49D9
+1AF73ED36581139D8BD42551E263E830EA3C6EB381D85C42D74C50DB0CCAEC03F535ADE92128A016
+0E811C34748309AF7604919B66CD43EB5CA975302DCB6076FEB6BDD6FF55976FE990FB0CE9ABB11B
+195403FB26E3D6C6A0DE1C5BE79E171A61E21F79EE8DBE7A832519813EF6B33EA098C2C32ADEA219
+AB2AAC8B093F40000995539D1276D5F2EF84CCD099B71FE4269BDBDB6A8D59C86F7D2E3FBCCF8773
+D0FAE97640BC1AD43CB4B992BFADFB09DBD0CAAEB8CD9DA264187C4F97300E9A6C9DEED5525479E6
+05C65AE336CBBDF4E5D7F79AD098F977285E065579B748FEAA97F2A753E1F962FCAB68D72BAA8EE4
+FF6691C23E31BC0F3E981A96FB440404856AE1AB32A7205B17D411D8F21C8C93B704D07EC594422A
+BC368CDA2B1610CE6A973F4474E12B78B532666797F5755D269772C9F5400B3BFC6C58395D38527E
+2CCCF29B56123F7DCEF3BDE5DC1DFC5B0293BB125085B1D2D929BC3EE84F4FAD571A4991C3DEE03F
+2DB3A3097E52B1A7D5C73CCB6148EAC62E8E36DE9A71C57638C6E4D5D9DED18174E8C390E50B4A5B
+913C074EEAEBE390B214B3A68F02862B9A296DB4B409769649E51D738CBBDFB7702E15C73C2AFC6B
+C37CE15171F4E822CF20EFE55D9F061AA43E648989628FF79E65932390CBB15D8E621333B18B11C3
+BDF96F841D7434E01AD501FEA964A75B248A35CD9DF9A37E48A1E5A09C624B93CE44F0042FA00D7F
+9EE89B9F7AB785E9C718CF6E7228F743271C2C9BBA17E5208B920E44E765D99D86650EB454B0FAAA
+112753AA1BD3A24239E9C5FC47EEB1547AC9D23731B8DC48B9707830DAEC60C8D3790BBA1120F776
+4EFAC542CFFBCD5C05F9510B27B2534B704ECD36C8B041FD49A96881302FFF5B0163A2DD09C751D6
+D6AFEA9170A4F4C4AB8D46E62F763FE1BDA51DD1CE4A27E772F3A2869155F762FF26B7AA6FCFA4F1
+292E56F03AAB6322BF867E7710C34D43B5D85B45AA68014AD7879EED051B1933E491496E3E26D9AA
+8B80A07BF2B94F1077E84A9726F08199887D66DE7A307BF33C30DD9CF3DA188088C03B2BAD09A217
+6B110DB2C868B53DA9A66C85737BA66C93C58A259860E294AD0191E3A72C73F40B0BD98699AA08DA
+F03587B78F391F3A4313C58D9F29B53C70785637BD0C58310109C54091AB0A34CBB0C478613A7AC0
+FB8F0A8B4645AC966395D8BA775262CD291136AFFDDF01C1D83DD4EB3B59CCAD18057FE7D92A8CD4
+A58F22508D9FD7CF356571F701BBB23E749BDDCBF8A317FDA0AEFD952BB18545610FFAD3AC143D35
+1B8DB3F66293375E0E50235F0D0466932181D377EDD32A5F0FFA4E22B5A0CB4F343D9A7E4A342E9D
+09DFF6C697630CD3971802C277A5590B8CA94BDE6B38446C794D072BBCCB724D5BC208EEF1B018D7
+39373BB910D668882CAA779C2D686081DE6A2606417B54D7C20E0E7F722648D893E4EDBAE8F00D6A
+6DA3712F91AE860C756D1127D133AB828E9D80023B50B162C5A1C5CDF70CCB3FDD7EA060ED20838B
+E1E50C4094C9E79E1A0187CDF780CAF45A725964F004253E034C5BE46BBF89D94631F1A33BAA35B8
+4FA2A9D08481C6674126CD96ED05DCE48BDA069D902D6836D5DFBA701DC0F98A863E64F0E312145D
+8DC0B77F25B43AEC729A1243B45B08CA228DD6101CAA2AC5ADCC8EFF84A4CA3F254176C2CC711EE6
+C273835D0FD3528ECA2A976B88E51FE347FDB60F32370B66D338931D6581630ED586F349C638960C
+31AE4204E89521A96E1219E696B913DEB2AAB7A3B022D06F34FDFCB810A04E60A4FEBE284C2F063E
+0AE9EDF87704921CCFA193BDC912B747E13570066223A49F1F6E2AF0D4D65DA04CA876FF7A462FFC
+9C0BA2CC545C3BD36DBE762F32B2D6BE5867C59F479195C92440DC165098B74EA5C3AD93CDF2D410
+B04C16BC7801E7956F4E5107450787AA592493171C3628E6B8F49D4F8429EB98DC52EF025F001387
+BC1A7093F7A99F10B5D2D7DD8BBB393BF6E56F08F4F7FA1A343F220D5A1EAE7168C74D41BE1DC1A8
+3BD65B72B982F4F7B34F24F97F9EC9A91011064031FACFF2A14921A32024385F4E061CD07D152E74
+1BF97156D951A342488FA7F5EF934CCAD13E2753A0AB7A1F565C2F7F6B349DF03BBC25BBD972A9AD
+F809BB5C5048A8CCEF9297B2ED3324D18867F293CC66E88B3A39D107B610DFE79A3B4E83A96D3D52
+A17FE8A62C9FDD271130148366942C9CE57558D023DA5F7501319EBFA33DE9E6D1E76D7C20DB8A09
+B657839DA99F3D8143F1EE6253A3295C9651FA4366547893C2DC7ABCBF4BB7609DE5D001E0A36D9F
+FBE01F7D0903B3208AE8547E2E5F14EC1AF4C2535CA8F4EA37E3F3CE172C7A1E8308995B1CC23E6E
+81190246BCAB6E755BF868D449BB02A2AA87C44C9CC0F571ADC72547CEECBE104BB274B8AC16DCB7
+5D5F458D356466B921ACDEEAE384E2EB1DF6EF393B41B9747F0A4FAEB4AF1928D9AD6FB7E06FDC62
+1E4C6FC98CFB43F88584BD55D9B97CC9549093EDE586912161931162B1B1D52D0443260DABA02AF2
+B4432100D5506546013DA703573FA8013685CC798CE501960093DED713FFCCF89CA2B9106390198C
+29A00864108CDCC1984A8BAB53919028C01B26ECC7925E38CBE6CCA8978EE21C2B06E7B3E48FBA97
+8E2A7D186E563C088F84AA23178B60E4729EE87D67B1091F3B6973676C1CBFE6530EB773C62E2C24
+97014AB0E8B71A1F4E86A378AA26591511BEE3CF3D64C94848582E1354E1605B6457823F2C5E640A
+D3802946BB2E7E8E594E8C04B430C2385DD40746CE8534F50842E74D7115F3DB0C72D1C9C607C657
+3B094AEB73B7A79876CFFC3E2F8C9FEAAA07D3BFCE05B61F7749A8793BE90CCCECA2D7077F25E899
+D3331FE161A7E86C842495D584C6E4A0880B2951D8A13B88C4672080A0B1BE36BF47C3ACE7288CFE
+41A8C1BAA6F0814A947FBD6B3AA72B6C73A8C578CA51CCC96F2352316C467BB960E981F2B6485BFB
+44B577E71EFDA16E7405954BC7C9F0759F5A9F1EBCD2FA9CC9648D5831A68887F41B15081A204C24
+B4B992A231DEF9E698D4C3A25B6F5474F5BE6A601F2D337A58A0D21FF37FD91EB86D1D738893A03A
+69F0CD743F611CDFFE69DB2C6ED0E4611D56F803BB0DC06E7FE85A303839612707647B1BE9FAF8D6
+84122CA9E5CB8BDE2936D3F4FF254D31529D7538BBD4D35539489F9E7316F24214B996BCDCF1818E
+749A71CF0E8845AA1E2A58AA62A48E02BA4564625D20AA220EE719608521D7D7A7FCA0BD8904A401
+9819D371F3F59D46C1354E5FC1A6E5F79B20CF4ACA2BF0F2DE73DA193A6F9ACBFE0B4731C4BCEBE6
+D96FE822965DE965232282A3A130361F188B3AABDA95A8A2790D9240BE008B6A6DE4BBFCADA05B67
+86B9BB8E0DFA0C30043A3B07ED46277E07B9808422C8ED16758B9C396F4EA929D769785B2C9568E5
+70A83B989B25CE200F1727D41E2B702E7F88F1784F4C83FA60A74EB26B2DA95126E508ED519A61CC
+151DB6804F61826C5F86D8FA89D06E526FED97A0DB88EDB432FF32C1ACC9B622EEDF601081AF7B96
+3C9CFC1D13E4A9C74FEA0A1C8E3D8653CD92A944D4CA6B0D306619AFD503506D77732D6514F604BE
+4610C2560931BDE0B40939BC1D126B0E97F72AE1B4A9252123B54F7A27E0CFA4425B4546526FD741
+CA77952B10D13E0AC2E32006A903808FF0CD013F936238C74CC75FD915244C56A8412F37F0134840
+347699508D6F3D7F3203A25B7C70100719582CD588590EE34B3AB13E255B613A6D00386A0104CC5E
+D2C646F09A88888D3751651D5646C5227A3C80E8DA1B0A331121DD2429F1F4775D30564DFF47D01B
+BE2C6C72CE4D1FD9A2077C04D2B0274B8916F6A9D1A4A6964A534F47CF241D5A8E34B23F85BE9ACF
+FC2FEA961F277539F215F8728D6788F67BEAF45502839BCF23D8763C3949352F00C579A9A4FC408E
+C625E310DAE61512DFE6844E82D36A2F81709E1F05B38AE9C222ED62C961EE63593CED7AAF73CE2E
+D3667740C77B309B93EEFE1B4BA65D48575A66BE86743DC9E5D3C2FF418D11F7F211B86E827EE1DF
+C3613E7498030F07050524536D1F8A94DDB6698BE7B963C55CB3F74B676CD815A7B3DF4B1A0EA2BE
+1B0B9A11FFBFD5B1FA49668AEE14629316AF436A0821C20BEEF7B3480847934A99F6D85B68F4DDF8
+859A754E009428AF89A90D1852C220A607FF0806E8080726EDC94D691D214B4521C147C4273AEBDD
+BB4A697EF16448CD9B2FC95293305858DECFD406B89B9F3FDAE2AC579E80CF321EBAE5701FB2F7CA
+D8ED04B4A63115886D45D6120F69AEF1A21D80AD3C2D35D2899F1902242B96CD349E0AAADA40F7A1
+1282B6B52BDD97708E58DC5E2D22D1153E5FA3F3B300BCDFAF98DEC2F4E3C82A1C85F985735F3987
+4F557579F422664E07CBE19DA680EFB0FC82C323EC5C4644C51709AC8D674608A8043C91E6C7988D
+430F10BA6CE1FC7FC0604FCD8F723895250AEC36CC35B3FA14FE2A0D24095DCC30B2093F2298F5F0
+A97676A0BE66C3DC9ADACFE2FC0F721A20E945AFC1096A619075D5E9A264C796EC6C90EF1AEEA8DC
+089B44FFC13D27CB2370070A52D4416C53F364393E46EDD7EDE00799960CE6E0D57E4909E88ADD64
+BDD2B0EBE2D73FA6ACF8B40280DAA0637E705C65AABD523B8815F22F23E9FF81E7829C7E4BC980C9
+143AEBE1A04DC0D253396BBB7268BD5AEEA356B610D5DCEE03135E00AE34388251F31714A1C40E18
+2652C48CDA2211A22CB6F02490E69A44CECB169754C53B16028D352E0119F5D5FAE0BD7EA1CDA647
+12A6147374B64244E21E9EC9F0D1381AD22D5B6212B26C3F9AA5F6045F25DD9F5EB4489EA39B1945
+331AC70510C5752557DE21D0A6CFC1EB10A98FA867B76DA6E4249469F591FD154D39E89364A43DB0
+07AA0D7A911CFAE6CE2B557997FBC44F55A27F622BD7B8B10EC9F5D10F2649A646FD964AE1B111B3
+5B46A252C4DEE44E7426EB5739F24E8A390694597DB3A1FE7800C97E59558322F0E49A0CCE2AD94B
+1E2D1026AFA771723E3F523916F55ED866C9FB4A2F759651C613A2CFF362028CDF9D38F05D4C7C60
+24C533E930B64B099FB1AF04B01F5FB9CA6867E6EFF55A772C5391831059987E10CBF987E3F378E0
+1329F73D54DC0484177D3C3C06F67397955FF1CA4EF8AD1606B70455255D631A7D6EB92BFDBA14A0
+FF28B2ACE7E81AD666EA9B3A0F5A6BA3B5DFE35044FA4B3D8ED956009C60E98CC132F2E84967F4A9
+8A67B336D5EE7CAF7DD1F74D1FA08619941361FA7312CF225D89CEF97E864C8369EAFAB94D97F056
+5505D825972B754F6729596EEA91210B75DD8F645382ACE36DE60819A02B3B48DD00F5485F9264F9
+FA926D732E2C267B0BE8CA98526F124F97EFDB86132C5EF16B103908172FC51F286FFE45FF253512
+E0033F037FF182BA536A9EB2DF2D1DB257D9C86C46E1B002FB32AC70CA9462E6EB48994752CEBCE3
+9F08ABD4F4B0889283E55500702185A841E328
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+cleartomark
+%%EndResource
+/Times-Bold-iso1252 /Times-Bold ISO1252Encoding psp_definefont
+/Times-Roman-iso1252 /Times-Roman ISO1252Encoding psp_definefont
+/NimbusMonL-Regu-iso1252 /NimbusMonL-Regu ISO1252Encoding psp_definefont
+253 283 moveto
+0 0 0 setrgbcolor
+/Times-Bold-iso1252 findfont 67 -67 matrix scale makefont setfont
+<50726F63E9647572652064652072616A6F75742065742064652074657374206475206D61696C6C
+6575722074E974726168E9647269717565204E657467656E>
+show
+403 361 moveto
+<64616E73206C65206D6F64756C6520534D455348206465206C27656E7669726F6E6E656D656E74
+2053616C6F6D652032>
+show
+220 439 moveto
+<202020202020>
+show
+220 508 moveto
+/Times-Bold-iso1252 findfont 58 -58 matrix scale makefont setfont
+<20202020205072E9616C61626C65733A>
+show
+295 566 moveto
+/Times-Roman-iso1252 findfont 50 -50 matrix scale makefont setfont
+<4F6E20737570706F736520717565204E657467656E206120E974E920696E7374616C6CE9206461
+6E73206C6120636F6E66696775726174696F6E2073756976616E7465>
+show
+1647 566 moveto
+<20>
+show
+1659 566 moveto
+<3A>
+show
+312 683 moveto
+<6C732020206E657467656E5F696E7374616C6C6174696F6E5F706174682F696E636C756465>
+show
+312 739 moveto
+<6E676C69622E68>
+show
+312 795 moveto
+<6C73206E657467656E5F696E7374616C6C6174696F6E5F706174682F6C69622F4C494E5558>
+show
+312 851 moveto
+<6C69626373672E61202020206C6962677072696D2E61202020206C69626D6573682E6120202020
+202020202020202020206C69626F7074692E61202020202020202020206C69627669732E61>
+show
+312 907 moveto
+<6C696267656E2E61202020206C69626C612E61202020202020202020206C69626E67696E746572
+666163652E61202020206C696273746C67656F6D2E61>
+show
+312 963 moveto
+<6C73206E657467656E5F696E7374616C6C6174696F6E5F706174682F62696E2F4C494E5558>
+show
+312 1019 moveto
+<6469616C6F672E74636C20202020202020206D656E75737461742E74636C202020206E6768656C
+702E74636C202020206E672E74636C2020202020202020202020202020706172616D65746572732E
+74636C202020207661726961626C65732E74636C>
+show
+312 1075 moveto
+<64726177696E672E74636C202020206E6720202020202020202020202020202020202020206E67
+69636F6E2E74636C202020206E6776697375616C2E74636C20202020737461727475702E74636C>
+show
+295 1191 moveto
+<6FF9206E657467656E5F696E7374616C6C6174696F6E5F7061746820657374206C612064697265
+63746F7279206427696E7374616C6C6174696F6E206465204E657467656E2E204C65732066696368
+69657273>
+show
+295 1247 moveto
+<6E657467656E5F696E7374616C6C6174696F6E5F706174682F62696E2F4C494E55582F2A2E7463
+6C20736F6E74206C657320666963686965727320646520636F6D6D616E642074636C20706F757220
+70696C6F746572206C65>
+show
+295 1303 moveto
+<6D61696C6C657572204E657467656E20E0207472617665727320736F6E2049484D2E206E657467
+656E5F696E7374616C6C6174696F6E5F706174682F62696E2F4C494E55582F6E6720657374>
+show
+295 1359 moveto
+<6C276578E963757461626C65206465204E657467656E206176656320736F6E2049484D20656D62
+61727175E9652E204C6573206C696272616972696573202A2E612064616E73>
+show
+295 1415 moveto
+<6E657467656E5F696E7374616C6C6174696F6E5F706174682F6C69622F4C494E55582F20646F69
+76656E7420EA74726520636F6D70696CE97320656E20656E6C6576616E74206C276F7074696F6E>
+show
+295 1471 moveto
+<2D444F50454E474C20717569206E27657374207574696C652071756520706F7572206C27484D20
+6465204E657467656E2E204C61206C6962726169726965206C69626E67696E746572666163652E61
+20646F6974>
+show
+295 1528 moveto
+<636F6E74656E6972206C276F626A6574206E676C69622E6F206574206E6520646F697420706173
+20636F6E74656E6972206E676E657764656C6574652E6F2E>
+show
+295 1640 moveto
+<4C612070726F63E96475726520E02061646F707465722065737420746F757420642761626F7264
+20646520636F6D70696C6572204E657467656E2028766F6972206C6520524541444D452E494E5354
+414C4C>
+show
+295 1696 moveto
+<76656E616E742061766563206C6120646973747269627574696F6E293B20636520717569207072
+6F6475697261206C276578E963757461626C65206E6720206C696E6BE92073746174697175656D65
+6E742061766563206C6573>
+show
+295 1752 moveto
+<6C696272616972696573202A2E612E205075697320617072E87320696C20666175647261697420
+6D6F646966696572206C657320646966666572656E7473204D616B6566696C6520706F757220656E
+6C65766572206C276F7074696F6E20>
+show
+295 1808 moveto
+<2D444F50454E474C2C202072616A6F75746572206C276F626A6574206E676C69622E6F2C206578
+636C757265206C276F626A657420206E676E657764656C6574652E6F20E0206C61206C6962726169
+726965>
+show
+295 1864 moveto
+<6C69626E67696E746572666163652E6120657420656E66696E207265636F6D70696C6572207365
+756C656D656E74206C6573206C6962726169726965732E>
+show
+343 1984 moveto
+/Symbol findfont 50 -50 matrix scale makefont setfont
+<B7>
+show
+418 1984 moveto
+/Times-Roman-iso1252 findfont 50 -50 matrix scale makefont setfont
+<4F6E206120E0206E6F74726520646973706F736974696F6E20286465206C612070617274206465
+204E616469722920756E652061726368697665204E657467656E2E74677A20636F6E74656E616E74
+206C6573>
+show
+295 2044 moveto
+<2020202020202020202020736F757263657320646520534D45534820717569207772617070656E
+74206C657320617070656C732061757820726F7574696E6573206465204E657467656E>
+show
+1779 2044 moveto
+<20>
+show
+1791 2044 moveto
+<706F7572206C65>
+show
+295 2100 moveto
+<20202020202020202020206D61696C6C6575722074E974726168E96472697175653A>
+show
+294 2201 moveto
+/NimbusMonL-Regu-iso1252 findfont 42 -42 matrix scale makefont setfont
+<63642053414C4F4D45325F524F4F54>
+show
+294 2245 moveto
+<746172207A787666204E657467656E2E74677A>
+show
+294 2289 moveto
+<2E2F534D4553485F5352432F7372632F4E455447454E2F4D616B6566696C652E696E>
+show
+294 2333 moveto
+<2E2F534D4553485F5352432F7372632F534D4553482F534D4553485F4E455447454E5F33442E63
+7878>
+show
+294 2377 moveto
+<2E2F534D4553485F5352432F7372632F534D4553482F534D4553485F4E455447454E5F33442E68
+7878>
+show
+294 2421 moveto
+<2E2F534D4553485F5352432F7372632F534D4553482F534D4553485F4D6178456C656D656E7456
+6F6C756D652E637878>
+show
+294 2465 moveto
+<2E2F534D4553485F5352432F7372632F534D4553482F534D4553485F4D6178456C656D656E7456
+6F6C756D652E687878>
+show
+294 2509 moveto
+<2E2F534D4553485F5352432F7372632F534D4553485F492F534D4553485F4E455447454E5F3344
+5F692E637878>
+show
+294 2553 moveto
+<2E2F534D4553485F5352432F7372632F534D4553485F492F534D4553485F4E455447454E5F3344
+5F692E687878>
+show
+294 2597 moveto
+<2E2F534D4553485F5352432F7372632F534D4553485F492F534D4553485F4D6178456C656D656E
+74566F6C756D655F692E637878>
+show
+294 2641 moveto
+<2E2F534D4553485F5352432F7372632F534D4553485F492F534D4553485F4D6178456C656D656E
+74566F6C756D655F692E687878>
+show
+294 2685 moveto
+<2E2F534D4553485F5352432F7372632F534D4553485F492F534D4553485F4C656E67746846726F
+6D45646765735F692E637878>
+show
+294 2729 moveto
+<2E2F534D4553485F5352432F7372632F534D4553485F492F534D4553485F4C656E67746846726F
+6D45646765735F692E687878>
+show
+294 2773 moveto
+<2E2F534D4553485F5352432F7372632F534D4553485F535749472F534D4553485F626F785F7465
+7472612E7079>
+show
+294 2816 moveto
+<2E2F534D4553485F5352432F7372632F534D4553485F535749472F534D4553485F626F78325F74
+657472612E7079>
+show
+294 2860 moveto
+<2E2F534D4553485F5352432F7372632F534D4553485F535749472F534D4553485F626F78335F74
+657472612E7079>
+show
+294 2904 moveto
+<2E2F534D4553485F5352432F7372632F534D4553485F535749472F534D4553485F666978617469
+6F6E5F74657472612E7079>
+show
+294 2948 moveto
+<2E2F534D4553485F5352432F7372632F534D4553485F535749472F534D4553485F666978617469
+6F6E5F686578612E7079>
+show
+294 2992 moveto
+<2E2F534D4553485F5352432F7372632F534D4553485F535749472F534D4553485F506172746974
+696F6E315F74657472612E7079>
+show
+294 3036 moveto
+<2E2F534D4553485F5352432F7372632F534D4553485F535749472F534D4553485F666C69676874
+5F736B696E2E7079>
+show
+294 3080 moveto
+<2E2F>
+show
+344 3080 moveto
+<534D4553485F5352432F>
+show
+596 3080 moveto
+<61646D5F6C6F63616C2F756E69782F636F6E6669675F66696C65732F636865636B5F4E65746765
+6E2E6D34>
+show
+296 634 1 457 rectfill
+2109 634 1 457 rectfill
+296 634 1814 1 rectfill
+296 1090 1814 1 rectfill
+280 2167 1 924 rectfill
+2125 2167 1 924 rectfill
+280 2167 1846 1 rectfill
+280 3090 1846 1 rectfill
+showpage
+grestore grestore
+%%PageTrailer
+
+%%Page: 1 1
+%%PageBoundingBox: 18 18 577 824
+%%BeginSetup
+%
+%%EndSetup
+%%BeginPageSetup
+%
+gsave
+[0.24 0 0 -0.24 18 824] concat
+gsave
+%%EndPageSetup
+%%BeginResource: font NimbusMonL-ReguObli
+%!PS-AdobeFont-1.0: NimbusMonL-ReguObli 1.05
+%%CreationDate: Wed Dec 22 1999
+% Copyright (URW)++,Copyright 1999 by (URW)++ Design & Development
+% (URW)++,Copyright 1999 by (URW)++ Design & Development
+% See the file PUBLIC (Aladdin Free Public License) for license conditions.
+% As a special exception, permission is granted to include this font
+% program in a Postscript or PDF file that consists of a document that
+% contains text to be displayed or printed using this font, regardless
+% of the conditions or license applying to the document itself.
+12 dict begin
+/FontInfo 10 dict dup begin
+/version (1.05) readonly def
+/Notice ((URW)++,Copyright 1999 by (URW)++ Design & Development. See the file PUBLIC (Aladdin Free Public License) for license conditions. As a special exception, permission is granted to include this font program in a Postscript or PDF file that consists of a document that contains text to be displayed or printed using this font, regardless of the conditions or license applying to the document itself.) readonly def
+/Copyright (Copyright (URW)++,Copyright 1999 by (URW)++ Design & Development) readonly def
+/FullName (Nimbus Mono L Regular Oblique) readonly def
+/FamilyName (Nimbus Mono L) readonly def
+/Weight (Regular) readonly def
+/ItalicAngle -12.0 def
+/isFixedPitch false def
+/UnderlinePosition -100 def
+/UnderlineThickness 50 def
+end readonly def
+/FontName /NimbusMonL-ReguObli def
+/PaintType 0 def
+/WMode 0 def
+/FontBBox {-61 -237 774 811} readonly def
+/FontType 1 def
+/FontMatrix [0.001 0.0 0.0 0.001 0.0 0.0] readonly def
+/Encoding StandardEncoding def
+/UniqueID 5020947 def
+currentdict end
+currentfile eexec
+E98D09D760A3C22CF119F9DC699A22C35B5B35ED6AA23593C76D54CABB5E942BF7D6DD84F1664B89
+699C74B472DE9F8E6DF925F6C4F204E9F1C639B4DBA988ED2AC419FF2B2BDE605B8EE3264EDD6641
+2D4F21C64AC522BDFC7C5502F9C3F3E5592B3B2093D33C9BFAEDD2D49E89AABAA832E23F062E91A2
+5032519D1868816E44B4E0747795003D7930299D6E1E2A5BFE0D595DC97E140989CE81D8D7F852FF
+9CDC7A1B1B598C69131DEE005B415805A16D8A123E6A208511C6D0C255B9A5BB2FDEDB4D399C6CF1
+94FFAC236883767C0F68F4EF84EE696B677DE704EC3B097384F2E673A1F51692B7B260693738C211
+9F7D90FFDB21EB715FD5B8134FC87DBA320EE54C2CEC6A4D6BB350555EAFF2EC4F84365CCC0802DB
+B3BD0E3F0D9F858647DD637725C2CAF9557FDF842A0DA6A0CA0F1B442EF8EE6CBF2B03858468A466
+AC5883CBBD3815B283343B39205803C02C917D06825C09E2BB14609FA32C28D720C0E14A4B12D4F1
+25FF6281FF324DA33A56FC49987AC7D3AA206540F8127273FFE9A3DACFFE2B1C269D3DB9A811578A
+C7D532C2EFC18376F473FBB2B32EF642B19CDEC1D6DE83643723E3C6DFC87F97A7007B6081894BBC
+45C955B7001EB36211B26AD7A3D07459CFB33F9C54A40A360CB802FD202C8E93D4DB888B325CE246
+D02D1220ABF55CE646DFB45F07CB848406E470362F80CE4C02D98DD845189877732744CC16C7F566
+9F77EF096EA55AFF98AA103EEAEFB971731EBF3782E6AB725D4E9E35B2968689E8007C038CF25B6A
+E69451A4731E79AC22BD268F56942A233E52D71873E83E00A1874E04D3B22E72FB2D0671AF81C698
+53C389B51F4A257373AEBF4DE2DA1E4DA5E2CA88941F81EAE0E32D982064C8AFDD7A9A600D56D736
+05B9463C6240606B3361BAF22AF74EF89AC804A5793BD512DA2D13F4BB1B73EFCA1E621ED2A65D66
+5AAD0AD228B3B7E3D90DBDB6061E172B686E92355A7C7459D83199040A368B5697DDC3B81DDAD341
+6FF4405E1096B1240EDC18A0E9985CA55A0D697972BB11E9F1BC30765D6775BB68C69704BE200EEF
+4E11B78ADDB6229D8FA49A6B1525ADADF17122C0FFF51A08AA7AED158724AC4352EBB91ED0C157E2
+4281BDC1FD610195F495E87062A8C38E0D046DA4067EE16E81BC5F87E583315B973184E474064482
+9B2A52E0D37E249BAB31988B906F891AC904D1BB8901F0673AECE60ACEDE97B8DB7935C6488ADE8D
+FD898027424AA85A11A3DA494498B084133B857017A6D507D70A3421235486EB3CF7613C59139FD4
+DCB92EADC60BB6225D9CD0599779217BDAF4813A453989B2E56903F4DBB83D83DF4837C86BB4C3D3
+CCF98F07A23EBBF7AB5687C3E1E6792E40F92A7A466DE352294064537505EEF3F9C308C9EB94506D
+B02CFAE289F10005A6E42D2DCE43731A7AE368564B2983038DAD6987F67062199018395BC0FCAF28
+7A2B040C71F7325FA1E9A9808979B2FEF19096B98B8A0A728EB98F2BA3D33B49E3C20BE992822C7A
+1BCCA5B4E4D1099D456D8D7D83C57ECBA0FF21428024F7572A1470317CB8CBC8679A974E13D88C68
+1338C68C9AC9557F97784F4E1C8C2E61F26023ACF46232CBBDF3C0BCC5583B935FE9FA09A562129A
+8927AE73988DB0F7E733C6561CA7C9716DCA9B88208A715166F2FAE6D5EFF289A9B2EDCE813403A4
+16F243F1B57EEDE7D81E10C2DA4065A3082BC92A38B2457368EEC9C3C17296CB09819E9E642D7365
+F9A6EF430FC7DD611EA5FDBDEDFA72634AB599EB666A5DC178B0A0BD1FAB042792115EF3B6222C12
+41DCE36CB38B738F68B1B3CB489FED9E53315553F3C5C3BBCE40451E47B7EA53FD3D3ABA6CE0AD22
+5DAEE734BDFA3BF1D81C1B42C6D856A05D0924E03F7627C5EB24D7FBEA3BD85716207F961B56803D
+BE046E81ED5FDC378F9CA52C14FD8544CA7C539201BEE06487EBDC30FF3B28E8264EC7FD5DA7E080
+65B0A9147344CE28DA5182335875E9F8B2347A44E33DFAA167232A5C3E69E8C5B58B7C7216537827
+C936F5741B87FC68753EB0D4A466961D0050DB59DF3195BD3379F5647F8CFED35DA952D7CF2DED45
+EB442DBFE992711D22EB228BDDF36B8D7DBA27062D60D2271EA8E8412F4290B58F5BE26FF06F0559
+872F9DE4DEAABA015EAB4904BA1F509F6D517C6E897312DDD571D769BC474FD378AF4360E8B1F103
+AA75F48721B9E0BA589319E15D74AC0B03D730C3EF708C7C504787483F134EA6297097B46D2680FF
+8AA50B7A255563C88D594B912F5574564A1371463674793E4834AF11D14C7991E7FDB3A6ABF8529E
+1A4F10CAE79C60D37429579093DBD041ECAF03824DF9C007E96F45595A524B27EF8774A83AEEBD3A
+7134AB4435C80944DEFF5C1CBA921B0A41B9651968581DA4834B3C0E6D4DE13C1E792FCEED26A72A
+DC4D9E3903661D8803DDB58EB2B929CE31FC9F50A694116B00AC9F3EEF53FFDB1ACA3394BF111610
+38F39917B022394C75A0D467D64B89A44E5505DED7D9C6B8BA6BA098F140C9C00E09200EB4828356
+A2D6BE9EC1D5524B09C06D9C6FCB5E2808050A339B5E5FD4DD6C2035A48FE9674520901EDCAD107F
+67AC8C8E508E6003011978D77ED225F361BC0F86A98B6120EEAFB73F7377DB1E7213E02D12C330F5
+492511B4DDE08558D75D5B8AA2D56A3111DCCD257EE96E3446EF1C76F000C8916C4CE261425ED9D1
+5B58CED128DAA6C1300466E7B152BCFB5E6FAAB2519B8A98F26B29F98133AF886A0AA7E586A090BD
+A1DC6120DBB5640885C609A8BDADEEFE5DE0DA5B75A8A29E92515E86E7E66BB29581E5AFF8CB6551
+D8D1103DF60D558E7987E6F56126A13DB2C9A04886C655064E68A0A20D1B7DE24DAD22BBFEE1B7C3
+C208D4FD6A58DE78D6A0A6126EFDEE3B1A9713DEE94069A9F0A2B392A2F391C4C75327803B53F252
+CC9EF0323F84929BA4716C50385681FF5B4ED54929821594F9026B7C1297941B178C3F8A704CE097
+60533DBC6CF4B18AFBCBAD039ECB2EBDC7838A9410E7B227924BED7123944675A5DBCA388B710F8A
+F6048B03DFB713F881EA0F3B191A5CD989EA150B979059C8AADE403855815D8F7980CE6288F47EAA
+37C1097D33F13776F08779063C5217D7408D9835AACBE5C071EA40C9AE6DF685F4A9827B828815D8
+F3A672E73A418E5CB15684EB6C6FE0998A386E124D76620446907F993BE16FE5AFCEC681F585601E
+18182EDCFD3024062A3082AF97E803C47D32229D0A24596CF7E03F18229FA631175699E2F0D60FC0
+9C4F1954C5D12D03BFB4395F0E5EB6C6877083807D91D93CA4177A6B5A8D2AA500131FCB670E7118
+73F8A3C77575EC93A3ACBA37EA117DB268CF10D04AD0F079484DB124F6DC14A50AD3B0294F7157D0
+837D8F9A6060FBCB385606066401708C041594E0396A0BE4B8B66FEA141CCE4BD29366A986ADB98D
+9A6935C49C57F8CD415E93FF8AE0DF75E463E02AAC68DF064C1B789B685F84E15E512404E065A39E
+9E8F5568A7D97671AE1602605FC7E4933975189837586FB1A55007FBB0E91382A629277C36A190BC
+85AF49EF3F0F38D4ADD2B5DEE09916B79690EC83473C63E92CF617617A66DF472A49641DA10654E3
+AD3880D060B02A4A6C75B51E4E9917A2B6D8EFDA12D59DE5A8E222DC7E82F02F23A9D3DBF637154F
+719B14114DBB102BE5EB76B441D7E9990EF6420C2E80942C8AED5A1D0B19BCE115B5929AB9E145F1
+496753DD6B1798324F5EC1D0C7F26FC3045D7BB46A14110C99BA07A45EC16002CB754C0BAE7A1A88
+EB387BB345FA70B0A38AB4D532C2DE49274D4F86F2582728A2CC54B4C09D26C0CDEB8FEE6A42885C
+6207D74953CFCC583ED82DD7C0F29D35BDAE5BB251B8A2D4B1DC97E2264DCE035E359DFBADDE84F7
+37EA6A59C23D1A64D963E635769233624F7682EA34636B595CCD064AAFF3887D916867475731BFCB
+F7F96D5E5E1FBE6AABF454C2F504EA4E8EB382911560195295C87793D5F7739AD7EC7176E126413C
+D4D1058EBD7D6EBEE14BB94A1ECF28B686411D91E07373E891F78C4C0A05D2E8D90A8AE2614F7FC2
+63A762D0F43485473A54C31726F8547701D4A38D20565ED1707847AED9C805780F062B847E668E15
+565CBA07A72B0BA99F03FB57D26FA26FF579C30EED0AAB6FEC1B5DBEA81AA88F16F0C9BE869505BE
+18C1CB79657D91D6706E2A3F0BE9920655B93EBBAE2B4D0B5DF6BE622C951F2CFA42AEDBF7AE649E
+2150FE87CDBF5C2685EF36051080BF39D864573A45AE2648AD97662B1F69787031B9BC43511FB841
+55ECDC3D91E2475D072BDE6A5207ACEA1E0D2ECB1DA8A1BC4BEEC335A5C7102963E84B97BE741C44
+58ACC3D72A7E53B1F08C955F33EDC3A0DC3E7308270C0F7FF814B111459985733C62E8863625A551
+837952F3CBF32ADCFD9F345E14B585B23ECC440775310654DAF7F41E56FF45F89701292019A94BF3
+0EB2D65E14B1A1D6BF89D4CC43187ADADF3F6E03A90ED01E5D876BD3AA56E5EE84DBAA4DAD9824DE
+9984BD45AF96FB8A56C010B3C3A3C6139D58E9D69D9109DB18561B55EAD6452497840B9AE90C749C
+155B6329716F0152A7AD52DBD0B8A25B9995E1416681F38FDBDFA443879B5C4C25AA29E0DCC07DE8
+BB161C36D76EF286EC88D57C74BF44DBCB4FEFF771D3BD82C8F4E233357C48E516EFE3DB9E60EF16
+8E2C45B54651DF9A5ACB5F1790F7929BCB16CE5E9F6A43919AD287DBC8E12D9F9E97E5DBAA592879
+1A5A02D39D259F3CE273A870906A643CC18D86E23F115D2A35DE6926053D8C84B940B362E7DB183C
+4905060316B269223DAD309EB5AC96DEBA757BEA45FA3100F77F4765334EDF3D659E09BD1A5552DA
+492BE9174DD406F8353A059ECFEE3709422940A8C369919EE1F22F7C02412C995FE93DC4559D32A3
+155DD22D3526D89B16D9ADDC30CB7ADA6E52D62C5F2DFD142D4D7B6E066671EBAD08F54917E31704
+1F410CFD8A3243F8B39459C418B7B7C6494551C6F6753A94072D09E0D812351D62916383C6E061F3
+5ED864923002007E626089772D269B298DCA2CC1F25D9BE43FD8AD62D554C16AFEB7EF6E5DDA66D0
+5A810F003CDDCFD2C02FFF02BB61344968091F67D3862C1499409ECCA137B9A2A9BE314995B818AC
+CDAE27ED4AD583BE29DDE4E8C2400C5F8152C85709AD2A4737BAC768FEB70CE81A92C9657DDDB2D0
+BCF9169D272A063C75C150ADDFCBC2F5F2503DE3D13231AA8CFB396DB38E80197A605F6BC20EFA1E
+DE40CF424CF221218D51BEACE64A3DC88377E4F3EFE43DB4F4FC0803BF61764104CFF0B618C90311
+98B094E20B0FACFB94240B438B67BA298E31D3F4E31FD190E48BFCE27B1BE29D36E765E7D295E96E
+DCE09094FAC43B87E294818FDE9363FC7DC5EA36A1497EE25762D02DFA00A9BE53F87ABE62E52ED6
+F59818FDFCA643042EC13D670DED1980413950EE43372D31AE2694B83DDA42E1FBB049F7E7B7E69C
+93FFA3195A2462423DD2C022E5141783FFA07E192AEBC5070F08B23AEC9142EED56DA74F93BDB504
+78DA55DDD0A9987FEA131E4CCA0EFC51064E4B37632728261369C3FEDACA100F1AA78FB718ECE7A9
+F56296C5FB43781E63F36B0E1D34BB748EFF35E1953941F94D1A9B0FA474FD68B47183F2AC53A63F
+9F1D30B9B89C5FE54C3765B43DB403D57994701C133E42B950D9BB1CA202F15B5E590EE75598FAE4
+3D5CF1546572770BBA9A6373F100CDC61DB4E5EBBE0A93E0E51C86005E333F69110B1C8E492F2BF2
+52CADD5B73E7D3EBB53E759353F1EF3C9B8B39C230D13AB7158A5D92EE4C452F81F6DFC18803280A
+A023832FD0DCB482CE5AF615C952BC3F7E58F6417D69775FC7C0D5B405AAC632857736ACF32B2EE0
+F2A2C0F3B3CAD483C614505BE94706322F2A2830FC5AB592907D0291ED1873377E7A6158140C2CDB
+1B0E27EEC9CA50176102200992308045CCB5A169B61EA0546778B8D280737319046716604945A21F
+2A1CB9E15E3A5DB31E0FB5A3B0AFDFDF6F3424B7536D473F9756CA3694DEE4301FB1AB1AE47128F8
+D2B461C051C1B999DBB010E78DD13AFCBBA6F7D5226D540527F17881A18F551B3EEF76A7E28B4FDD
+879381A2217EF2FF9F9982E9EA70AD2003B862D7C36D57C5FF9FBEAAB56040FEE973EFC3B34D8319
+1960010110BA10694C17B7635AE03CC1CD087C0B05522A7A791F0CA34022A3F5860B536D9551BDFD
+BF560A07F63AA4E687407E5E48584E689591F1B52671213E430A708C06A34D2E1D51CFA6B328A122
+007C81B5EB263B967746961BCFC8772F8502DD95898724ABF369B0877F3313A167F3F714023C229C
+5757D4D46FCD9B4AFECD093DCABE52B78132CE9AB6225C9A344C4BF8D96F2C50C4272CB9AA0D606F
+013B2642F8C880E08EA2822C8CF5097D2CDB64932FE195ABD5FDF36D3BE123AEDD8BA2F82A8A628D
+BE3ED6129DC0FDC4BE50D5574AE4FECC65062E70F4703BFECB35EADE196294FE173EA57938679DBA
+6D15448FF44C0D1A903B202439DA93C0B0E612110068F8079219AA89F435E44D0464F54833BEB338
+670BD820D941DF4B31F51B895BEDF833F9C43CB7616DB80F988CE72FD3C12C7D49F740CF85B4766C
+0ED398EB837695D102DEC16E24B7475A0F5DDE88FBF2D6B94F126417C811E8362B9CCC52D8891C13
+C10937AACC228D621D4712CB9DE0BAB60EDE2A97E9292BE04E42E6D3425594DF56931A61E1F96172
+6AF6E6891D63B240E6E79E5BF30C052091D681BA1102409874CFD8EDC3EE2BE331676E31AC00F807
+91D1019BB789CA4F5907F4823B002AF3581448C352BB67D80FDFFCD1C5BEEF60523330AA2C045600
+8F62DEB55E69AC2F86369FAB1ECC90D2487954E61117A90D9269A65DFBDF297EBD29C3DD1F62755F
+8F289C42A534F59650685F8576EA2FC5D26B99B8E3DCD3F1FEEC73131000F99AA9868EA9BAC0B56D
+AE2CF46DA6CC1D18C0AB8D77BECFF7B89992175CBA2E22779C13DB9DF53FF5B1C8FE95E164997D94
+202C37175E562C8622989B075CDCDE173452C064274354D5DB8F7D5A78D48AD4A103B9E47500D08E
+DC7C51C1F3CFA7F43C3686A3C24A7EB5018B0F419961564F87E212CE0A0741AC68D6822C7AB9FD68
+85F5D0B2AC249CB7F50E2353CC4B0A6A24562F564FBBC7090C3FDF1284AB0EC615E0B3FBE132F315
+70C8A65C814F93910AA4BB80D516CB70D2E1D11969238E6F022D628FA2F33A0A15C4EF0CE7F753DF
+80A8AD9494885A1B9ADAE6C38AC9DA6FB0A61696AD3A502630252AD7B574C841117D34BD20BD6581
+217D977B35F5D04E02B933E1E84F5C090F6615AF484D63265D28517BA74BEA8876FDA332A84AEA12
+E6CD82B94AE10A778CD3A216ABC08495EF319F06AD6FF8ADD237D911F846A514FDBFAA8A1EC8E0AA
+9F80F11F1CE615519A4B044F3D1CF1A17D7F3D2174222A5FFA8B39F20197FF6CAF250B6ADBDBF519
+1C525070C8D38220FB501C223F493D80F498621A02EBCCD6EFE914F16B2A435D60C0A1A453E288A5
+3D818FE1EDCA7D55A26A017F2EE47A816E90D6C3FCDF0035EEA307DFB06D2BCCE43458A67354A4ED
+B6E5C57233DE4FBE41ED07EE5EC77A5DFADC4032138DA9E1B74428CAD02A913E40152F8063A774D4
+FDD4070E4B8A6C089F199AF7C529C277E902195DB760D81EC655DFFD1BB283F3C5AA8BB58F2476BC
+797B2892E94414ABBE96D4DB93E280CF7DE23EB852E7CA954D6682A6F1A4BE0507884C2A05AC863D
+2BA73F3B54668397B6C54DC2F4183130AB414875F3C3D8792BF7E5FC4D228DF87748BF0B14178DB7
+E3FFB7891D700A1E9520D778B095DA80E4801F53442D5C073EDEB706A5DB8466FFE7E701ABA9C364
+A37169F585C883A83713A61C9C3BD9336A667EA4E3DB5F4DF6BC6A552BE8D3EF093639EC67E5FF71
+8959F9902477F5AA894ED2D1CD312ED82EE417D95C49C96671B23FB0E1738E892ADFFE62EC1C3D4C
+BEB6CD089C98DE8D247DF7ED17DFA2959D3662F105E8386D75AD308480536959F8E6CF8F2C6937B0
+9F2E8137C811327D6B165ABE46C51834A955FE8306D10033F8C2A34667F13A8BA831CCF52C7A21C1
+3DB92F3E77B55CE291F6190BB1D194A33FD73151C3F61ABD2D8A0C9BDE90E796BD996D2D0094DB2B
+E98657E751BDEEFE8A43EE4501B98F0CC6D80805189438872A60047A8CAA9039893530A3E5F6BD75
+BB466B25165737C939AFF3EA59BFF4A7DB09C2A5B36B8A1F0C6C5E5870C7C9412589877EF44F8428
+4B8A53B5B74315CE72D2EAFC631BC4CC2E5B71DC958B5A6350CB5F615C3A4502E973622E3E18193B
+69572DEF1D02303A375ED60ABA1BC8A179FAA0F221A49078FE15AE13383585FB45FF4D5F3BB3D0F6
+D8BF62E9BD6BAB3C9A7D38C8A5AB0BE57ACDADCBD02B1DC7952D73AEF702D406F62719922BEA96B8
+FDC9B879708E794891C7A0A42F2CCD6812C3F4DB030B5178E3A627C3E77621D312CE4EBE815CD387
+7208FAD92761A5396B67E835222609F823728B1C987857CFEAAE21F2AD5EA9D841212993508091A4
+A2C268BF1D8DA1C650F6AB93995E7C13A3F84DB55748C626FD09C0DA1E3325CCB0BF091E996245BF
+51EB486680162BAE63B6513C74CE83B92359938439921950D713C69324A87BCE67B45A030C9CF10A
+DFA0A82781D49FF224AC57A23C6CB321F95915C5E14E41FA852F66E1E2044A9E7B1DC3BE9E818515
+D28B2C4D2F2210098C39557067062BA4239F2AAE28816D999955910298A450741947A9A1AABCBD8A
+FF3530626089978C87DFC73618C044731B6DB8007739A9699ABC354A6F985E03C11D750B8B9E9AE0
+5436205FAAD1B895B159E2C90562B82A62EA1A7FFB501767DCE2B11C51D55A17529EF5ADF0A0EE9A
+96D0E7E89F68E50EED813836531B4B46E9071E84AA413F4135CC882CE832BF78ECFA7CAB0C9F64EB
+92C86DFCD1152BB7D4AB33831AA0C139B555967F6346068D5C3351A7A4368EEBD2933E6B9F789DAF
+37EF536FCF965C397AF1B7F98AF864B301F3F440B7ACF704B59540453678FD6C1504519481893812
+3E2F47B265EC4F5CF2172D394543D84CD4281165CBEB11349B315A85DEB2D1699507B0C8C110C726
+62EA2959C4962FF093AA5EE6F21F89B3CCB0149CEFEF1855B9A48D28BB363416C015A1F4EA1975C3
+D8807F616C5817C8162536176F464A198EBEE6C97029F15F414275A39B8219128B8C8542E9483550
+7FC2D3908BB0EC375771280B9EBE87E827811418EF93E52EF70546891BFC0FB34969FD7DEA4CE752
+4D9EEFF2B46BED908C0FB2E02EFC1D1624642EAEA1CAC1EB4841E020532E88E59AC890E6C3F44734
+B99722E9816402D1D0FDF8045C5481EC055100836EBFB48E9FBC392143032C909853C9BA38A19363
+141BED09DAF02FDF4E7CC9808321CD0708A1B45270BFFCC3A0D7C27F7E781713D5DECE82C72ED303
+86B02D14575A1A6447547ECC7FAAC1BDFF332C92984758E242256C054656CDD2C45D46E67AEC6F83
+9F95D74E222A6EAE12EFAAB723A7C816D4E42D4ED2725A794743F67597F3DB8CCDDE45BAABC25726
+B851E02E56341EBE69E4D91F2A233583EC816F18A1DECBDA4AB69320F55E730617360FCFB8AC2D2B
+737675B406297F7F8C4BC370CB084C22BFEC5FEF02E9AB290282F7B153F0A4B1AE569F1E52371A43
+46A748DDE09336CAD1F5337FC3D7CF0677091E59480AB15021E023E356B0E1BAC6C6471AD53625C7
+0206C338536F4D0D40733AB217E2297F86B593717C61458B6C93A16027CC886A8CFDC01EF19C34C9
+A608B95A84B6A2E31454BC03C10FA55CDCB7B1EB7DC16AC1E93981A46DECD7E7F00638DCAC568744
+69A2D9B45CBC81398727E4ED3DB5DB31965F358D8179CBF934EE2C4D652C9CC211807F070C80E3A8
+222B4C31FFEC8DFB9EE07A94C973462254BC1B1581903EE6F9AD91524A787129A63FCE048B45BBE6
+855826750C586B6B23B805FEC3E7AAAC079576949A06F422FC2C826BDB78AE96135E9E2C20C2B2EF
+F6171D610B2EB8635ACAB7C5C5ED9C9FFC26CD54D2FD4CB9E4294E178CECA1E16CC8E3FC06518BD1
+6F4D63AE2B435753538834CDD9D8AE7DE624006CE688938031336351A6578C304C2E5480A3FCB43A
+8BEE4953DABC30558B7790C6E7A6F0F9FFA557C50417407AC6A0DDA1E736F7070BC89455FC293453
+3DB004AA9070734C8C2608A07330E421A0220DAB99F8A77489132F6413ADB9EA637F3B75948050E6
+67276A55BEB09D4153DC126BBDBE0DB9298AC799A943D72AFB769BFA1488D311BEB86A907EC9385A
+AE4F77835DFFE4389E3D9ADED1B08BBC2B1ED6084B3D1074A326CCBF38E06BD026919107BD03BD9C
+30470DB779508DFE0DC82DFFD2DED749E872EB7EB9DDF509D5319865070DD76846C34E4E43691AF4
+29AA40DB4BF2CDD50B275589987D8081F7C5A0461AA5D1455A660178A94A0BA0DCB69C3CEBF5EE04
+26D6534F6F919D9795AD6A0E1A1F452AF3B4CB2EA54D6011FA809132421D111EFC51174E223AB6A1
+3596411A9723079231B050CEDAE7659CF168C39AEA9C6902C2CD37D25492CEE00096EDD63DC7643B
+667FDFDE5B595DC54F0A72C2650E1E46990584C78A5CEF9BFC3C5F88CFB0C49CD6CADD9DBA675177
+D601927D75C6902B55AAED0E9E3CB52A577C887D581B3CE6201A1C77C9546CEE5A13B92963337F17
+070E2BF9F5C5E86B84225863874618AA50F4DE855DE567BF2AB7163944ED43DBD7F4BBC0E1623180
+7C43DCB47B2EB694E6FEDCFBE26194D2D9943A1BFE32AA1E5305F5E341EA021F91532162978DD1B8
+C5295A5E7551E2DEE46DC2347C6B32197AF430AF3BB676A53BCA9BD1EA88678377DC0A9A86E2AB6D
+E29E3E261BFD5573C66FB5687BA9C0544D894A759866B066E1DB5C66E60AE071CC3A1C4AE40197CD
+E4EC723F7B80137619DEDC99AF57A5497D6E03C1C9E672E74F48F6C213A3CFACF2699CAE72345A51
+C71C1D69348DE5BC5F443EC0EADE1E76A8A33066922CF3869E3C1D26A3B34E540DC08EA4DA2DDE3E
+EB17C16790DA4EF1A3A76D71D34B788A87838BF2A5A3DB8176F9C097D2320050A79EA6C4A94926DA
+11ABCDCD26DBA09FD33F30AEED977E8B5AD928F3967F607628859429DCB4ECEC7DA3411BE35A0385
+1017B535985632639D378CDCD13B00FE537A49FD9EB6DF1E3AAF5C41EBE35721FA6833C2FE08AA3C
+FFC3477E7FCEBF9EF9F4DAE62FF78F319481C3F1E72999C8A493EC6EE295316B58A5CD62FFAB62C8
+96E521B678342F04BCE1613CF7F6778CBF5227BA20504500D743270771953ACBD5C6586432F3FA6C
+0987BAD33B88BC6C15D29C4B3CC54A9DD72A2357AA5BAEB2CB057CDCE72DC80CC98C62B16AC50B4C
+6A7641379B766CDDF990DBB2FC7F9CDBBA755B6E3DEA438FD6699C30A99A8B3178E6D613AA938120
+835E517431D28114BCA1AB745C11FE6E52ADB82B9D3D53A33BCC49740C93017D9531ECF43831359C
+5C93CB0E926DB440B139E3125CC2E069B1CF6D96EF68407F32DB517242C3AE0BC6723E560B0F45FC
+7F87A5E44E1751C8B7F9F669C24AD5CF16F84FB03BA121B86B0694234D8F2C9C947269AF96FCA08A
+78F736E4E04ACEA44C5BAAFDE360FCD8BA6A59724CA86160A5527FD564468123D302DB45173C1B21
+6B01DC5B6D3415B13FBDBBD3121A5493374B3357EFB131CABFE5087AA1D2C7472B0377066B3632C8
+2073C6A846285CC953A8F28E131CF587B35217EE498D9A1DB57B063CE068DAF55D8CC1771C0C3099
+9CA4FDC5D67BE4E7E69418F6334BC6149000821B89A7437CCDF9A6A0ED702D5968F1E04F7E4FE9FE
+C9D1E994885CB624035BBC5426CB8EDF0456828F8EEE75BE491B45FAC192A405EBA25CAA4F4C66C0
+DC234D7B417628DA5276C08260BE512B2432256C401A66E3B583E69D23E9FD278CD5F2178544D054
+16B9B4F61A88A4728AF2CEED07C08E207F31D644E8E3BA1E4E2F9D8E30936BCB9C6AEB54E37DB46B
+D64F2ECC1021336D0564DF0F18E5A6B6BA470233D8D41FDD9D1079706EA685B6D8A740570BFB78E3
+984BB155C3155C69BCCCB41CB51975EEA1C1B4294CB546CFB03DC31BF86EC3BCB1977E8F94A771CA
+B09DE12A82F1D6C791FA7800E5A21DF81C9C8FCDA78622ABE75B54AEEA747AA4F26D563200992E33
+7231A430137C720A17D44F3AD6CFFE63B2DE12D3184BD3E151F955786B8DDCCCB290C42718F3A219
+1759DF76371C2FC177544A6C425CAB14AAAB31628A9CF9D71B5257AFF0D59843989CF0D747375A26
+DC9ED29B66AC2147DA0168306C48C2484C70CA92F33C0C138F92F276F5EAF5EA3082A8A1CB12DB66
+1633C2F71E3B69918F509060AC949FCD52C36498A2ABB77D139DF1EB33E3B846A7C1BBDCEF5DEECA
+4EF0AD250CEA9C2751E13EF7681E8FAE0491CFA6C144DBAC1FC39D39E76EB12D3EE9CA159AA77D27
+94F0C433345B135BA632F544082BBDC9471E9FA3AED3A7D465AB7158E8AC97F68B1FBC8D368E2350
+45C18EFCCADEE98778D894D96301F903283C5AE355A863BB0DC5809158F7E108662D04A5C1234915
+E7BD5B4C30F9EFA55E702E54F87FCA06FB321507BC57A1E55CC117E21AA4E3A4DFB77C1A949EFE36
+6D93F2BD827EF8CC16D387CA82AC039F77FE995BE6D9AEFC87F8D809E90C1017803BCFA1C737DAD5
+F1A631EBE6894AD20C70791665E7BC71F21C2C3F4462F60FDE75C8A377CF49BE99314663C6ECB538
+B1BF021B2F2174D2B22CF6FAD115EB0ECE8A2E64097A5FB0A2AF666E1EE13276AEC59FD0C9D4BFF2
+3F71E835984E5EEEE36490C54E077AD7355DBC98BDD37DF29B3DDF8C55480B7349C4D17322418705
+796A8C521FFF920DD11773FC44FC631C7D6E9B420D7965D7F62EC7385F2BE30A51E2D796483134F8
+40AEC71FA19ED1272C27F98F2CDC9C7E54DAB585AC1703ED08F5F9E825564902EFD08EDF99DFD494
+44C21FA6BE16CB8A1B6D0C8A5ABF80A50BB8D055483176FD0AA07EBAEAD88FD694F96FEBD60751E5
+C4D8F9BC747D4F4030BCDF9B0370B7A5E0A6923FF60DEA16EF47F886F10CCEE6956ECF41A21F7C59
+6F3BC78299A9657266807E01762B2B2878E551914CA312C2A68D34CD91E4F5115EA1FBE801346E14
+AE529049089B6B0273E258785773A9CE8E4B6C4211CB7C2767319576758F811CBAF3A3FFB41B3130
+6C49F3798B698A47BFA2E3CA0251C4D90C0B02ACA28C611744526906791D9E157E54CE4E1BCF5B68
+6990BA8AB7897D624EF00EAB92CBAC255AE9177DA9F0D86447D35B452CD2F337147B5D3EBBF2B952
+35778A72914EB3707EA78294B3A3BC4ACB19FE87C72AA1D982E4B822F07B115CADF4D3E7EE3D1BA7
+08653BEC6F0A352A0C33252ED0630E7274961896D461EE8BF523D5911BAC1C8AC763E5FB11FDD217
+4E1F129675969C195476C7A5E18A81BF9A11ED9F2336D5301E3BD32174ED5C933E8C85D6272EA218
+52A6F7E2AAB174E0965F73E0EF89E906BAFB181DBCF8B1F5AA0C12D12C6272753C016AFEC2EC9F95
+41B8757874D6F2E061ABBE8B29281677246305B3C41E90418426C575BAA216CEE3C5EC29B2FDEE1C
+77C14FDF940792F48A56AE80AA33E370B037CB28A7373F882022AF378F26B6006A049FD3B35074A8
+65C97D153352ACC156992C00DE26AD21C982C71F0EDCFEB61593BB40FA5F2CEBF23C4FF34A4F4BDB
+73CA273C269242D1C6117262B7C47771F2619FE5710855134A80FA8F92BB2425CF88940CA3450F81
+234ABF2B11775929B12CFF86442B2AA0F4243D324A5983E5D1829775B3C7A111D5622D1C4E2B2A2F
+982FC8A95F789881416DCB34950A393F4F1720D2212F3D343A17683060182355DE9E4718506D76C9
+184F8DAC55788D7E603CFAF4907DDE965A49C323DFF425FE88C09AA4A4D16283F9B14AB9EF1BB885
+A954034710B4A9DA4C88A8A0932B18D139A687303EE562EC9F656F12F3E8F27DAA9C75DB0FA946FD
+0E1A982BB58E040BFC0A49A4AD8CD668493FCB573C849EC5474049A693CBEBD4D79AC7515047CC34
+7A9A7570C90861F3ECFB57B9F53AB9C0D6B05C8C570A8F3C04D58555A45524C98FF091B8F8A422F2
+E0E9E5A7B7FF69F1CEFC13E42F1CA276BCD584516D266BA6838D5E9CA9E9854F50C7D92CAED61AAC
+AF758A7C7BE59C3BAA82BF32B691ACA3E8EB171E08AD22C39FBE586A54E6E4DE2CD86B31138546BB
+8DA5834B2C6E4838547A1B67E651964E43988C8036931088904BBB589CA901E7EBBC094C0DA81E09
+1915D9E46828AD8596FD0FCA39FF12A6C27A359337F973809E81B2E9E3D43B3146F2516667E607FF
+EB9AC80FC95A7B7D4DED551FEE0F3561C70DB2D69ABA96673E39E3397F1C3F8FE5F48BAB8AD6E0ED
+8901F90F6CFF24E80CB5DCAC498506C4D01033E497C1241E413B022227A3264DA68BC3F91B35781F
+A2D018475C199F43CBA7D3A0D5697B45321BAD2C394B207136E1E16B41794975E8903EF2B2E1C33F
+87CF72C325C11EC0B92FD3890ACDF60B521DA32596763BDFCDCA837ADC6F26F129B23CA32F9CD39B
+33E64576970DF3C05B8DCA4BFE2F17E6C5678B84D69494F1DBA9FE0446AE6AFEAA1FF245C07916C7
+B7569E6267C42B459435A1D116CEC665B311E404171774C0ACC8DDE96B0D9167C8CC7D99C4240559
+2D745C4428755500EB4719340D2FC6BC215B67823F69FA949C08B5EC985D7AA87C9AC1F9BCC8994C
+6CBCE6027B7D1E0C22A83A5DE61DBA05D4AF6884C95F46BA7F253E0B2337E312916E163CAF9DB2EC
+56C5425990FE73EE53E42B3BCCA1CF642F02B0C5ABD529B568E9ADFF865B9DC190240AD78AD226ED
+884BED3C285B4CB0E3929E805C67F1318D186504D92085764B70DE6AB5AB6990F181BDA50FC31262
+348D980EC76608CF08176C2502E065AC2D8EA5CF9E2D44E2B70A7DDC7B922047C471DF8A0B2087D1
+106B5BD8A830EC0E53223CE3C96EF56E5541191167860EEA58D696EC357EC55799438C90156BBF2B
+13A0D5C9EE93227746654ED73EA5B9CAB61DAC5BC690F89C87FECAF9AD03BD39E438F43B81D39E07
+E0422F94E8B096AB38C88BC2E1A043811D8141C1A35DD3A6DBE41620E83C8ED3A379CD80D4F9BC30
+41BB44B933DACA7C5D4427AE94A176829F24B5968B713431CB8BD9F53080832C6B784CEA9B515687
+F121983EB9D9C9CE8BD4FA3BEC48AFE64E643B7BD86D8383D07521FE5D091392BE124CCC91113604
+3824B686988E7C83AEBF406D2DA88FD952D0FA9327F4AD04C55FEDBFBFA76ECAE8A176C516479AE1
+467125B7EB3C9E7C5B103BC0C470946346DF271F8EE19DF7E3FF7478C35EE059297F4BF21A5C7B95
+993BE6202E897776952A7ED0613A5CACAFA731FFC633CAB62963150E86EDAC796026CE02EB235B9F
+7A54E0B0C5281567138A612BAFE409A818C216DA8EAC5EDF9D1E3A1E3514AE50735A111B4D2AA083
+4EC6C11E290D58FF340F82F0E079F1C7B3566F2336EAA45BF72BCF88569988DB5F65D4C1E59B50F3
+41E45A899656A0B522847ED567B49CD5284FE50E5F8652CDAC1C076804F2B2185F6A51ED19DD4941
+2E65A0D2DBC844B75E2DF71B009776D9F97A4C6F786EFFEB87A307FB6B912BB659DC2BCC6D509A9F
+BDE87DE8D716040A8551B6CCFB7743978AD992D14D2B85CA052E87326138DB196C24593F8F7ECD6F
+486F85D1666B9DE2ACA6C7900044EE369D223524664A2790B773F9EA26E0A4CDFD709942A44298B8
+249506EB9B77BC887DC0EF947DDDC7CB3CFC6B48F060DBF032A11884E6C226D9D447A5A458CBA325
+D57E144C6DC295262763E7BB8FF6A0CA473EB7661C12E0E8E23EA37E8AB3387B9E54686F3E57765D
+4067E521BC1AFAE52394227793C737C19208803F2F2DA920B553E2AAF94EB992AB17E31B58C15CC4
+AA8A1B444DF5B3E7CD937CF03E1F7FAC63342731B4589F16939D16E8E497A74CDE5686F529E9495E
+1603D74875288CF53271DB9313A4511B104F80B179FCF213558970A002E945281BF3AE51E668DD6D
+13D9E85152747F562CA0B75DDEC8FE9FE31F8D05B0F59E802888A7A4F19B29954A31108D2F041367
+DEBD6AA1CAD856BDD1427E9EFE89956FE28D500CDC6A0CB80A76902A08D0BC6705583243F1DD8020
+749B257EDF4803BCAA653F7FD6D8B91690995BA5EA3EE92FCD367C11601C6B8ADCEDCE67B16C596C
+5D200693AC5FA15D4CC6CE9DF7A71C8A925E99F5085313D60FAD25C1BBAAD28D4AC2B69062D68F39
+0530A976319A3904CEE44DC9451E441AAB4780425440F8C499B81460B5D3E268974145117ED843B1
+71BB14AA84C3A084A7D8E07B9979260675D5CE6534DC176DDB60DDE90F6A3674F67462EF78195F8D
+FF74FB5882B079DEE31FE92816F16CE1A70D07752EA25FAF5000ADF79BBE7D17EB1BD2F9BF6CDBB6
+F078CAF97986442680A8FC4121866F9CE86C385DE34E30D8B9768A0136D9EEF79A4B38EE99CBB9A4
+D32316564C9D56996E2595753EA71BEF684834FD030D38BB100E2332B026B046316A53270A96DAB2
+182E994E91262FB03D1AFFBAD623F1689228409884F91DBA153030870A7BEB2C7EE2DEC51875B137
+33B7929041F8D23A94904BD54DD4BC9B432DD0C78DD81639F46D686FFAD39AAFBD1B6C1A37E248CE
+48F23E12464D5379B4AED0D50B5A41577E6ECB75270E9AD3EA7D0FC09DAB271FB18B51DCFC0069F1
+5D72546E6C51049F3425AD005F88FD7F02042DABE9F097F9D6A076B30D8CD777B1EC12BD163FDABA
+5972EAA61E3C87E9AC007A052B1A3FFE14D7D43C7A0ADC89B1DD4CB4F9C762A84A6C0701494B2D8C
+4E4E1A9245738BE4111805C2F153A20ED9FECF2DCF4C8F7C3BAF84D60454A7403D4F5F81C6404173
+A7BA81BB0CEAECFD493D877465DC5735D43E3102CEC57B8A589182FC65A4704661A9E351FCCBC731
+5A87E62F65D24EEB9CEE979C6E10DBCF5C162ADB926EC8CC9BFFE381F6B8A3AC0A19D1631BEA2938
+731AFC99E8EAA39BC75DDB3A39D01AD8F0BC1838F4D674B9BEE9F6F7BE4D9C8BD97E8D171EFF330C
+15B76614A1FFD25B3BE19E4A201BCC850F926ED51616318C965AD2F0E56F9433B1247C6D5B72EDF3
+D408A3E0674A509BF30BE813A5E669D72B978794683CA8B85E3469EACB167C30F7666DB5E081B81E
+E99ECFBC1704B9646B1A29E4A4CE5654CA8409ADD60145DFC54225BDB8485E39CC98CBC3F38FD0A7
+97E5DFC2099452A2418C6636BD2D5F6B24345ACFA65F4E7DBD2D0AA0C1776A4920B4466C509BB5BC
+7D6627946C4DCB38A27098B7B5BEEDC2B3BA18F927077F71E38644597719652037621BB350BB5369
+DCCC073954026E6438FD8393DDB3630C4473F06D9FB9E422E435566C396B12FDCD5605DFEA232171
+CD8EF298786806E9159B84599C26D4C7D8C3BB064665CDD072E2083190372AA808B2268B3FEC8878
+B6420CA829BCF995DC20E067EE6B8E44D2869D51BA3AEDD1763F7F8D2CFB8EC41E6E9E0129DE5343
+1457960CC51D546B10B8B6CE08A1C2B79FBA448DF9783D815608A16C55E589DCD8EF6B04C66232F4
+7A473973A35618000D79B8173258B7365C9691DDFE47B16EEB08B28F881828B946FB5D6FE10ECC6A
+FC4EA1F762E90B3320403382E42AF4885B183AA48DB5E4DFC9A54E0B4FFBF7C26EB17A4F13B4BB93
+12234434FFF05549E7587BA0373ACB3E31418BFAF400D8938FC6466B94273D1735306AB912AAB13E
+31DA3541C1733E2A7E4DA5B82767D37F3084AA7A7C488CDCA7ABEF77D19E42B4448ABBD346E9BC28
+8ABC4540C0A1CFD0BF46C5BC7454B25E27E9906A3E6CBF678BFECAD1B19B4E42398A210CD567EC35
+FB115D5C0DF0EEECE593982056B0E1D14C292F70B3E049984F8881C8B477956AD3140B4AA22256DA
+AC0D11C4126808B5B9F922BCC5F24A77FF352E2C621A3941AC07A20E550A69C49B1B87D116EE6F2F
+970918F0F1A501166AC4423FC212E4EC8039AC7F9C212D864F418CBB92948FBD588228108FAC1AD1
+837070512305C110F0FC3FAFE6E1529C2BD0DDE868A9EBE5137DFDFC5C12A3D08014BF0EE27B1080
+02AAD6B607F5C5C0F1B1EED3C552919C9A2E97204A8127F97B1066607ECFB47BA95EF2B51F007C29
+3B2F6A63041A9C1120D9CFCD5357222E5B02DFC73CF94CF9B5CB00EAF073E9BF253E30E09B50341E
+57BF245A746EA31BFFD0B00201C34CF0881BBD1006BC9BA7D420A48E53686B598BEDB3449924EBA5
+8D5DB1B1B01AE2BA281D5758C99EFE38ADCE18F7B182FBD0D0622A6EA497A4E7C00C7D17299A2765
+EFD8DE376C214D01A21819451FC04A0277EC84A151FF93903D61C78AB7886911E36E12526ED855AB
+43F6289C1890222602B8EFBF15782B374AC1E580B6E963403D6D15A051DB8558F2E61C0B9476C6DE
+5D4861585CF515CE951732F20D32969F39192FBF1690D242AC04D47E0C53D467D0FE4656B9526C0F
+7F852348B0437737CB0F29ECF9B54A5E17185236DD0C16349C3496F3ABA569EA20E343F6D771210C
+39DC932DC65ECEF94575C6E76902CDF6C8C8361F9C757A2577DA535187FD526699917CFE0AD438C2
+A758727B306BC7979547E68B94E87ED820614BDBC649D469EF6B4E4E3DD2EAEB5F80B22FE576CED2
+56495467C76A75F589460061E03F3A1B065121A5ABE3E2C51148B3DDC9F624C97889AAF7FB84B158
+C015EDA5670746C6359D27B0C2BD65144F2B88A64331816DA904572BE398E015A9924218B3EEF951
+23AABFC3AC8217B7B4F691219A1C9DD0A3EDD5C04E63ACBDE71B423522532561F4B71B7028415C34
+37E346BE728A415596AB749015C1D59BD8328E39A850CB98085B34B57FB52DD1D154F98FEC49B3AE
+BFCB1672762E4D2A1ECF02787F59DF1EBF2625C3631BED849B298C6D226BE4E6EA2AB66A287D2BA9
+2A6C9C612A5F849B3CB3C25F17164BE286F6E4F5E7E4C9EB17BC68AA5EF0190B64696A570442E1D9
+BDD1A30E7692524E30E4B4C3DF84481DCEC6E10E7308E65DE9D90099F3FABB3F4F766BB86CC98594
+6D2003E21287761A7386CD8461615B570BDA015F5EFA23D18E83C325EE444EC166A1A32D9818C2A6
+5A092D44156C06D3FD079B92450B8A491CBB3529DDAC7D95AFE8EAF33777FBB265FEB8A4B9AFF2CE
+CEFFF49AFBDCF6C4197497D3B448866D70EF28D8E4B17E7CE95F43F64BB48C4A73EB84B26650F62D
+3E5199D64DB0B5B87702650ED0B850FD5D16C848D096E4C7E61BC63B2A3ECFC099CD713E12C91A65
+77A88D6F55D348617C7A49890A86EA8FE2045704B5ED529DB128C9B19EE129E5FE6498CC97087F6B
+DE96007C9D01CE9CAF75646E5A5B32BFEAD9362A52223D746943A2D09C536CFAF78E601BC2D2F0B7
+63AD722E3A7AE7069D65F9F2BDED7278511D0120F5EA071D41A69F8C2A2D720D3B24B4BE61C83FFB
+EFFAE21B0560A6FD1A44E53E42E0D10E0E93F421A8A7E167BB65F0D7F1DDE2809FA3CDFD931CCC69
+B119C83238C1C00EC100D8E7AB1C7FB02EDE97073C8A5860371A8132BE391EB1C397B61F93876FEB
+438C288EF2E38DDCD182A5CFBBA994A94A1BF818312CD8234215FCCD7C240A15AC01A885E1179E5D
+7D6305DC2F534BAA141F25EA6A5F356486E5FA0AE3C6980A9F5E8E99E7AE5B95AC42977510970245
+4FC951E4319AE4B1DDC9B07D0998372C0A95ABA6985A4DBE6DC633154FAA30ACE689D36A7F17011B
+F29CEDC58A6692A8B3B0A5742E6CEC2F69B255BCEDA762DEE72F125EBA98891CFF4D88AAC14188A1
+8D81424979C9079E44890D94EE094D4CADDC1C7AC5F6791FAB8849CC0240A579ABD800EFE3AA4EE2
+F78119A3C2806C05C2B1F17940BE73984982D1C0065433A9BD658EA31AC819DA9A11B87475BB565C
+C294B6F302FE3F7752ED9B963C5279B5F1196762D0E12E6DA46FF9A0CADE3876D7DF695D8965CB4B
+47B351FA3F759811269376B2C3134403633FDE27C9B024F6BA81F3E1699CF64A426618428BA6C326
+6BF016C5DAA5FA4CC82FB6DC23FF2D742160518CD3A65ADB38E53F1067076CA1625466E0C64670A1
+564A54CE14DC5C57D24A12283FBCBFFD0FD594AC2A56EE58B552F7586825E4FB1EC23F8221711692
+C8C56F42272B87EBFF3865191F1C11943BB76D8C0CFC53ED452AE49404D2C8193ECC2A7BB8CFBF24
+870ABA38D2CCF7869E9363DC0AD94FACAED5922B324DC3B6FE83E7B34FE29ABC1EAD62B49FFBCB81
+1ADBB5148D5AC2743E3A058386036FADAB6FF071BC1C3B8023F908B6FF48DB0AB1C9C67487C35211
+D40995E1892C8B66AD6C9C6203F6F8B513B11117B10DA8725AB45B4437B5A88A96AF3178D856D601
+196E8162868A83DA64E408FDDEBD14D6591881EA652032CF2F88B3FD6C0479C8F89AC68D14D01AF0
+CEAFD95AD146E68FAE01A07F39E7A0C5E4FFA6D6A91D710827CA5ACFE7D1F946A8D7B67621D60F53
+41F32C12A6EFB03AE5AC5373A382C044A276F6B41C173D0AAAAE0C1DE4C3CC71EC2637225CCBFBD4
+5EAB92BF39357C57195B410F74283585B12B926438AC72AFADAAD2D0FA2CCA728C8E86BD3FE75D47
+B8BEB96AB13B5480F7A3D5741EB51E3E40C21FF2ED7D9221D9877C7D1A8CECF394E4023FCF8C4EFD
+B38B839499FF5CD96A46AB4FDB46F35D3B48B91757C0159328120E93CF1F2739E936E28908FB1947
+1D3AD7F6F1AD2BD1EC364986A411CC1B547D0CA104FBC10B1CA7B638A60E75485574034561DB345D
+DA68415146AAC632DFA34769B6ED7D7D4694E92CBFF4EFB16B55495908102E85E827FC623CF1BBE6
+A13CBF64E878E1A2A159948B5529B75E071744A5F0E50DF18C110B0AF117CE7F33F8C959D4C98CED
+5A9D492AE6F56DA57B0F17495DACB130660BCEFB064FD8309D965ABE8D2BE98F6898C1B7A39CBBE3
+E75DA0FFEF6CC3945CE76DA3BE915546FE8A5310130AE0ACAA9AB73C7E041C00533B4BC7724657AA
+649B9388B791AAC5EABFCDDDEA2CC67A0FD0AE9BE37DF9AD40636538EE55A83F60E9E026C64FBD8B
+220CEB46E67410144A520FCEACA252E8165448F84D8EA083C793AD09B90B3EE83B73FEFC3365C729
+E3C738894B8C01C2F8AEE0CC8B114E1175EFB44CC4C6CEF5C8754B1CC7CEC200AD8BF1189D741CB7
+5BCA4E88BE959E32216AD33F674F49AB20A354CF3969F1611A95D3934E148831AE7C81A7EBE3C524
+4F743E66A82E10D16CC09F8194EA7A596BC5981D833318AB4F7DBF2ABCE543E410B649D18D146F01
+486159683DF61A3F880F9B21EBFAB77E908C6CFC79F89BA5F51114F0BF7C3CCEC7BF0F3B057C3195
+CFBA6908E31E0DF10DF69163C9DA7BABC00E9A580FA7FAC202910615BD479BBF76FB8068630D1EC2
+1CD2926D351E869E16C2CF1E023CF04D4FC61607DAEFEEEDFF5593E6023492F00029E2AE4B4A2C14
+50954EFA2792F32B4934A768F892171245A1E2F034E2B9F39833F1B331A19A386BAACFEC8C929BA6
+B67CD8922BBC9DC005EC3976575D5B0508D0717C6BF11123EA36D8FD37FA77A6F1F5AA84D4AD8D25
+B2C11D1877A6E2F9B74F3B5829FAEFD4F7209CE9785AA6FDE68672554A6F29D8BF03FE108ED90A7F
+58690FAC399A8AD3A26899072B832874DDB629581A51B3325CD9EDFD49E890EA8959DB937DAB83C7
+77F2A426B967AF5888C33A3635B78D647AD6BA441E222C958EA58D61945F781D7EF409771B89B202
+42AD7D07C2EF592CBF413C5FC89EC30FC9EBEE4BC63709AE33B65EE3091CECBE610B847E12C556A2
+79C8B114C3E460822D3330ADFD72BD69F54C08A81848C2002A08326CF3B09B1305490D35AEE59179
+08E1604ECE75BBE811A715AE8AF7EA9C371B322D0428EDF4C893FDEA607E70E1B6F6614947326101
+EAEF18E29BE0557D2A92CF1FC1505E8B434BC368CE07CCAABC0774F8A63E1073FBBCEB3F4052462A
+A9008A1E53F188C9EAE339FABA74AFD6D60F47282CD9FF721F64BD51787F3C13B5A6C5A5F7861171
+0111F5E0471E206D72520F1DFA465F4A23C71DCF99A04CEEF11B0E3BDFC35B7461A60753D3AC26DC
+50A5956C9195A4F5226388E0953DDD03AF128A98F03BDFA0602CBBAA20AB9ECCDF7255962A332E16
+D4380762E498FDA4885C64FF5F9B480DA487C58E78943DF62616E6E2C69EEC8836DFCFA9EBF58938
+A878F3E792E8BD8C5D6DF557A5D82018DBAE1CA9C64BA5AF8E21BE1B6680FC5DB22422220B776E9B
+A0BF1ED2B7212F8BF111EC8C8C77B223C05EB5E5F1CFABD2D037F4BA0F9503E2CD83F4519D180476
+63F09E308883F5DA5228F83045FF41214D2273B2FE0A9017D5E0557BC2A198C35D1E7E81F7965444
+5760CBA1D3F05EA4B90658E53FDF0823BDB1501ED51DA75C47395073D8980D1E3504E3F67DB3259E
+4EE73A87CFD96F84E221796573958D364A51E635FC55478C9CBF9AEA16B7D8C25F2115CFE4B7F598
+54E24968833BA0D64D1D332A666DFA2A3FD71B05A26BAB7DA382907B13DE0B80871DF184D3622B62
+3D7E09BC32A4F6EA2E6DA450A906EAD36D53FDEC7F83E101FEF32F4FAEC581B000686D86A0D3861C
+1E67F18A4C4647F51F978484D9E3100B37BE9D20AE84C085461C1FBF929C669E936659050C2627AC
+1B019837BAA75757F5B0A82E8AE9CF2111931A38BFC94744E2FDE3F8710342AC615286E4ACE7F269
+743AA05463AF537D9416230ECCA859D8C99B7C6E70BE7FE11DB698589BE9E11900C8E9582A4EF5EA
+94B5F62820C90DBC022A620EC536E06CB8BE7526A789996D0E741AAD980880A33800A6FE92286CCD
+02C9CB407EB31FB95D9C9F4AFF38B37087AC582C1F7B64A7C3D2202BDD62E9AEB31BCA85C4CF323F
+03DA9D318B91F78FDC0D266630F7444ED068B55C05461C97552366A82C2E743CEC353D51028FDCF5
+403B3B74D379B82EB69C4380ED40239E15A86B2E5C860891E26781CC111FB5705E3B7C7AF1946006
+54B5FA1B5FC54FD0BA43666E7BABD2C91C859F393ED49F7123EDFB648A3D6152F2C17F7E438C0A63
+8968AC06B4FB3F77F64F358AE063820BD33F0213C85C40E4D97ED100EC2DA1C2E1EA258BF107AF67
+5A9D995F60BFA37222B9C2B325C0052BB8537D2B27DD43A129C7E8FF42757B3AC9B447703D382108
+DA520B8B3BB3E8C7295B776B44ED28F863B8E1F81B0BD1DAEE8A171525D09D2620C04DD3219D880C
+2ECC79282DD7B1772A9CBBCA706909AE8BC7798E6EC7375189B6CFCE8A875849176E5913B85A18FB
+197A33CA4B5B4058603CF1FA79A56856B43D538E9ECE117D99AFA73B57E307364F553644DE01EDB4
+6234EFAC13046B6E047ECC8F63942F20097AD7ACF0A45C0501A95263DE9439A880D6B5C5214D2918
+0A54D7FE9B2E627EF49E189B59FCC78745E878E45B46C0A648955D3EA8C935113D94F92EC963F66C
+F3CF3A526BA71CDF3CD4CA69EFAB08B7389E3390716892A4872BD29DC1E0889A42D7FFB4190E9A8D
+05D84EB9C5741BE6B02716BC75E0106F5F94BD3778BE985E03860D27E44088C3CB2A059DEBC420DC
+E3A8F4087A9548485E616C409AC400DD1C411CE4B6A229D091B253EB68F06E43511EC5AA6ECA4D6E
+4818D6AA2068DA1AEFCA377611BFA816B5215182432D5683294D67A7C1FD76C52233087CA44943EC
+7280005E93145F5E7AE50100C18364E1B36741E9647C4DC1F68A58EC44095920FDCF05532F603717
+80F78420077EF5C24D63E26040CDDFF8DFD65D871DB943F50CDE84900C1372EF33FD8AB9889C82F9
+4F61A0E6842219A0F39EC7B232CBF802C4A744F33159432E827006C7CA77E480A48A9B0E6A876158
+8A3102E3F98A77BBD62A3A23150FD140D3941773BF7CBBA2338FF37B9EB640558A2313E8824E8E62
+0331568A9B76F4897198A709F9313F4AC40827D8C3A71F2ABFF02BFD57D30D0B14012FB5C39B85AF
+540DDA0ADC27A85B31694E8D7B61F9D9B476571022D98F2D768246550A877293F3FF6ED918A498D6
+A600223E1A61890C49ACFB60265867CE9464F9C32C59E94F7641C3873FB4FA6EB237F8ED94579957
+270D6FD640BD9543E683F2372CCD7B60AAD269E03A72C5CDB732B128818D41A6DDD2BC139F7D3911
+F48E1B1D263DD4AE8E4CE1A686F3A00A2CBF48978631CD243566E22E68F8D7397134A3530EA3745E
+4F1EACB4D6A5FD84C3011094F37573F7F9902305020C53926716D4780C6B0A257BF711AD94C83F1D
+41A02C1C7DD203A3E6E4B14EDA2FDBB36B063A3E074495F626B0EEA146D22AC33457F44F41675967
+6D2A0566EC2B726D2F0540ABF225339F02F406D4E7A62E5233DDF20AE7C86CA0CDD561F33C422654
+BF2DC3685CA91BB9D4B09AC8B15A24A99FF56E2894F11F7BB4728FE8F0F5B799F74F475D2D01F61B
+7E9E0E541F7FEB8A557486D7DF2CE50927515D833BCAA1CD9BF7A650BEE9E003A5951C98ED147C4C
+52F64F692AB281984EE65A47E44A4A5FA93D6F18D276D3B01C5E5F6135AC6940524CD713DF4077FB
+4943E8AC927A68489EA52ACF7A854393CD027EB52EA2DC6234EF034F3DC742D6DB5A67FC21D22B97
+146B9C268BA97C30161CE01EDC69A6A1F05EFB0E06F22644E1A368F0E2C0C6C1C832878E0614B74B
+D645F5CB293CFDB7618B837FFF14A1210AA061C8C81867244305B80DAA73CB25A417228E9559E7BD
+52C119B0CCDB7C4DCE7E1B9F7E8EBBCB575E5BD213BDD6DB88769DACB05E5870232F0EF82F448559
+187423409EEF756BA6247493BE24CB1879B5DD822E03D0ADEA1EDBDD83D3FC46759C679B921F0616
+F27212903F728AB44C1784E8A7DCED0DF5625A7D3F48A20FCA34008184CECD145CCD98E31B79E174
+CF107E8F35C40C19D86B40BAEE6164353408801EDF75A619FFC5B6FAF3F3A95F64795CC40C1F8963
+4FD8C13852D265FBCEF834C800AB46E3E8167476B23CDD8AFF6E2F997C99A86A9CB30EF8C853154D
+0D89EEE9B9CDC1B4F27BDA32432A4173B55CA8D9FB50ACB2D886AD8E5862FFD5DFF224BA13C8B8A5
+4A7F1A9F987FBBDBC5A3C3D762A5BE309D5D926AE5093C40AA47B3B1BD828797CBB9BC9FEC9D19EE
+A73D2A39764816113A8EDC6CFA6E605AD578FC8E30ABD600658A49ABCD5AC54655D29C50FDB72070
+169D1B389F114B7C71EF95A80D82AB537AC8C165D47371FC142A51625029A990A577EB1618480D72
+6DA93C98E5C5F24F622A850CDD94BADAEA91D4BC32CD50CE69E9F00E77DEA8EC1D37916398FB7092
+402605359DF08AFE7B99C76C2A7C70383F28A7C000C696F45291BB8F074791798197CAFF1544C76C
+EEA8C9E6D76EDCBD92A86DF889481F3BBFF0865442264F0EA40D3CAA69AE467A08003F9C30FF7F2B
+77E767580575398462D5B1171DD441D8986F33BC7BDA17D413EBB6B7A32642E33F20B284BF3EDED0
+02352FC66C6F7741A542155F4A159CD778BE56B9492CD95115C1A06189A216CFD2E6725965A13DE9
+73765A05114D9A5A4BE0615AF8BF6A5EAFF84468B849954D15BEAE1CDD57C435788B331905C01421
+B50F20B184506A0BEF746330BC98E9C89AAA8F9D102F158043BEB6A682059A1C8B8CF67B2F3D7AF4
+D8BBE086254CDE53765E3226BA2F95AE8063649F9F94BD9519411DAF8A0287307335668190638806
+E29484A4FFBC1E46B1800E03B162C23B1DC0B4C0DD3C7ABED2F00762972EF06EEB9BCDC7B3F39C70
+BE32789D366F073AC3280C273DFF2979507671B3E1E7685A9A4F0FD3867F96DD675BF05F25ED986A
+79249B75F182FD73CDA2A6A66D693E4CC5AFE3402431B2C816DA1486C34BC9DCA4E2D51C868688A7
+787CD10ABB9ACA14B7181369DE89913CD8FAB58FC84519EA2AA14E54B7A8CE474F213E07CF2DE2E8
+88093DEEC937526816B71C96ED75FA9E2EDC0F9E6E84569C12BB8E39AAEDBF546630745553D6084F
+F9524FEC6A7264F88CEB7EC3358E923B392474E3A48865564431662988FEA768CE555AB0DA48BD52
+6A84B0CB17B4584066C1640C1023D91F7869EF0C4D701BE121A6E3C832010427490758AED7A2B30D
+6028F2215AA44E86D852FDC67DA5CCBA79EEA863BAC9EDC2535B66AB0E54EC4D4411390FDEB8D1FB
+C1743F15C3B68DC92A8659E7A892D5E53872EA51EE8CA7EF51103E87C29A2714E907C79DB9CF3744
+1785D2F73A1EE58550111A4D9BCCBEBF2E39CD3B93DCA300FAC3ED1ADD8215301E5766C30C8CF296
+75746C5A77BF1FE3CD75D25CF193DE8D9AF02AF8F7A6E8F84B548058CDD3C6998ED13463FADE7391
+26D83D3CE2C7201F955382832E32C10DCBCCA35835985B9A93F8E3B0208BE6E92428787C47D3808A
+0F77B8F1D76E6BF6A17FF81CDB065180E03809D03638307BD7BF5CEDBF64904E918FC805AC905379
+928B816480F6E3BDEE47042CBA98539DA0E113B1A5F23EAF1A3210BD18561985E6436EAB90395DA4
+77C7A6D7888D2377B3FC4169368357D880CE041E1F7C875E956600DB7D9B35D1EE66BE476E9DD806
+4CC02230276829C2C0A098F051502E828A0CC505AFD8C3DF293DA1508AC4D25866BEEE6BBD5A230E
+9C2DCDD4F06883936381F476DDCD86CCFE15C2CE3C3243E148CBE603B8513A7CE7A6910A66A90B70
+89E5CCD4368BEFFF2BCF8E918BFE0A1B069AB2A914CA7BB91A0AC3B3C0B060FA1A0316F6135E890E
+E549315897C8464496CC6DEA0F7E3AF43FFA4C3281156067582CA255B1D2E80F999A3AC0402BBD17
+01824C3BB524130F5B82A45275807BC2F3A0655EA208F968B297F98C369192C8ACA26BEBA7DC4506
+FBD1305E2EFA4DBE5375281A88EE2D6FC88FC0A755E72934B4B58F6DD3BDAF7171A4A3C776576735
+2492BFA9A7758504750AB7F38754683B70E9E293CB1CD7B23BA62BD7397ABB84D7EDB22EF6C3F58B
+3EEAF656E361747ED04020163253D1CF3F905B5E85F83FFF30AB2778CAE43781667C0F65C8FD404D
+6B9202A99EA76AF9AE1236631550B66B063847180B6DCA832EA8DC4A6EFDB674B5A26552A7C7D54C
+2799C7D4E03C24F661A91103086DE3A90A774A6988347656344CFBA06065AB22476BB09FB68F9928
+C0045F2764AF643CFEF0516D87FDE6DBF93BAE2829B176CB507BB99835E01BAD5E55C2F8798C93FA
+35EB3FEF02CFA31D3D21B030547F86D27B9448D68E2B155A65C742BD2999DAA0C3AED64447B9CC67
+F7AF33B63AFAF25F3CF7EF86657FE8F952288CA4B691D369E8F1935CDA44A180A6767560C2ED3F2F
+CC38B6BD7991D4170C7C566D690A8A25BE03212A80871108D18CCEFF246623E653107631F29227D6
+4754B2208D19F84E547799E691CA473780DDD56AE620CD953D5133D135E3D51F237078FEEBB73714
+54EE633CFE238AEA63F9999E32850E6C197687A0EC4E5908D2A18C5349627E336AB5E3185B218228
+603A4B1852069F5EE849D571B8387DCE1F8F8E9FE94FADEF128BA83BDD245F8C1C27C11F2ED1A8AB
+2D6D601726842CEE744EE7AAC6B6FA16CCAA39DBF5B3B1D47339F31DFA562671A9CF7DDE6915FEF9
+F19B3E068A464DD350A3AD146D1A241673B5112A4A8768F976723E6E184790C0604506C46591BEF2
+106C40789B733331A80740D59ABED39868F80BECC2AA21C400A0BD0CC326D186FFF9EB37680F1EDC
+32AC78F9059280D07B5FF2E354FED545129FA5FA8F3D4317FF21E027602FDB2522F049BB545FF4DA
+60248130F81F4E348373142F3148DED038AFBA818F26D5B49FC02DE9800D894E9239C88EE0EDE431
+F8083697CB0BE3B497473473E5714717C914A1A926730C249413FEA2615EF72BDB0906933387A892
+370F77EEBF62D26CD583EE643B02E323821379C0DC966407D36AE3CDF646B95DEDC7D7FD0F28E950
+78F12DFC0D6400B327B743C548A0A3517A175A7ED963ED756B1E107AE7087E2446BA702CD4E26E2D
+CDC1A8B697108B5B5E81E9F03105F220C72D4AEBC57665887C8C7964089FBE9424120EFDB14D76EE
+F8C6F7A30B13E1AE90CB9D93D2E14BDE47F4A1D05ED5B18D32AA39911B92D24C93976ACEB7EF597A
+75161923A73B2CC761785493D0EEDC08B5AFE95F3C006B41438A0785C962B070DE2BD096CB63B847
+C87539880AA3D3FC5C345E0992D7BE77C6CFF4948617FDDA784CC55652192B0ED775129C4EA4245A
+41BCF3875BE319DA0EE2DAFEFAE920CD2B6C6C2001762F88C0C5C05053025C0349DB17104360FCE1
+5D7F3A8E30ED13155A74FAF91DC77B8AABDD6FBD5A1EAF255DB209D7F2B90822296B5603FB5E2CC9
+5CBC5F7A6044058B8044ADCE73ACFD896177F1F70EAD2F6534DC3AD755AB2BA87126D63CA2E9C441
+DF0965BDDD6BE494E58D6B5057A561D1E31BD38E92CB73C1465AF6B9C001F7229059BCA4104847D1
+639E124E082F7364B56548BF8112D0EB461B316B2449049F6A476D36D6B7C0C1126C08F2E9A1246A
+3B5B21E7C8FAC6E23B82E33A7783E4F31F0240E96E69C9444E7D7A928636CFD086475DF1E0A28464
+81387BB2010655B9F81A0744121699B4905AAEDCC84BC5D5AB3674601DBBB651EDE7B5DF05C8A463
+DAB41F79706D285C4F9063997F7AC8CEF35CAD51FBE5F5BB1B3FA6DA2C3ABF2B3E925581349728D6
+DA0D59C1EF6444539742EE9A23A5727F20CF9377F4F84DEA420607015A30FB14632D084A2DD181BB
+02FC3A84FC499B318156B675B9CA3CCABD87FDB2497C6705FA70EBA43ADDB6CF961B30E8F6AB9F84
+E1DD8D6DB3314B34B7F7AA3BBE19D5BDC75ECADFD8EAE19E07B387A1FC586F0F30DB695926764B54
+0D89F1D854B0FF86528AD9523CAF56371E29498C11AFB2F4D5202670C834E930103F039D13348824
+16A49BF93B84FD3CF1209EEF7D4994C8302436C0794497461C11F5B8BA152BACBCC08AF8A15F4A4D
+F3EFFB7227CA97FC21D2D0356C93390C749CBE9750B821F1A7BCFAE2C8BC6D9A27F844D8AD088320
+79ABF0EAD8ECD4EA72846DFEED021857F33C1ACE4C07BEC90398B629814C498D33BEB375B9A53DA0
+F926FE6E89E70322C72CB2DDBFB16B13EF7A4F50DF783316584C6AC2BD7D9029124933133B2229BF
+74A228868AB30EA5C3E87C78C3F0962199480DBCADBEF53BDDE45849DA857A4FD85B96682F1EDEB8
+5384929DEE4AFAF84C51A09F5D572705673D885070303FDB47DC898F874E103A9E7C1E894115DFDD
+AD81549C7375D4AEDCCE2E52C13E5130B47F206F7C5AFAF1F9EE83DA8188D70B473269CA280A6A02
+DE85300B93D8A4F6B402FB5DF58F1327470CE11CC63ECEF2EFAA396A6680A6746A20382D9529B58E
+7CE684B39AC00F7086BCB47C2230DF0343BED9B9152A61C9826AEF9E00A1452D91305CF05490D4BC
+0BADC9C6FCBFA93FAD52C3A80705A1956890497557C0873EBDCF61CCDD2219354A4F5621AB33B119
+32065C1D990A9B68858331EE7875CAC855F98563B14EF9E1060BEA90F195AFFF94728AE935453438
+DAB35123D0E2699475884DDAFC7307A5CC06920F35341728D85965F5BA86F261CFFCB1E29B429F97
+6970D42D10E6AF6C4B792B4384122AEF2448E22A58D3AA007743C71324EA08D06819FED14AC1F22A
+4F0BE4787BC8738E1CEF240677571C65804ED3E748D72E89C94B6F310BE748FAEA31EE246859CAF7
+A1EA17CCB5B246C87EAB771E2AC5D378650191081514DDC2C66878E3766CB20DC49F630F2743A7FA
+ECBE9DBE9E815A3CB57DADF2BFF5EF2FCE23A56298A30A2E052FEAEFBD698101F9DB992613706693
+CB0EFAF6F60C8BB5E7D0A50B3392B9831EF3A304A846CD4AF431E9F018FCD3A5B16387552D55DAEA
+683D36257418AAA0E7BF8A03ED7BAB114D7C15119E6C71C1946BD7903C1C42E115E954619051B853
+BF05AE316E15E619A7DEE498F771E809D9435969C1056402725EF40C0200E083F3EC6E0EC27B8ED3
+8DFE32EA0E5E156AC36C4BB9AC5ED111A11678339703F1B9299345AEB1F251FCEFA11FB3101CC499
+907DC862B4463D5523B9B25C5B69F70AB6B29CFC1DF1ECAB8227EB3ED1F882E90B12080EE003714D
+403EC43B7B54491446B6A3DD6EB641EFBFEF060C45E873E7398025B1CB7065441F1753028F6F8C49
+A96801C0D598E098EADC96A21117F817B6FD6E6947642F93E22425A00E8F6B592AD50B317B69C0F9
+4047386A45E5EBC9504FE55451A01EB29DDF9A41D4BAD85FC84CE280971E834F06CEF49C8C20ED2C
+EAC889F158CB14A8C070900478804CFF1D1637CC880C81AA287D8382837FFA8F41FF3C9DF2F22CB2
+0044C171E4815D0D0F6C22D19A52114E780CECD71DAF63427782E85E463DCB333789F496340E8CFF
+885A9D9A4250118B439C71C6BE51A9338BE29251AA794EDC67DEEC6337FA63CA9B03C1C9F75E733A
+4A918646E7BC9792486CB5A4BCC5F84FBABDFE338C3792254A3EEA3D88903C2C47B91E076259DCCC
+8BD3DCA90ECCC832C09C45141C6242026BFE309029A562C3EE0FCCDCD40E5CF265ED9C3DE582884E
+0E14819DB98B3AF734B1B3276AC41D43384EBE73003D15CE39FFCC04109583390E470F431B4407F9
+8550E138F96C4564B494E5480F47C853BDD237E27301F55E42A3BED18FADA152572B7B465A581DBF
+E7DB2619365CF16D71BF8F091862B9FCF04BF8D0859A76F46E7B5712F2757EDCE332D3213B8A30AC
+2CE7D7797EEF6F30904906B0805DFA7CA36D32A20D989858497A66CE72491393DD79332003D55C09
+5A5AB5DF761C4BE5C041FA8407263D604E53091F7B6B15496245DBBEE96A63F10FC2978D99E65731
+28689366FE8B0BADA48B50185B861BAD03E3600F22BAD4274F2542B635F6C7944BEFC3BC741BDEF1
+1A8DD659038CB40FEF2E16AD1AE7EBEDB7D9BA15FDCF26355331505A386DD7399FB999535D6061EA
+BC61DD76EF3EB457446F29D0BB6EC2FC0AABAC20B27A3C123C27BC27A76336D0A0A6D456DA070367
+4D959A4AFE428E2206A511BFC80039ECD56E75F69786DA0A8084D81A66644DD98B6018681F1D70AD
+E09BD9BF3D16D68DD5D0A03AE26DCF1552549E459FE190B310A8776B2C8468C14CA8B1B9A7AF2956
+507A3B705AD75A17A0EEA7FE089273353CECD07BB8563465EC8DECA0EB42F43FE3664EB5F31E1D13
+24185539B28D508BCD065ED576D8814ED3FD637D576F027927162344AFB0255A91FFC616948E4E35
+8867E9FC76A9AFFACAEBFFE110808C1532A2BBB0DBEF3F010E45FFC73F228D28F12E98478B27397D
+8F456781ED9E19711DF2E9EECBC3FE61F7493FDF1A59124668A91BE51F122F93DCA4BBD22DEEA339
+E6EDA3D6EBEE03DF958113E1CA49C8398D2C59DA6764882EE3663F62A55AE50A7E91B4FEAD1B11FE
+0D50ACCC5D75F1A515F0C53616A500F1491381DFD0E2477E402AB0CF9F67D501A442629C8593ED5D
+25A72EDB9746B02F2B0F0759CC9CDCB4C9D8B4519C8C617E569B432F0CF6890372AA879CA7DE46E1
+10D95E230A4F0E52CF65811C54365DF4A3E40D819E2FD379B47DA3233D0DEF0EFBCE04AD8BAA3888
+4F6A69FE5C373E38AE0FD0241480F2BE7CCD18AF85916D2703A049779FE7398FC47D348454CF03F2
+2EB3FECC064606957898B5643464845445C25C0C7D685C8DB042AF5D5882174374ACE90081C68678
+9BCA96AC602EB41D317BD652293EE628951875641661EC86A2C40A42E8F0813A861D41A0F5178E55
+43651CA0E99150462DB5EE0010F00DE6D55B0D7FD7EC5BAEA24ED3E90A7D6A0589761922B91A6A91
+3A7FEDDD3B68254D89ECF767CE8E27F966426A8B4FB1B4085384FD09D63E288405B78A646F44C87E
+EE22C8596B13188085479F75F63D3D97A28F9C8306FD207DBFD38DEDF0FFEB7DD80B2A3292DFBF1E
+D605ADF1B33E85B010309E3EC058FCD922B1325FEE71EFF2DBBC2E68DB52D513E024C01D47CF657B
+B61C9734649A4AB63C0AF4720EC3EFCD82DD3CA6E80BB63BCF1B8DE810A0C6C517C63B76FE68C0B2
+86867BE102424FC31C4937048B6F323D039618586FC21731005D949E7D802A430DF8D2F0CE99F2A2
+376C2953EFC4184355E4D12F422C9E1E25C4DF38DEA334DBC89B540E14C61A7769D77115CE8968FB
+76B27D0863CEA2496783114C24D4CC816DA884D953DA3F9B9D3AF8938BC607BF26A071956CA07E6A
+5509EA2F5D80E5CBEB98041B197FAC760976EE75B470DC20AA023BA3F63C2876EB281FF5173BB490
+D6815604517AA1B1FA0631401B3C1A04CA103E2CA4ECCD83874D9CFC8ABC134CC0F9141D9AFA5684
+8BF222342016C556C14B3482482DCE5D0B6EF1AB522AA1812BDD8DD3397E05327EC12748FC480842
+9B97202E24E1DE0C7C0D272C046BA73B37D30930C5DE5A47D96955CB0F5DED8F3AD929A8B42D2839
+0458F5910A0F93610F79EDDB27078943DFE17C716D65F96589769349F3B66AB7B8C004CCC59EF688
+1F745EC7129865A76F9C2D029D4660CCFB4D5F9D412BA3372A27CB175E9D65F759575CF14A5899A8
+D31FF039AC02DBD8391C3397428AC0D5717C005200790785354813C8859BE90E0E17914F6CB9C674
+F1E9A9648657B54E5E1F52756C4F982DF74E73F6E4D40718C71D1D0E2420FB7462FEC9E457C0414A
+96E475C6BE2C10437096FCA0C942E995A9ADA789AB637B648781D32DFB68E62E91C2CE7E13680F8D
+31ECF8C824885FA7618981CD05FB335AA111B409C59EE337DF4E5F9DCC920A5FC0D620DC07F20DAD
+63F4FF5E0EE5A2F390AF1C32122BA7780F210229E5A5E3ED97BC1C3CDDDD456E739CA782EDBF4B81
+0552368E9C734B0C78B0B8E3F8B2DD782862B74318871BB1EF087828CC173D7B049811FCF598B8EF
+DE4D9BC5447F4848C98029C854F3AE461B9D46DDAD8CE67A521F3C811A81A396CB0F80F3C8D8EC88
+30532FB7F9624F7CAE0F8C6DF875073333DEB28AAA90AAF486AB8C932553CE697B885E71EC8E40C7
+835CD5D59A2C695DB9E51216FF9B77A15B0DA63717FF25B05B939E45CF7FBE490E51E9344213B32E
+115C2DE14D76DFD5845088DE645B0E75042A61D82FB1753C445AD0A956A1263E5A096B681D3BC51A
+9FF32EBAFFF7ECA8B59D40F0937EEFF38312AE57462C7BF3B1FE24D2BA8DFE84515270E09063CE3C
+80DF4935E409F62EB4F54AF16A186D4329972B9BDF15FB08461B688ED49928429226CAD9F67C9D63
+6D1375CBB7B08A5631956B7FE29CC9EFA8D75C9E4919C8C2C54F401D2E0D7BFBA40C50CAE214D210
+C6F3EA5802339F63FC4C1C1995787617F3EC2C806CE44CF8E29F76606CD5836F6E5A2E423CD791BE
+CD3F112F25657DFED9366FC4ADF90B685CCE4A5698E5FE16D7542B913FBC01B288DD13F43DB2B1ED
+8CCB80159DBDC90A8132125DF8DF547C4851CA609D1F6F4D647741260E845B457937787827A89E37
+CDA06BB191669AC84B8608EAE132D10177F3FC384980F3A6E439B048A38D0D6B9CEF09F3F2D732AA
+71BD058169D6D0F8C9D146D9DA046774027559A8B3843F6116B418427E78476AD8F0F81E8A6B1209
+8060FF7DD686503F972D6C42FD6CC29C083AC3D72E3751F21D2E44A572EEC80E81EE44C90FAA7AFA
+BCD3ECEB98FD4068F6C3A4DED0E6CEC523C9A0054D1FC2A8D61A4A26F9BC250B8F302416924AB22E
+722297888B85B9C12F8DFD2A744CBD143F9B2514C1CBE988D9CB4E77D90B2EFD5C2A528355A35F7C
+4AF039C7D1D756305967B847D4ACBB81263D4992C001E2A262B9FEE2D1F5022BE5B15E1D8F1D67BC
+52227344EE912C018CB73E5F47CED54FD202627777BB77AACF3EE6B22706FB2FA9062BEE87E22CD2
+802E7706322648DAA0C624EA885430175F746E1F536F9A8E1C610C4A761D07248426DB63C9319A88
+A3FA449C3FB8AC94C6003C745E6BAD717A3B2EA3862D1E08512A98E57772A62F85F1E2FFBA40E2EE
+43AEC11203DA9CE5AFBF673436F2DB6AF85BBE89D802F7A9E5FA25A408DB69E51F0577DD26F94CF2
+BA2FC53EDDD6FBEB534AF15F74F66EF8D14E7FF77D8A5D284C8202DD5A6053CEAA606BF925992382
+5EF4EFFAA8D878652A4CAF2EE43ED26BF3590402686C876F86C1AE95046E527617CDD3C429BD4CC3
+F9654D2C76DD4102471FF746FA9FA379B16DF96BFE3836D43FCC0B8E95120C27370049ACA4AC313E
+1D50D72D1814F2566B8B29FA9C9C20D0488743722A766436776783B939171FFFA00E04805A8B5821
+4D4F114F7B9C3C17CE7486AEA2BCC895ECDE809502BDE57981318A93F23016F056A421B733C4590E
+34AB08BB348DA4A48F19B6BEFAA1DDD2A49A6C440443028333CDD48C85CD698ADAF3FD8676739E44
+400A98B575BE02350576F96CFA54D4184BA47555B8D12374B86D038D085F7FA51FF4BE2FF5981408
+999B48B2FAF305212ED54B2E371F5A0074CF68D1B0E5CD279BBC8BBAEF694A89A6C43F518D01BB4E
+8402AADF34E96E9B3FCCAB4CBEA2741D3FD9ADF7AF32388F7771845AF99965A6078F4DA335EFA436
+BE36903E33A743C112C0267309F266DD44FA998C9A139704E400B89DAB952EECFE2AC09C82D9F497
+5371CCC27DA37890EC84123193314D8A7A707C217FFC951A547EE5B6D1B7C8ED85BEBD9D3F4B9B09
+6A78E5F7DF88C931E3F396973974454E59340CA51DBFEA1A00DE084B64630E26C6D6A3593B828814
+E27DB0186BF2A87EEF268AA1B135AC09B52CFE53051CBCC88CEC5657BD47F603C8E1A6249161684F
+D9084AC279F57A4F9BBD0A546A87E147B62AC860911969A29B8AA20E3AAAD0079D64E6BF1B0F2CE8
+F0C54C9019207E1B403358253C2FA93A662F63B9380B65C5173C198D86A3D0DC1800D1F5378DA39C
+E8523EB62C6AFAD8A0D7AD1629F2CECAD82B8FDE38975303768C7D3A08B91478EDB3C45A8C6B7725
+EA8596A8ED50B8355FB852FB8966479D12E1086223B1E6523A65FBA81DD106FE254F7309718768AB
+009FF7714A8C363B09DDA73CD3F81BF9C0CD3B0C806CF3B7BBFAB73E46FACAD2480EEBA97AE68EC9
+4D3D79AA01ECC22067858EFFA9D7B7F997ABD2CE5AAA8781E5499E8580C405681CC63EEA53BB47E5
+5ECC5BA2A7A3C5472DF034B022F455C60FFF971B01583A29E211A87F7163187B190B0C1083D696B5
+86E9438FD8BAA45101A5EDCD1BE5AB9A585511089DDAC8DF1B1FDBE582ABD945E67F99ADC4452988
+A9859E39C90EF794C5C4E62997085B7A16A0D90107D08610BA175AD66377345662DA7DA4D8FEF847
+EE5D57E3AC54B928A0957CC1C944E7FF14658FE4A641CD26C61105C0F136A75950764B69CA17509E
+3C19351D456B22C87C55E8DCC4ACD3E150D936333FF36499AD6B02B6403DE0F12901301ECB2EBA10
+324BA72B58206A13B8F37B0AEB12115D0C12879C8EA8A2EB70E85C95434564BA3DFF481C8972587E
+FF74EEBBBAB14FB32B8A84B8FC42EBECA65D25E8C32C19CA5962832BF45DFDA4E871508AEC318495
+0D6DBE89019CEA29E40484C36E33D76B756255531ADD1DB24C03B2A64A47BD8FBA3FDCB1F5B96F8E
+ECB60D5834AB001A70740498720AFB6EC03445CC35B51F7987109618C6C78CBE3041BEDC69B6FB12
+8142CEC5C8683B558AFE3024EFF7A12D04EF59A72E156DF11D33ABA08A8EEB16259DD9529CD003AD
+4EF4137B6FF1654236473DFB93F597331A5E26C7796F528F65C94FE07B3B4F4DD49034FA0CC189DF
+CDFF70C2F1C6D3DF30AE103E2AC5CFF20664AB934CE5C19693292071C93BD590383E0A1931E04D1D
+DD18071DAFB628F5D7472E457BF81D6064EDFA8DEBFF91701C5038CB30865D6122076A336732DBCD
+B0A625548773D0013648A76F07BBDC9C16284D158EC7A105AE37A62279419C3A2F360D0C7A74D6FD
+D0E36DCA2A8BD59945A4196598F690878F84C894852C1811AFEA4BE3B9F6A5219E6628C66669DBD8
+FA9A0CFC2DDE7716A356FC4FB271D8A2CDDC8D4684DE447355BC7A287DC56852A638C5777826EB6E
+B72FACCC86F80BEDDD0D649A883CFEEF4D74750172A90B5DD8252592FCFE19FFAAD868E99562DAEA
+E70514F5DE296EF7B57E6F193737ABB6AA317956584423817E11664A67389197AD9F8F771EA59551
+98C9EE40A0761639E638CE9D890DF468642670235F1373D3AC6B1F43B5777FC0A91A96E095E89BB9
+FD62614DE456CE7AFD6B855112367573FD9FCBBD4A4F9C676E672D62DDD34A9BFE8311B6175A003C
+D143C0DF15E4C0B48C735404086E48AEED6B6FA21FD9F40B84215DFF287F0677904E2DDFDA774A40
+19DF45CC877F553E95A1C65DF1D67BC0C60E0BBA4D205C0DA3DA80229FDD71859F65AD04506B308C
+2B783839F31CFE4425263224F08C5C7E98A2C9D3DC8EA5AC1920F4E395413262E0836BC019A092A0
+DECA104EB2DF6B63392AE8E2136379140DE5FC98B0B69860FE8E31DAB5C5DF7807D19BEA34AC14E0
+ABC6F6519C51247B104DE7D912C5BF6EF11B48FC6DF84512E9F5FEBB48F72FF1B722BDC3BB2E835B
+2E7CC6324BEE84893996B8DC2D4DC2793A4F69C18E63DAF04A7BB5C0A9076E2D5A343E134CC3C89C
+4712900656FFC202E1988526D80C7FD9281FE47FBA8AB5D025E63A84051F6B13167BEC15B346212C
+BD051AFE7A98BE3A2491F3C469718A58E783ED91F90E274FB4978F8719E92A99A1E8F142EA7E1F2C
+46AFF0A2FB50F4D105130CE8EA309B0E480DC8F80D506172B609EA4BB4E2BBAE98D8882814FB273E
+690DA990B60A9CDA20A2418246BD10AE67D846A0FA815AC25858145ADDA106A6778A11877FE59A2A
+BE300D7DB9BBAB31CB5B960B7E4EF91D4600886D8795DC361CBDDDDE05EBD54B1941F426F7FA8399
+270D2F54C998BE92D146227270A8E89AF90C48BAFC4ECCCA01E6322AFC165743475E752F39BDAEC4
+9297290510FFA264342A0AFE2985F85DEEC66C36EB4A1D46683EE7C591A89B81569A8566AFBCA268
+10DDB0970577A76EC8A066622606B08315DB0F2E6C671F3259C73637D773D1A180AAD66ADADA2A65
+95B5F481E5F59E51CBA876FA06D21E1D674CFAB46A02D267E20234324D0891E7847C13C69BFCEEA3
+AC55F2EAF753726BCEB0DE1EECF42ADA964BF9E475953302C2FCA804B70B779482DC9319B40381E0
+9C0096460AE113C19A2DC9157FA138CF0E7758F71008E71D0F7599744D647B09B16E3C795C56EE5B
+D14D8D63E7A512900D67487975EC9CEAEF69572FC3C2342AC5D365E8A4BCF462006B5268ECC15754
+94CAD9A9E7A9E8D9AFFE49AF647C017743EC7CFD5E66F4E4D845A6BBC836849274FBD270CBF263F1
+67DF7E26BA91F21C60F96257C07523AC37A2193010E976965CBD75751E312817C0564E1C5AE0CBA8
+BD12B01122D07020A0852120680985A8AC987BC33BE863EEC52AF13435B6E4048D951F5BCE36526E
+07A8661CF2538F69D1F223BC53BF5896437D1BD46F57D9698F642F0E99C7392D8EE47134E34DCE94
+D392949B418D9821E12CAFA8337323E8469DAC24DADC6AAD4A0DADD7FF65694BA3A27964D28D8EB4
+1179458F91CD3F83B8F119BF5E76184DD29CC4C0718CF7945DCECC993A7A78739363136CEC7F2FB4
+95EEA8CEDB3EBF14373A058758C442939D36774435554851E9519B6F09C31EF26B6CD997DAFA11DA
+91FA9759F17B7079164C5B47B99CCB7A876FBAB1D0D5D1E1A2683CD6914E6B3B755939CEF1C9168D
+30B2738C4349650CF86C90D2542FC9B90F36A494C035A1C86DD716014AA16E6B9EC7AA03B16554BE
+C436511DD3097FAB1FD0CD49EDAB96F74E8FD26400FC748CBD9EE1EEAEE24DA30DB6F8734B52818B
+3A5E510AA5C14E42060898033E7E36CBA9A64042CF94A74E4B52E37AC027C0DC69BAC4944CCE12E7
+AD81AEDCE642EC34CA23E3FF07B8CD35DFF19F33C8D4DBB56A52534F8A827BE47AD4AEDCAD83B273
+38409FD1101C4DFF3F12D3DF79AD1FCE65B2F419451DD059C88BF066413E23DE27D3621DAC2DCC8F
+9F3620DAD0F4B1A6E8C9E6E8ADB552E1EB2C4B2A3B73986AD53ED9ED8911F82F750DF05CD2EBA3E1
+B0DF208A87FB5ED44C3296B803881C1D9776D13350CD29C3F716F0B5A8B8557812024BA70069BE65
+89AA579EADB1F657712DF2570843D7C5FF7F4009D4D232D3547DC8B92ED5C4DB77B76255E661FF8B
+163C6F3856DE5651B597EC7C78B84F0C6C1D6EA3A82286F1D3BB45F708D564E139E81F473C705AB2
+56346328DAA64D1EA8645DC10FD449092E0634D9D7344B2AEC3C75F6B6CD8B3F3867FF3CBB0F556B
+186EE9A7C26BD2D17C8A773055D9D5013BD2F937D697A770C57BDB36D922CB911CD14E7FA14160BE
+19C1A052E297B1A2D682D4BBC9F1D2493BCD7CAD2FA75D904C5F5479179DAF7DC6A4E0D269BACA2C
+4F2430B4C8CF1572FBDC750A05DCD5B09FA3A9CD6F2F2A386E2B3D4D8E257BD43A783B38E63BCEE5
+03EA96FF2C373181744A607F0CB8D281D7DB1A6F4076AA3E2C61914BD796EF8A0873F79F964FDE28
+B792BA99A20C3F1F5ED1FD189FB1867C84DCD6AF43D49420C8B1F3DCE7DBAE71DEB17FE45644DB24
+4F44B1011C7C768EBB7254F4DACA64E9BA87AA7CD0F0C4B2228FFB9EBDCF3DDE4DCED39399FFEB34
+8811547D025320A88B480943A339E2CD2FA3605AAAE87939B1D7901465A1879BCB4C5BE1A179E7E3
+71F1BA2E0844F88AFBAE9B78DCCA47AE8AEDF5BD3D458C7D4A7A08ACCBF880D1F1DC69C636628DF1
+EBDC5C42FF88FF8B66351F3F72D703E52F3CE91E4E00759753A599FDD863788E99858498B66B93E5
+083BC3501C39A9BA928B0D763C28826FD237E949EF0BA85CCA9AA20C405DB6D5612DB718F7B4AD31
+D253AE306E4D7CB615C59AE668D347A4E60FFF7B103F8BD0E7CBDB142A763BE88AB40EEF6B8FC200
+458D728930AD0F94FE52ACBF0657C4907CC7942710AB1FD8BD149A9C9DEF6B8DCA7DB9062AA7B1B0
+11ABB5AAE8B77893A023F9EEEED4A20FBC30F922282A7AE2F1ACFF64151013D6B8AC2EAAE58171A1
+0F80BC18C3BBB5DE1E22EBE6033BF83040629023D74CCBAB3F1923CFA4A6735E1DFA8A1B261FBF1C
+397E26F3BA9C2629CFDA84DFA3D1087EBB19DDA7E2D76E30DC2E15B8821D5291DA1DFD73940E5560
+A8A6DC91BE0075E3ED8D9E8CAC85AC20768D868CD2DC45DEADCC8B59AABE6EE5B2F891E0D7CBAE82
+0F83479332BF9707486698FE196C72EF72B52F54314329FC498171782BF160E1110A19B8208FC591
+EF0F0DA71AF657B43A7CC649A8488B759F7B69134B4F9DCF79DAEBC1CE52CC8015F324C9D46320F4
+4E1551EDA6D86139DFD1DB814CF38A22A89FABB4F75FB896B00E769820F763486E86668253CC466C
+1529A5A924CC337C48448851A381DCEF63A0A302B65203D6571A1DD1FB9DC0C3BD6AEF4891497033
+109CEB5A481BFE442249940EC54096F1D0F2436D9E60495D0ACFF967A741B30467D24AC6B0032213
+18666B951EFD45324987B10BEF4AAA0FF1DF6887377A7F70F555DFB9FF1001C67438A167A00B05D2
+C37065655173A7ED9AE342DFA1497FB1F2FED6098901249A085D31B66DBB6AC25EF16C106B0A6FF3
+47CDF66434DC3F0012DAADE80B942D522CD59AF4C31C1C062157B3D000B9CB86E2AA7B4A5BF31605
+8A0D5A148EAA2C67977FAA0966E4C3454E08DF14C2498AD76E389AF65D2C139A6D8675298C46ACEB
+7DBE6904C373C06E5F71399B2EDA0B40AB96E8BE991DDC39F92F1D24797F9EC9F2FAE25669B43754
+E2498E8EA5C44B176C3FB3E8F7A7A1481275A461F2549AFC4CC73E28417BD8C5212C13105EAB967D
+AA679AE822B9B75B372A99C7E82D6BD83AA2BA00314DA4AC51B9CAA30D80507505BE24BAD0A87C5D
+5D7336EDF60CCA4CEC8201D243C3932F74D171E2409D789AAD0D04A7BB22FB6DC3AB92AE33FFEA89
+7C484D741039F38C317EA396A0FBB9F15A27D87FCBE007558799BAB73212B6E5FAF2080BA074724E
+AC87D88166DBC1464CF5D41B99428851FF1D99246944511CF42C3F9248513E9E51593F253D89C604
+388AD7132D6A169E9DD888E020AC1F8BA606F2E1EBB97977E505D8C40853653D8F398F71CC9F8F9C
+540C22A1E6195BA578AE7262FC845FCCF77B33F33EEF266489AF8B81A615D6A13464BCA58BEC16C2
+3F31D678F14A938BEC31272DAC3CCB1B2DAE577A26BED852FC59843176A5FCFCFA0AB7FB00D2309D
+E55C82CB9049F44FA61F1E313205A76317C4CF529A4456019D970624129681F46A9CD7950B8B5C40
+61853040113C8115319E68B37F88D864C6957DF813B305D09E6A1716B10F26F2EF5C727FC77AABBA
+73E12B5AE6416AB19F6563CE14046B715BD4CB2B1E4D315F42D10F74CDEDE82BCDD524A1A5460921
+9084CF1CDABFE72CC8375478B41614BC18A914903596D6FC2F361EE519F875385F4ECB50F7053127
+4EBDEB14A5DBD906A60817246042E3799BB3AC647CDA7244B7998AE4F3BFBE5C767FD2142E48518A
+4217599E0EC2CF5E86C8C270FF8B02F949EE001D6A439BCB4BC7D7F7C8167C3AE0A7E59687FB8BF6
+F37BEAA164541B8EAFD92E9D152E3FD0F413C99CCC34FCD8AA455A0B55DEC846A5874B94FC95CFF1
+BB386B2A1E22CD1C3914264B6D5BD1746972857C9235052D77A6C0DD3019F8A307FBEE63A3EF12B0
+39B224108276FFA84021F1AC5B745C54690B3FF587B4B1710AC3533A67BCEFC503ADF1F4B62B2910
+B31965E364EEC9CC437CC40181A7320CD52BE9C546B8F1DC824312216C2FD8232E2BB8D40EE2E314
+54C09772A387F9520E331456C269F51A078E6ABD9FB6A68BFD5F557215B0BBD2227B8959CBD1BD4A
+EEAB094DD18E891C61FB00933C0A0D76174D169C0B6445D34C00DC9E06D85EB086C18F3BE27DF734
+EBB9CF078AFF6514438549CBE92A0C0D25EFE4A527D86F158B4E9D8870C7AC5D6C059643A3298079
+CC20398324CA87273B86ED801057D797D91BC3CF2F96C650EE1566CD3CF8656CC577D38B830201BE
+718DC9A494268177A5019546EEEDBF101996BE593631654B638C75A6BAA648CD1E7AA9AC1EA60F4C
+D604071C89DCCFF8B3E430A57ED6DE11C5837E78956ED991058F3646219BEAE94E4D9381A33D48CA
+9B8FF12B54A73FF869D0EEED7E098D80152295E6016CDD809173C57D1F5FCE908A37010AD4C4471A
+53451DE9B4363B63437C374C598F548F145D3D288F42531FCF36A9CDF72521F1C0868FCEEEB1857E
+A983F6B75CE245D875BEAD1BCB8819E5464518E04717B78BD6E335F0AD77B832AF5682062A1E2AC7
+7CD5EDD5DC372EE456C96D38BF8BF348DAC2B4EBBB2440F2CE97B4B337F2E23247E3E8423BFA9237
+CA6CEB6FB93F960CAD894A96F0371168A33222052DE9B3BE04B022AB95C0C243486E35197721FC55
+311DC55F87BC72D09B6C940CA36E6640AEB66C394A5949A604E7F15DCE3A008BB41B0EEF2840A357
+F348443B4DCE064B4C15E5EC52E448C985FAA1C3D6526270B1CC691009959A7620C9A6202619A19B
+E410FF7BD535A8B2640AAA459DFDCB8F2BB35112626497E8A397D4F9E04788322A738DC8907CB643
+15CF63C95809E90D06EF02F72AB04AA61FE02ECCF7E9049FF9F3EF2258A75656178AAAC9F3C2A26C
+001341862D526CC14E92A81BD63502F959066E0BCD659CB9B5A45606153DD77039B8C5D5B13565F0
+0D95A41937CF97089F3938E39659A64DC3D6046D0E9EF66544CAF8A206635DF49926A3EEF3FDBC9D
+CCEA2886EC855F1821C4B9CE1D02A19A11BBBEF43A7D4D536715548A62802F64AF30BBCBEA8C7E55
+AD56C801D8A569C8183615A78CD393CA42C103F155941E845712C335F4ACFC7807202B92A983111A
+ED241BBB8501F15560E8F2157C29752BDCDB274008137277920053D6D7DCDC626A574A82A8A34F1E
+77B2FC8CF7C1A7322F22DFCB450259EB450C52B70DF3584A7C54C813DB41E3DD81253A03B02BC252
+346AF0160716355797B6F8210C453DD7E1E756FF08C7E6A5F4F87605E1DFF35A130D79148A57B7AD
+12D94A129FE3F055CF974EBA09A2B13DEECA2E02EA818A58B81E8743004646C7746110BC61B86ADF
+2D5D8C45A6A5461EB34497FCCD09E711F47BFA742C73F87B257B53F30CB68D151424DC3C210D3E8A
+C67C2495A8236EA2D7985A5E1DEAC699D7B700E6D38EEE2E93B191BAA5A8A2C916D206C63FE63427
+AAAFED2B5784276FC21EEFF2D70E47C8540DCCC3E00134642B703795CD3702631AE2A90E063A218B
+61E5B89BBCFFF84F567E37A31A9B349717A8CDB9C9377215BA838FF7469BC486B64EF2B6D92519C0
+BF0826E3652903F40E400689F5749DF86FE3DE178E21E20EDF9053081F6510D8F19ACD021CBA481C
+484D30EAD3B84ED0190087EE478A17154B243346C3938FDD5340CF6E47B185E64ABDF44F8CBCDB82
+94492B91929BFEB9DA2B033C3ACEE554F0F1A7F8A56DF7C06A3583C1E9C5CA458D40E550FDF3E2F2
+E7BE8312D5FEE98543388EDC8A04CA29F1B82B7AB4ADABBA3F2C331EFF3521B2B92F99C4377AB827
+A989B423750D36ADDD2E286E7F3B694E29B8BC403693C6F7CAB5FE34F1E48C8D41B47831E8C3F5BE
+5ED5142E3C44ACF5180CD41FDA149B1F4AED36812E42BC184227F5034220F74F67830255E1CAEC12
+66DEFA358A87D2E3B4B4E7EF30181570D0B2B43072EE0311C2C157D32EE2BEA8EA4251B59F6B61D2
+B4FDEB654DEB67AA3DFF4AD65B727F0D6B7D61523E4B44D99BA5CD33540F340A35DDD466ABEA4E72
+E504FC9BAAE51D231C33A8CE7DC2970DE4C1FB5B096A3D9C641EF77DC9039886831DDD01C4F21E6E
+168E38BBDDA5F4308C959C7BBF36A42D042DA6862937EB20D4FA2E5927741A58DA5CBFFD9553BEFF
+BD92E6D64871D8B25D9049F4E71970A8FF5557D1DE83DD24286D6C3E4770EE00F9A1A0B0063C9999
+4AEC75E84D6F9C488434D1F3DCFD0A8BEE9ED8257CA97E75E8B1285747184D6D2228EF95D4A0B8DA
+252318ABD35C8398FC6568B294D90AB308A7675F9F160140F0A08C88AD0CA1CA2CF85E4D031CFA3B
+87635F1398EB7DBC666A259F02DB6741D13E11B230025DD6DD64C438409AF109090058151E4DFB8C
+0E9CD65935C4CC063CC6100FDE70896E23E3661C7FC1B8228B26A55903E997F80207EDD8863FA074
+EE4FF23BE585BAF708040C9F8CFDEB42FB8EB71D4CB6D7757E973E4D8C9DDD082712C23F868E1135
+ECD91250BB4335958B07C12FDA75EEB56BE19D1644C1F76A8811C021122619F751CBBFEB1D3DC912
+999017FA163672A1EF754C5CB78962BAAB76EC48461B492FA88F9897170DE857CC8374C8BAE417D4
+C78A56047024731F4A45145F0393A27CAB614A7FF747BBC28E6880D4D01C0A6CF317A1DE5BB5ADFA
+4B5FBFE0C57598C79F25AE57BB797A489D51F85A9B9CF8BEA64293F8FCC43B0D5484DF99DBE19152
+692CE756F6FBE8CE5831CF4B8A5AF47524E272C45C62ACBFBDFE7E60B05BB1A1A6AF0E9210012014
+69B3DBB49EC7B23A363FA68417B7118DCEA71D4ACA2E36F88C6DDEFB70205DF3AB7C74CF65CFD01F
+F85FAF99F172689737331D4C6CFF7A29029772F487FBF625F17BDAD89B4AC076948277B4ED687840
+301016C2B7AD4C6D02F81E88C75B7A04D724E234E38A38269351582245E361A42C75B8256AFD5624
+B558ADA2190F960A896BBAE7A8C57E76DA10DC29E69BBF3AA86214C001A27B39C1D17C548DA5601E
+86A5CF53E7B1896BF003AAE9387ABA9B102EB1E9002DD3754A378F3E49F2C6EECF47EB1BAC2CFCE1
+1AC0C5CB063672D32733563F3E1E891B6073739BC53AAA0043FC45E90E413DFBD4548DD320B681ED
+70A7443A233D79E3F038D26975586E5CDD2115AA614727B1F6DD4024B85CCCFC79D10B7B6AFA789D
+B37BD0E8C423C1A4A8681B5FF3A9FA1F61A46E46C4B1836D1AA41A89264A7F4B1C259E4B10ECDF37
+5BD26A1F412FE01FBDC03368FCAF48AA0EC28B1BD603A6A0D0DADE66D14C9B7285569230FAB76803
+35BE104305E4B748FA99FA31F23991608DFDD2097DA292551136F255051C9F7EEF3FB7C7FDB4E651
+C3D03A4CA357B587245236F4FF3252563F6BE08EF8A3EC09BE2BF27B9120F7D37801F6999EFB1C8A
+D1A08698CC59CEAE2CFCDBF6BD8F94DEC94F7EBF33AF05F52C85760C63950B455510C6AB9398D09A
+C288EFA09E8F631A59B03FBBC75BBDAFD675FFACCCF8ADF71E815A4A49F14BF70E42DB0B7347B528
+4E234C24010E2177DBBD57648E398FA6B54571A37BA8C989503594D03C6E60871A7F964599022154
+02BA168B8D1D2685F5CF8645D5E11A1769473027F42564C2966C10C0DEE1EE1B6975852A4870D492
+83A470E623337544A7CDA5C16FE2855BA2A548511FB4D4FF2E3E78D108E4C734F64EE2F12CC9562C
+BDF363EFAF5201B673AD00583FF108AFF6B68055A5F299452D176EAAFB92C84F114C8C22A05EAD65
+64A3371420EA9E646308DE97D40705E1638DF08704FC90249CBC0D2D3E884A4562CC27370B1A9738
+9D8EFD237E644A7370B8B38ED1C377F522C75F981D878A5E87101E621DF9D85C7207BBE5A87CCB60
+7F93A2E52F660E05C83A7A6CE6D01AB4B62A1EF8DA47CF97D4BBA0FA8EFFA9C0F61A325A97ADA694
+45F23AB1FE27A66C271639F839203040D44B11ECC6E805FBE88843B34C4FD52D1D3C6C70FFED433F
+C04501FC20536ABDFFA429B8DC8192B2D45DD9D646049CBF40719C3D674773F9676F9FCF32817DCB
+55402A72C56D74AA4CE4035687C730B6B44A9CC614BCA5A3FD17C170ED949E588EE45E89E18B0766
+2A6327FB9E8475C43E5DA1B0AF07C23774B19C9EF59281F5D884990D6194170D8293A86DB52A0FE1
+7E88DA82209A00A16BD29B8B2F13FD60AA25FCFA9745F57C8216283C1D6EA1C119CB9B8D57C00419
+5210FFBD56395A3EC2D3098ED38F389EFC0324FD0E55EA339B3892568229D8D3E205A821E8219FCB
+1A7713FCF3450F8BEF976CA0BECA47376A8CA73DF85B340C67EFE4534D459617996526B5E5D3D19E
+17CC5449E5EF2B82B2C4C2131FF8A19FCFE6A186A9840D872D85C40665A7A04E67EE26B8BC9206C3
+5B44C8F8A1AFC3867D96DC6D48BD45063BE25B882E9BC0D0948C18DC870E6925818E1FE17D336217
+F174EB4481F5C0ED37A3BEAFAF4D46F857811B6728BEC461AE6468D87A736572F4FF95B58B04564A
+9D3C22754587DF15495A319D822B838461764B73483C1F7CB930EECC6F7424841EE10E4087E95120
+2FE88A391375C96BEC4480328A54740213F741105B12A39F19808F3823507B88115D468C61B212A8
+ABAE7480E39BA52390A1892C7EC50271156B4E8076FC3ADA222695DF372385DA7B117A29E04CD2B8
+0A320F186D61C963FBDAFE9224E537057C49E82E405196AAB621B5FE4011E1782A747EF935ED8BB1
+1BDA39A141CC0BA42D04AE123383BC95A1D03A85A9440010C3B9613064FFECA76197E10919BA5006
+F35837ED9BCD7DE5E6D968AACB6FC91178091FA467EF6FDEB728E17293DC89DDE5A5261FAA95A2B0
+000FC750E7073900D4D88247DA464613ADC2B3903A6132D96AC0E1C564385FFBF6249DEA76BEA2A9
+9160632DD2FC2B99133E9F2F470F72B45D6F18B45020F604B06CD9174BA3805DB60EB9C5E6A9C789
+ACE76AE9C79C1BD34434E95E501BC968633AF93FF4883C6A596776254C0C74993710327086B2886B
+02FD3E42A725A03459CB36EE34A094139AF5FCF487D3DFE63FAD20BF0DFB60DEEDA2ACCA3510E963
+189D1256EABD81253F7FF9D11263FDBC1DCFDA3D1EA2E52005CE3C605C993231258A717423F64BFE
+EBC34684EFA676358B9B543C2042BEF954829FE3246A879845B30EBACB43D8DD7A20FCFEDF763AD2
+C5D20A798B69E08722DCE6A5762E249ACE3055B650D9E110599EA30DE5C4FE7200D5A8DA9E1FE268
+6350D0DF334877D0B9F6524C552D0B6DFFAE125EC4C18F7547BD51C14288E4ABB7F8A1A00458596C
+390AEEE6FA308AC1F788FAE30D7F8928AFC91D4DE6352D20B19D8D8AB122B7378CB379C5BE7E3CE2
+922FE667EA057B5D7B3F0B51C7BF0C85F87AC2F360D82C38964F4DABCC9104B32F0FB8802235E8E8
+D9A5997D392259074C00AF2CE1D2BF7B8E90E2E2AC34185C68A03BAB8B267778292B227245D7FF86
+70786E3F746F86B9D4D17190DB859A0E144B2A61E6AC9254DE5DBAEF20E2E9DB0B2FF654B996E962
+F55E465DD238BD1643CE59DC2B5A58B1E6E4AE2DDC2D74D79AFF3C34E4E593E051FDA236B79CC0DB
+268D2A89B1878051223BB8F33FF99BA87A4811C0B3BCC01171D0A731EB732ECD8749D27952C27886
+B252F9C3D190419FD2900987A0A255B9753FB7AA70C37462134C467A2C4B7920BED9F9E86F8F98B9
+6D00AF8B05A4BD5F14C2A0D914A9A84160D554FD0718F50ECB5DF5E76623065852DAA74C9AD6DA07
+A119DF12C3577FE276AE551D48B1C5CD8A50E84DEC9CB0840520D78FA7F9A7C2071E28CD20EC7649
+B991F3818CDE295CDB6085F24FCF93147E9F4DD084FBD32525326D2EA147ECD5B6C9D9F4A7166663
+AD18BF234E9CB92FF72138A8A49E73E527E9A6488A4CA808AECABC94D693CD2C0C357D285F65006F
+A2F9197F61FBCA6EF07B013E2B558AB531D2FD270CEE7FA8E467FAB885E90C5884843AA08E2BBFEA
+0AA575643727BA18ACC499FF34E3438645BE2AA71EA491E54687CD305E12BBC94FAEC848311AE816
+495B013BC5075A2D2AE54A7AD7C9105B64356CB51F18C2C28E3A83B9D81A4554DBEC9BEA9A660CF7
+E1BA89E6D4DFB3EEC6A3DE3FCDED9B2D614156EDAE8CFDAD5FF0EFEE31DA3E6A54D94CE9453A1CAA
+D9756D91BE85315F6514BAFBC821EE810BB5D8E1B8F05F64F3F72C4B35D424F7E4DC3AB581B74ADE
+B6D6297CDE7AA8278909F269FED79B7DFD39B1C0338E01D556C4DB9CA3A8578ACE3EC3D743ED4B9C
+0145E4525E8C315F7A1B98584B975C70F0D415708C8CCC13F848B1D36AC8249B73638F95DE0CD27C
+7EFB52BED4339EBDA4812564D7A77416DDF4CC88CFB52D07A252D89353C6826CA1832A153242979B
+6CEE783ABDE65C8B40CF4EA7B42B8DBCC0E02423DD693108006F6A4AEBF053B666C3CB63D1861F86
+EAACD43BB9BB6F2C3A17293C189331D253B447757EE7CBF4518BABB73A1D44874D7F0625E6A013C6
+08E991B4AD17A9ADB36740D25E3E35B459B422F7370B134CDFFF3F3BCC4C32B4E9EBF6A2478013F6
+6933A1FA9403A2F1161EC632F1F04EDF95ED0F33DAD9665D54DD9DB2564E51DA7B65978CAB50D6DC
+1568976E83B056EB0E3A6758518B6E17E9EBFE49B72EB148B472BA144BDC2AC95744C9BF1258F0A2
+E47470AB0EFF90E190A41108914AB8C1ED6B11E0681778521870E80C16AF2AFC723CAD8719ADB62D
+3939D3BC8CC1D8A4E07E9D734F54ECA33D936D2C39D5C8055739C33E53359BD40E576C11E93B4B4C
+122BDBC9B1BBF44243AF4F0BCDBDFADE68C526B5CD74E29CE3F70D62BA83C489034111FE8E4DAEA2
+F01F9D938ABB532DEEAC0E329F42453FF5C15DEC2AEA8C198323C9E8FEA55B3F5DC4751D2E2E16B6
+154E7F2ADD46860E9CA71DC114C99D80E7EA1DAB51E925DE161CEDD678EE6282AFF38E3CD0E65954
+9C970613209955A3F581E1ABE485E56402A3DB0D1E9B8A9DFD05C4B0B7F97FC6D0EED0B69AD6F182
+B1D028ADD2F24463834B13F5C1307F91D363891824E81108E57CFD5211F86400D3E96B107F3B1FE8
+9C4908649D04A46DC3CEE0DE66AF03A7FF9F4DAFECDD6DF4D93784CC899B527784DBE0718050FCE1
+85BDE3F39DEBCDD660B2488D23AB1CFF87B0546D02B48E7B7724C9E87B71BF34B5D6640E0F6ECE47
+B182D41C89461F712849C6CFDB7E3F5EBC1ACDD12D65A422BA362A8FD6CAAC5104CCC5AB5FC04A46
+E4309ACAC83D659DDDA256CCDDD1BFF9AB3622450C4FBC89C82214F00C42FB0311BCB1B722A691ED
+839CAF9024FB1671F18E4639C96D84718C663A4341DEC037175C6BBD288BBF5A0478298CA726567A
+9B74C32A527339C666A294A17F6821CBF243D13EA4B1603C292953308B566653423E7301A032E5D5
+E2B93F1C1434893633DD19501AD12728B5A1D9D36635B589FA2E151140B543D7C5E469AFAE8E80C4
+FC1D9CB6C3823CC1BB7EE40AECB58CBC1465792226B19E0FE79235115F6A3AFE19F98C5DB63D372D
+D7C041CD940F4F79F2474D9CEEA0334FA04A97DC9773064895CF11CF73F11B4684F06E48F4469F6A
+1AEB2CBBC52994DFAB3319DCE3A0C8C2EFA9627496F8CC84D3DF3BDC4FFCB61672780F294F453278
+AEB9262E66486856D37B7647141A82E049364ED3D03F925284A3F1FA3DDF4C0B48B3FE22E7DF9ABA
+239D33CD300FFA8FD4B96192BD568FB18D325CAA8E1F1FD4B27527417B034841FD49E4A77F217062
+3CC8B22101166D80361EB15FA9020D24F61007B0A8274DF9DFCD8E97C85568E76D34AD5DB1779B02
+F034A69CCF9D4EBAA188EB3017EEF5B22A0A552696A574907F695098BD8A4849D5C8311F129447CD
+7A3CF88B8191AEC0AFF30A38A9AB8135608A7829207A7D242F6E1FA7DDA19F5E4C28560D42DB4405
+77CC0C5F5803EEE897103ECA0BD944E320AC26553BEE7852EAA733BD13DF760056B2F5BD1243BEDA
+BC3C1EA0531017D74B47E18F801A60074D6DF849FD0532234545E5B5E112D1E7385341D39A89551C
+80DC2DEAED5D5DA2A4BE5015D297324E92BE64C68428132E6EC654DD4BDCC6640C68835FF8A05E09
+9604B8CD43D3AF2B2FE10C8AFEDEC5A70AF8509D12F662338CBF166D9452CD36331758AC4F4CBD7E
+DD52139AD27DC52569877FE709F297444C4F31899D1945C81B14ABDECBF31DC463A4148F04EC4FB9
+703C158216C0FBE65CCD450043ABFD4E65BF8B28CC148252E9F3E797EA0B57B8721C94CBC2EA602D
+F2C57E87938C887A382D2659226463BC7D6A1DA87F4A341A59BEA458177D3F18D1213539DC0E301F
+6EFE0111FCF6921368BE17CCBB7428127E0C059C2C5ADB2A3F0197F0CEAB77FF7F3C027A8EC3EE76
+CF5C986EB47CB60561C773B3A2DA47B5A35394E29373DBD5C3FF4C9213A89AED77CC4F3FCFC49EF6
+EC7557C521979A546983C106B3627B5FD2D71CC5F08A32BF49332A89C5DA71AFBFB94C949A91220A
+B1F885C981423AF93F73BC1CA4D92D9DBAE3EFE6A76E2DE3D0F74FD3255820636E3F1A6B7C185306
+23C12AF90CDCD2C0A728521E9B639EB6345D1DE8FFFC3B19C72E7A93823DFE3115E9E7BBBEB28CB7
+3DB121AED8920D47D8CC08EA2E472E39A4CAD5881B5C4204F2B732AF9D5189D25ABF413CC78714CB
+01B1D8CA5565169A919DC481F6D2E67F1D490AEBC5CC62A8F62C1A323EBB55ED35AA5C8D6F8B970E
+93205C2701CF4817BDA994FC16197B469ECC5F5E9DDF0FA05640C2E571849571CBD26402B1EB1E80
+3FCF423345007B9B52B13E3B034E8CB3984B925EBFFE719ED4F39F3D0E3343316A6FDC26BDBEA88C
+4366D3B2F851D2B244CC4408251AE2C77348CCE9DD8BB9C89800B572D38C5D1CC34C740BEEBB5DDB
+0A8BB251655FB989840D23205D16311A9FCCF7C85F6DFFEA9704492A4E7A8F6C0BDC29745AAC2ABF
+AEBA02B0E7AEFEB92BA63AB0DF844EB09D505C3DFC1058CE42CDD8043B76398401E1DB862FF9F76C
+05E8BC6260A4443CF494BC1755913D51745BF45ADF2F8C7A9546D7EF4FB11E9D94E4539632C2A396
+06D04480EE459408D7A2A869807A4C01881C1BB21C296A402B5E6E07093D833C3DFF075F4DD426EB
+87B1B8DE16C146DE79F52F5943015331EEB852809CBB8E1D6460AC4D176FE96F8D19F6CCB22ABBBA
+A27C4497D91312C3CFB5BB913B314E43D2EC6AB6897BA7C34CF2CAA6DB4BD69EB5DFCEE0AA917D69
+50E36A68A4C22A60DCC69379D47544A58D640EB10DFE120FCA843B588CA8B94F7869F97609A6FE03
+AC86EC1F7CEAD2EC8E81977D1B946E459DFCFEFE65A7BFF67E66F5F78A45D8DF65AF0146DF74E024
+FC042328886CC1DD7779F49CDBB750345CF83CD678A6A8897577299DEB38AD665DC4F21CE1892A18
+C256F318107DD3E9245C1AD3BC93CEF7B7BF057E33EC9A3F953251261AA3D1A8347261E70A46F777
+3A84F3D4D1A0DF6DD22A96429349DE0D180310E17955B10FBF53220EF6483D03C650A8D5C16D63DA
+F65C21ADCD6C2D0B5D4ADEB2F5526AACF7CF42F9A8BF4832FB2D4F73F3D5FFD984B572232F87BD3E
+59133ED3D2FA19F7856AD812515C74F7D851574019C532C25F8E163E595FC9C83E3E820C3CBF690D
+A62578A980FC0803EB6DB9B1E90E3256BD4650816ABE5EA86CE65C2EB418D0ADDA5F3EA04E17AA8C
+4536CC471AC20236E66ECA3619F161DFEFA485386C30EBB86A7AD930FD0AADF2DA69DCAF26C0F677
+206E2030E3B15B3662C0AD03DBC1636EBFAD1F2F2C37F5FA9856B0198C5B1D80B69C5EFFD94CE071
+5135C649C26B9BA1266B0A5B270CD08A706166C0B320915C87B27DE21DEB5D7E4806F6E700B7A06A
+4E29B629CB40761983E9CA8E34E869ABD04DDA190BFE5A6EE8B22D7E511B84EA584A84211F27AF89
+18DC5AF8A1FF2D360B6BE3CA8E66BA4CD2CE6A25E7E89406684DA83FFBCCCCBFD0844FE3BECD7DE6
+7764C59C022DB1168D585FE25073FE00E30218D1DFE115CA1FC606AFCB04F2A082EF91788B6BD096
+84DEA31F20034A91AB9D971366F97B5009FEFBF1EF0AD941654081B1E8F0B2EA495069A1DDF11DC5
+6857D29533DC857958B49D1A0779732819FD22E437084BD9F3C4F2CDA4D12CA14431937AB63A03F9
+C040AF1D801F367ABDCA7302E18A9050D6026FBA5A5A7FAD44E31593173CDF277CD737D1CEF59FE9
+684252BC0DDD00A80E023B88222494C1C8C0884230AB11D1083225AFDCDBC1E24D4AD5FAB396D2E3
+70E44A7571B230660D510A5076D8E35F7DB72C0566DFC119EE1B8AC3C0406950A3C4A4DA36BDE297
+040A27F70753A87E6CD593DC6BE9962261A99AE5949340C5D45C94A9AA3DD636CE8B497BBB812345
+7C824F443A53B3EE595C38983FE3E07DBDC6ACD55CAE8BE1081AFD4857A5F52A3C925143507A3C37
+F1992CF72ED0D4C48D94AE6CADDC3BC87AC3A3EF035E02181F78449E4B063B0835E827644051551C
+1603E2EAB5875F28FC77BEBA6923428D5521C698C6B7F133B0F689F105FDBAC30A8ED2F29F0255DD
+F8A037B81F04EDF004CBE639C8DB0F94D0C5DB92D34D66C2FED66CF8B895AFC4E659D08388EA44EA
+E83CE459E5BE306750A682B627802990037157339BF142BCB9C08FAFDC3C3FB16DC3544F62C6C7E3
+3E20CC4FC7CA21E2C3F6C546CD78DEE348F1A4C8CB548EF20C049678916771D83ACC9B7B22784AD8
+580134471A3C79BC86B5D6D0D305C32E6204274351C94F9DF45D9B2AD5B5087A89F90D6AA033E4B1
+D1BED022F36147C7ABD2B73134DFFD50907258E610C3B20949E141172B1C6A76DB238C375021CBA6
+645CDC26B717428B5A9B4D3F32A4B1E22FEFF3BB93FD889E1DEF8087718D5E3E650FE4A3330DA9C3
+7E9EB499DF5A342D8BA4C0A033C3347CB25A31BE143ECBF91384F2381E323E7FD3A82A3197C18905
+3200AE2C86B9D01AB0B289841EA7E9E9A26966E0DEF54DE0B85D8DF084B8C590081E444BAF1E1F60
+670FA12AB97159318624F2AF1B5EC7DD83C1073A99398D2143A52D10A13C201FB356BC9E90C63BB0
+BC2D4C42AF4A8B9C8C4D58A1B32E0597C63B3F8B3E893BD3BE8C60231838F1BC78E73A6C8CDD5E7F
+2907F897FC8EE99BFFDA7338BCEFB5AEF950E5549ADFD207AEB15846B509FC57989883642498A381
+1B8E5CDE69C05924EFAEC232FA4CEF302EE3251366ECAEF57D25CFA3B4A9E6397D996F421C900BEB
+CF73B038FE7B16FD0A1172AC2F40D19CE0B02FCEB8BC47DA5344CB933C7FEC950184F78ACB32D3E5
+E290E84BE753B9E7A7BFC4416CCF29D023760C06CDDEF2505806A65E1508990529245059AFD301DB
+669D41BD72BF7A80A9DF66B876B3553FDF4DD38D15289AF7A1AFBC53FFFF135A6348DD784AB42A6C
+0D6AA330B069607E2DF3CBEFCE79D6F63E274C9E73A33EB85246D5EBB986BFA923DF68B2B8CF82AF
+6C33E785F35B25B1D1D614DE85A4F4510ADFE42D75B5FA5408A59ABE53859E28B3D000EB9C6A7D2F
+67C91DD14C895BA87B9CB57B851E5193FCC2A443AF85FE28DF6F39537F23A058BCF81DD8C04CB2C2
+5040300F4C55975E856DCB4E21E2B5481BDCC05601942FB25BB8A6B6F93E2C2A33CD478B44655657
+C557EBB080179EE5D98C5CEBE0B25BFDD952FFEB258014D7A5BC4BCA4F1A23BBA73C454B12960451
+CE1752401B0151CB2E01D5C72595095EAE91D8D3BD55A54A2AEA89239FA176FA7CD6F16BB0733EF6
+CE6E77763A23AAC77DA88C8EFA7BBB2991E472FF2075FB25A75ACFA70A04C28764F4AE4C12051B25
+B120CAD2E3044DA35C1F94135DBD69B10DE147321CBBDC814CE99982AC1D76CE3D3330E41AB31F3C
+76BF89B95EAB81AF3464C732D5B1411D97DB36C9063537F64756F205B16ED7058E2CB1D6946C00A1
+A0CDA9EBBE924BDA6C7D7B605C514A98133907B793C74CA858E82DA3519188CD974B34DAA74265DB
+5BC8550D5F0B1173ACEB87458BCE2AB1F96996C811699A0FE4A9B849D39023725E2B1EE7E426D30A
+6C5C75AE6BCEA6DB41E4EB2035F7F924E6B9F0DCD00EB2BB014222E55FE387FBF5B9B7C04F4688D5
+AE3529FDACB38B5EB0AF5C3A874C1AA6B17CDA8D1E22EEE05A3DA88449200D3D0D002DB86F6C51B3
+37C8E19F338E7BFA01E1202612D50E210140947D5F350E84F790286C3F679A5D7E43BCDC337265C2
+631527FD62D598B7CA1F5835C0441881B97F5197901ECDC4F195BC665A846823D2E41417373F8639
+567B228FE7B73D781F07A361AA49C3E9D80FE5B2A32C4C1E575D194E841967B08D10405FA44EEE28
+47DB9372C5CC931E50469532F1BAF577F680BAB4E30B7E1CFFA8574ABB679789F69A8A1BAC07B7C6
+4EF5CE5EB00E97B36FBEACA9BBA4A13B0293D34BDBC77AD1FF88E5744AF009823BC262511C4724DD
+585E7E17D90F230F7A5861B0DFC42F0B4E49A04EE0EE4DADB908479DEF8372F334C53D2BA5D855CB
+39DC7C9550F9D0F7F77E82D5A59FBBF34BFFE92DC9E6668B68FEEAA4F20053433D6749162BBAC5D0
+D428DCF2D58D49B127FA2E674EDC7D3613B1342F4D0ABD7F4C5B049FBF78E804D5F16505AE7EDCBF
+4D6FA08D72890F5D55199034572AB4B0C9A7E7F6F5A403198864ADF113CAFF5BF9D4AB5B16F81D0F
+C2188FC80875E10034D12E30C0364F8F72797F1AED525A2712A40D44210B813DF5A29C84E9F6D51B
+1D60A5F6F938FAABF878D29E6AB252D95D05FC1ADF5D4CE1C9E585219112112BC6CD5C766411FBD2
+2731794B5DE0A27AC57D3C57926807469C360372BE529098C350EFE2154B87F1205A57A0B04C5206
+CC4FA66B8793BBBE492CC3271FB4F90A28D0066E0D7F63B8DD01549A05AFA5482C29560ABD628568
+75CAC16100087540162473498C14087B29B86B7BFAD693E81765CEC781F3FC80E9C7B410E9B55B88
+114191A1703C638DFBB469ED1DD8254B1407003A319CE74AD419B077F17047A01F0BC0AC8507191B
+F72D77D9333C9DA8C9DA733EFB5305F49CB8C7BC451321ADD7D896395D269DCDFDD084EB3AA70338
+6C0697E962929651164135C094D9BB1C9B949D5EEBD3BB17F02C98C813CCBFB23C2C26218A2F4C63
+9A8B9DFF2C29406037F91938A5E1227310728428B56F48108CDEB33BD3191ECA89F947271983DB77
+6B2BC897A30EECF2601EE3B2A6F0E135397622AAC1F2DF523CE6E6BC720E13CB530CEF4AB9C8273B
+D3D81563AC8A8E6C44A195112DAF824BC7A72FCDC4E129A480717BEB01085DEE65EE4344D0B41EC0
+BCDF842566B1D9F5353B1F6A063FFA6CDB06EF634C8BD5A7A63F991D178F56EACA653DD67685CE49
+E98C7554745A4AC533217662D23E1D6937135D13BC2208EB8D50560A2BAAC319DFAE478B6BA4CA5E
+DA20222F0E9BDB0806320ED1665B54A347DE0C42E9F77842DE4D188E7E824EB2F0D7AD163F05480A
+7FA99C5A603BBC5DBC843774CA66E889B945054C0ED0B1A4BB14324EF901B023C208CB95DFCE9284
+89789690CC45BAB97BE449F8E2F5AA9276C0571303E9788C46E7F789555BFCDC3FA9ED8DA8AD9BA4
+8B3AE09404664391E63A989EF1E24BB464043AA099E4F2D796E352EB277106D8D81BAF2F8562EF46
+BCFD1E0047E8018CBD973021DC1C1D821AF03F083F0B088A62EBCF2BF6C5B0FCFA441AAD1625FDB8
+34F943DD47A5A42EB3E9A5B49641F797C288B799A64897F1346070461B6D535E0C4ED099199C387A
+3176AEDC7DA7E7D9E118E55565092A36F7C74ABF281720C0147F4E4F37D49436466C61FF12764E30
+43D8A6D027E70537164F0E7942F4ACA42BB2CB136177EF7197E76F49AB403F741C0EF902FEBC471A
+D6C627424320A8C3A1F04C310C511B3F91C3937D9ACF459999C18A33F2C852EC38CA806599C728C5
+43714018C65E2C5F430F6270AF52AD71ED38813B60440779455F9529A4A1623CB9F5422B9216F9CD
+BA913B9A1CD95DA225E254E8101216085020660509D03A034B5D7E32E3DB5E5962A9A27711D4C3E2
+9CD84057F7D0D7E8000947AFE896F8523253391D2E11FFFE523366B05C532D5629A90741EAB3D4A7
+31D3F6D4F03FF93233DDF88BB1913ABA22EB9AA6311E3144381DAE29BCC8639958EEE59ACCFA06F3
+5DCCC63E0609F542F3EE5DFB1CF718CA3F328455726F8F65E23ACD970E4049225998371B63E35AE9
+8DC54D8329B8DB0901FAA63129EDE21B158776981D4D094013C096E9CD020315D123C03DEBA21E97
+E4B584B4BC0AF25F5DCE53C2DC0F3E61F99BECAB40799478BE7F5AFD7F68E23EF50AD6645C967EE1
+1206B6E791769428ACDC370D64E4F2B3972E0E4F442297199350663D6E772FC6777A9B9DE215273D
+082CCE4E8678FE9948DC8D5B0E459CD02F1645AC5620F3571A40B4D5A17DF5CFF48B6C843DDEAB5E
+BF58FE13D7DA08E8AA7902119248B3B151DA583101CF80853B0150FE05BDEDBFB50A7FB0F65728C9
+3B9DF48CE8AF1DF1FAC25C1D58E1AD30274A00EB54CF2F16029E1AC0A0919C0655474B9A6936AEE0
+FB74BD185FE7D70BB84786997D34A40326A74356A4AFAEE67B6B26D1C1A7BCFF8697B55C816CCD77
+312C332A55315DC54F9BC0A0F12500E0A76B3936292A3DA2DDF5AA8CBB9B5DC32EDACC4827D684D2
+74E65B8B76FB2C2B19F7D5607523FA953E34BB39032C05B1C1244304606C55660D3CA8607E764EA5
+B03DB7FCAB5CF7788C6E60EC8C449BCAFD90BCABA4132B6CBCCFF16784FB59B36B77CF0A9EA572E4
+CA0A01C725A6CF2E4500CDDF5BACCB9094D48925434F044118CFDC2696AF5FC0CAB3884107ED17B9
+BDE0C0104B1292A1F8C99B06FC4A6360B24480BD59DF0488641899B0F42B1311B582717BA7ECFEE1
+4143654B5371C8B9B2D80685AD38D897AD1E64875C28C7020A84FBB3A3BBEE16617DCB9BC822B7C5
+9C5A18C0CF7E80163ADFB7AA03B7CDE8497C1697D90F2ED90F813095C5B91657FC294EF0E341DB33
+92ED860CB2E0AA09293D0F99AE9EB54C761CA2DB1E51E1CEAEAB276C7BD916C68510D72D9A67468B
+09B3C39A7815628FB126CDFD5EFF59CC8184C0D35A5B5960F824BD175495DD3EB12A4E96008CB13B
+8C5745303E66CF8608FF27C4709C1D854EB79608E52F068FEC0151A74C125EDEAEA555C198FC0802
+7BBBB802835E1D435077AE4B1CCDBF722354F6C572BEB1376D3E342195FA80AC9722EB2F46E44DE0
+5F5A227B731B8D4A4B6EDEF04AF2C5DEC2EEF8FF48C5B18710ADE3DBFA0C956505B6DA9CCB7CBB83
+4DB6CC754948855D833670FF0AC42A4773FEA8322BECEE04CA74AC2D66855132D11A51524488C547
+71B5B7A512796D7D7AE0F9C1FBC9CBDBA0831074F4D200349D0CA40537B92496692766F020AC43AC
+01DB8B2AA2EFA9D21732BE3A315F6CAA402BB2E61D40DDEBDE11276D90C2C601A935C168BE600464
+76ADED15087D54A14C68EECBBBB590927C1E10D291C9285334CB0C80EDBD392BDE4D535EB61F8E76
+41F58AC1DF5B1C5A5D91E3E27E05CAF7EC97ECF0C85B6425197AA856521ED701E5AEB82A7F52A8BD
+7DC97D5B3FB5C99A5DF84D1BAFF89072922509D76BC6EDB15CE5F9EB8F4154BEE1E82020240283BD
+C83A8E49AA9A2649B7955D5C058F2818A63BD0BFE7EACED4A49063C489A626277AE1246F721C9926
+E2A2B6C31045FBCD235F3CC58BC4DD6C57FE998EBD1E9FA5154652BE3A1685BCD2EFAA079A3293F7
+8142A6473822FAB627927EACCD61B3E99C3077103D2D19382BC7EE15BAD0FDE489602D055A01DBBC
+F91A566974559D1B477C209416887053169C3F8F59955BE4DE82B60558CC9AE15602A93F029F6B43
+29E0E62A03982DB32F5229714EFA1491A7B24AEFE18FEBC2C93DFE50B3F641B51BDD33DA38871BF5
+243C17502D00AEA2D9E9734E80A96788D4CF5BC12A42BC386162FC88A7435EE13200C1C2C6CCC5D2
+1A03941007B4C4291BDB711446CEAF27148104BB240357D5EDA0EA5A5CE27D4A83909D75BFC05D75
+F10AA74A6DE37D7DE15C1DDA3AC3045DA6CD48323D904E716B445E5E096FCB379353ED70CF4B6FAC
+102C762711079EFAF13FB74C9B47AF75F3F6BDA2A4647D2AB47ECAB64DA6CC01479F618E8D2D0A36
+45445E8744683CBBC560D47C98078B84206E90EB839B02D37C852B8E284463D4E4D890203C3D5B20
+352110034EAD6BD7F41456B807E1DB1631A9D499E52E9D9853D86728B1A2E511F40F8CA1E4724A0D
+17ECD640B52FF6C66E28693D89765FC391612E5889E77423EC85CBD0A038B6BA98B607701DC0C4B6
+6B3B28C7790A1F1EB8D051DC98276DD9CFEFAB3F65C1C928E48A060C992B392A43E56EAA6DED896D
+EBCE71F8245BE4687F2F1B8FC0F43ECE8DB0BD0AB0811C5CE73CBE336023A0D66168B34A95B4B0A7
+50B3BF1D197E3C042C7914FA731D7831AF798E9429571CBB977E6258244E84701E5FF91D608F98FC
+3D68A4EE5B81D5FF38B6C184F6118B875F022B4CE207DC7B37E1452DFDC591A3E506AE82C7E7BFF0
+011B0A3DBD616A993FBF878FB03B6C9F2055A2B095D29361F8253C2623653687FE0AB98078F6AEE5
+FC2C2BDE0405EABEDB3A33EB7F04CB6837176245F190C6BBBCD64522B12FE7F9CDCF201A1AA8A19A
+7BBC4AC064B4958F44AA0F8DDA23835AD28A1FD0EA105DE2F395385DCCFBE2261DC5A89A23AF606A
+3985E5038706B1FE0910400E16BF008F250F3BDE3AD806C735495D499F16F99275010478FD2127BF
+7CEDD6B5BD505FBE9BD0065B4A7090C9D27CD5B36C3AD33E1B31EB6D44E375003B51B909DA50BD18
+218418B3CD22B43278B144BE78406EAF16C7DF6B6C1C6238004AAB73736B38E168441DC16F9A5CF6
+0793A18633BC43D78674D12D38CC979F7CAADA6EFE807CEA499CB9FE616496682A66E04BBDACE1DC
+112B2156B9B0B20A58A8CB43FF0EEDB99805234B9A5789762AC7D65F5A319C33F4F7438CD15E06BB
+80A7A97E976E8CEC23F4C646A5821880A82B2F1DC27767F090997E91488BFA15064B702F864FCE65
+05D6CEF87D2A0A12B55BA189AF269811E3B8B850C8401F3906C080D32618D9698A766732A40A9FC5
+A94E5BDDA3D028D823D6B603B6D17DD046DE181FD989EA0F80B4CA62F7973E4DF5E032A31FE6BC8F
+5CDA678D4A72787EB8253EA5882C337CDF9AA3E1E7D9536DD09B047CD8962E773F72F6418A3AEF5A
+289B3406C152A50CE7BD4B493FFFC27F6AA52F79EA67E362FD92559AA4F94A2F787F6C735DFADCF2
+F08AAF98B80C53CA5607A94F25F04AA65A70A75937840E73055B3D65FB054C63E2E48E68488C9315
+A13EE949E03E46723C11CC759D222CBFAD2E1A87CAD779B23D38F7E2F660DE1388EAF1CF4D18994D
+75C6CC63F187FDB949940C18B537A0AFB12AC5F67B0283CA5EFE2E764C4369104B9D3B06490D1244
+C41D6085C85F1106082EC9DB84586230511C05C82412D2CDF3DAFBF4759A775628878F997415296B
+C416AC8352A6C6988691FCB831CF95C10BAE691ADB3BA2918B35924BD5C3ACAD8B137397B10AF82B
+479800FE16D472CD0CDBDAAB4F882A0649CF561004B8CB7CA32EC129D0A415BE6CB91DA2B65F44E8
+0D138808A127E851A7FCF927E99DAA0EA2D626B77A16C72E37F058A3B882FC4955DC8CB6312434BD
+3BCED75780B13590BF4FE8D64ACF0371F9FB1D361B05025852AAB9EDA1A0C997CFA58052C454FD45
+1E6C1F194F4D363114E312F6DC35BBAF357A32CD200A3DD9654155134259887D677ACC44F89AA401
+CA27282DF7DC3F2F04A108CBEF2558DCCE28BAC2D87B8D5B7181EA927F61977764F882626D4AB338
+D95C9477C54E9C36012A3CFFBE199EC8120A99D2D70A21F9D9A0354E4EAC7947990E8A6E0601796A
+AF6F14E758CABCABDFBD8204A8E748A3E5FEBA570D36E2BF474C0083229A63F96114182321B2EBE1
+BC76DD193724C4588C1D39D184C332FAEAF4C629F2B3B2F49996E46AA6C9F497428BEA52D58876B0
+DC07B460248BC85CC16773A5DAC36CDE8B152D96057F4EFAAF8B1DC10022038577368057699B3A37
+178A9F1F6C6CC60BAE820B7ADD0717911BD23A6DCDADAFA32473491AA80CFE90F2A77E24CE2826FF
+77B18B869C33FA292FE01D6477765044C7D14A548B28B1360125C6933F05C58B0889390537CDD16F
+8E967E0B38579449DFC1E07389B7069AA8594C5103465D5041CC929268DE863FADB6925B350AA94A
+27D421FB7FCC81C6B35F906F12246B7A5140511A97211BA9BD6831A508E963FE8BE961332F557808
+488F06EAD75E86D60DE3FA2425AE8439ECB9112BC3E4D73747C1C8E87A649919827049832DB0BF6D
+A8C85C9A2592AC002809070900ECAD52A56F1BFD456AFE066509694EAC075788456B0B0BDD7C192D
+321E9FB6AADCAEF00F570F22CD4A5322FBCE8FA98FAEB681940895426270BB4319C11DA67D88552A
+7373398AEC5DA7C9CAA9F3B34581C6E968DAAAB2751CC012199DD897B448986CFFBAE4D412BF9ECB
+F46742715A9569932516259D3B3A5431CD7028E42FC751C434E2B714C718202BF02CAF9B8A2075DE
+922322EA7CFA605C8376FA958B8FBE43031E1026FBE6126A3775F643EA67EBBD97F239FB3C435526
+75CD08B19CA5EBF53B40D728556B4481C7F73EC71CAB0F89E34D60C69B272FADC22E8E7BDC6210DB
+09FDD913E209F49FD28E8712B8508904620250746CA3B21B026EDAE60A2822F59E912E626B93E0D2
+BFB3230DFD0E54E91A1DBA25A609B64D41ABD897A5D21764C351E85F9E87BEAB9E645149AD32AEEB
+B3B1161032C701647115F98C1C2AAECE871862D91D321AB90F3E923B1FDEE00D927F897AA9812373
+6536E2E0700F10053D7E6C589BF66029D794883EAE4C8228941CE96565B50D48887B5314A2E55379
+59638222A6CA54C77CBABD460DAC11B063519AE4F50D93DE41763BA7CFBF4C7724360E750478EB62
+8921DAA065858341958E4F3EB5966C6DD77C05EEECDF4B5F6CF19AB507589B4219377959BD258EC9
+21C34FE1DB003F7D0FEA3E2FD6F5DDB0A2D62CA5A2CD3C7AB457DFF25094EFE04A9E1B9CE7AE3F30
+026B1CB039228D309A22899F6E9B9BFF922E117123347967D7C62C670E2C74579C35989925603022
+C17B1DCE378031ABC9B4B437C7B6E64620932E93189754C01D4B280B8B08699B2CA953AE4823BB9E
+E34133C5C95B3290E1BF010705AD852C72BE87291E1034B09F44A95B6A2F83FEE8841DCF661770AF
+44D0AC7F9CDB280939FC5D953D525E0B41B7BE188D5C794687330CD770D24D9CD53B895A253004E1
+8A31BE4E82B384
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+cleartomark
+%%EndResource
+%%BeginResource: font NimbusMonL-Regu
+%!PS-AdobeFont-1.0: NimbusMonL-Regu 1.05
+%%CreationDate: Wed Dec 22 1999
+% Copyright (URW)++,Copyright 1999 by (URW)++ Design & Development
+% (URW)++,Copyright 1999 by (URW)++ Design & Development
+% See the file PUBLIC (Aladdin Free Public License) for license conditions.
+% As a special exception, permission is granted to include this font
+% program in a Postscript or PDF file that consists of a document that
+% contains text to be displayed or printed using this font, regardless
+% of the conditions or license applying to the document itself.
+12 dict begin
+/FontInfo 10 dict dup begin
+/version (1.05) readonly def
+/Notice ((URW)++,Copyright 1999 by (URW)++ Design & Development. See the file PUBLIC (Aladdin Free Public License) for license conditions. As a special exception, permission is granted to include this font program in a Postscript or PDF file that consists of a document that contains text to be displayed or printed using this font, regardless of the conditions or license applying to the document itself.) readonly def
+/Copyright (Copyright (URW)++,Copyright 1999 by (URW)++ Design & Development) readonly def
+/FullName (Nimbus Mono L Regular) readonly def
+/FamilyName (Nimbus Mono L) readonly def
+/Weight (Regular) readonly def
+/ItalicAngle 0.0 def
+/isFixedPitch false def
+/UnderlinePosition -100 def
+/UnderlineThickness 50 def
+end readonly def
+/FontName /NimbusMonL-Regu def
+/PaintType 0 def
+/WMode 0 def
+/FontBBox {-12 -237 650 811} readonly def
+/FontType 1 def
+/FontMatrix [0.001 0.0 0.0 0.001 0.0 0.0] readonly def
+/Encoding StandardEncoding def
+/UniqueID 5020945 def
+currentdict end
+currentfile eexec
+E98D09D760A3C22CF119F9DC699A22C35B5B35ED6AA23593C76D54CABB5E942BF7D6DD84F1664B89
+699C74B472DE9F8E6DF925F6C4F204E9F1C639B4DBA988ED2AC419FF2B2BDE605B8EE3264EDD6641
+2D4F21C64AC522BDFC7C5502F9C3F3E5592B3B2093D33C9BFAEDD2D49E89AABAA832E23F062E91A2
+5032519D1868816E44B4E0747795003D7930299D6E1E2A5BFE0D595DC97E140989CE81D8D7F852FF
+9CDC7A1B1B598C69131DEE005B415805A16D8A123E6A2261C63C769D2F4B60FA2C438AD7D199D8E4
+5F7E7C9A605C8CA14E21FCD81C9A515FB8DB6F99604534D06EA9D87FE0FAA852899C9D0595C7A97E
+6C55F79FAC45CD38E87B10D210CE7501E88C8FCD3444354365FB893A12F596AE2C1E70D5819EE0D0
+87D10BF8DA96F3DABD5405D28C4228C6C31BA4052464859640933FEEFD8071C0C84CDD829A9B1D0B
+A01F25A4D50EE2EA2B45160CA6333B2D2800306ED2BEFDFE155E9D9F9342EB8D5B0ADBF2460CCC98
+643FB1287CCD28ABA7B5CAB92EC39EE2E918990372B16F8487EBA30EAE88708B6CF33B6C015D8096
+C7CFE2F139F52052E3925C0D50FD64CE68236D59CB83EF56BFC584150EC38065059F3308AD6F9A99
+F83EF4E6CB13855C8175E31417D190D036B387D3952344A950F4D8C7781B307A094DF1ECAEE4D2C2
+FD747BC6F7F9C6BD0E90C19294F96C8C5CFE88FB34C477574A1B1630B8CC591529E59B20794DA32E
+61DECDA8ABBD1AE956CF74012AA01D42EE01E861B0AA6897C864788AE59DEF43C493246FDB1ACA55
+4C12594BC7B33657A9ECC9E3D1472EF826073F632BE540C35FF6FB40566773F3BB2204D3A579A08C
+CBC844C14B18C350F003B9DA23A570C362D6003893CA32F86F59B829C78EE3188B6E3F7FA81D7F62
+2825C639638DFB78B7AF1F500F5B450FA54DBFA5CBA277C794ECE93275A3DE0B452FDC8DDC2993BA
+A42F28A636008CDCB03EBF71BDCAF35019778993443F88412AD2AD0D7155A3944606463266322DBC
+0244B07DA1E9C27A27B59664E8566D7A54CC03E995AAD008B0A17E2C3EF61F720CE7F7788599C4E4
+4C709CD5C31B11107F16AD70B17B9AFE2E8CD922A7428DAC171427FFAF51067307FAB0ADB530E701
+FD22DA22C4CD3064067BD4F6089C4B2C87937DD426E4E9D2F60E608288BAC9056554D04947E69200
+61E379CF5E81BFD32FD37EFAC1F61CEBEE551B0851516471A7472C60DF89DAA9EB1DC5A67E479745
+3E69B9E22BAF4E3CCA4192D603295B018C4AB69D18DE52DFDF15E96B557F290A4B8C5B1E7A6CACA8
+1F2351B97ADFC36995ABA43803A6E5AC04A3C93495F6D38106B8B144449C07D1358210F9176E1565
+72363CFBDE576BFDF99FA329DD1346E83F79E06CF68250CA57A68931BC7F342AD295D0CBA17AA95B
+B8EEB53EA6E8E660B814E9F857CECB14F44A43288B69A9E7908D55BF19E844359879D28CAEF1C38A
+36420185D20DFB32C2E002202800E8EF3D67C5D50E919657CA958B538D537D503444865331D79BFC
+40312068D72364503BD0CC84B5F30A74D8B5B6A26AF2DB764564FB65A6BA8F9051AE2B4EA458D46A
+4569F30C6E77DC097356770362E6CF3F1661074778EBB44FF7D1E3B64FF75E77E11FE525BB121C65
+46CFD13300CA1F02D571B82A5825E6226D14FDCF27F06D87452A8B6C5DCA658535CEE2A795E58137
+D48E566B69D53A0C3B766E84C51EAA221C46999CC8065ADB2F129D5B630FAB1814C0C33B5AEA0EFB
+B6E994D80941B53079AF96D90A0B924F9B0E319BED9836B8F9053F868363D3CA554CBB181863301F
+8CB940872ED5FA7BD18CE39218B5AD8AC57D0F752D941076B1C64D99BE0DB86D7A6D96510D772EB2
+4C587F11779BD21CFE5BDE1F29C1EF9022B2B8BCD7F91153C845906722477829C40111D810480F3C
+F62DE8DBA7FD86CD236E656618CAF6FC46827FBC4898EA7672F8C9971AFE43E0E01EC8B77D4AF48C
+BF1210E98C1DB15C16D149BFF58AB0270CF015B107A3A50F5DC8F37FFB92EEC8CB6778DDB7CE4AAB
+C464C4AFF654223006A550EB52485A23D2B4AA7198D3CD54418102F1E9A4FBDE37B841E56F5C2C53
+966DB9B66B000E4588282E3FB80C2C519339F0002D2F83C979EDC5827A3B3C8EF8810A0F9DACB6B9
+998E9AF6551F56313DC4011904CB979AA2D32B11A811BC248141E4B9734D9FB7982A5671002D8279
+CAB93ABE057474628DEFC95D43890DB1ED34CFA8A20BDC3D874E7679A396158E522ED0AB969A4E3E
+C7E4474E192590504D54DEB7B260B7935C4E56548A7D121AC1F741F8CDF259EA1B5813175A77A1D2
+D30BA26F65EB765A04C09ED51F69F41551ADF399E6AA2FC09788137BEA4913F17B8EB838C38FB272
+1FDCB55FD65697FF0B850E7D3D1CE266BF90F7EC06A9A0876BDFE767D3A918B092FC78C775F945CF
+1F96E859C03DBF630D9A940939654C3549D8F7921CB94EE23D5A0535DE9DF31EA0F937F860B4F220
+A99ADDFC343D7CF7BFA0B803C12C26403F0DCFFC8EA786D0D8A8D9C367419CA8AE41190CE93A8086
+583A1E6C9D70B612C84D87D2EEAA71EC2DC12F4CDE6A821303D5F6A9BBDB7EEDCD289E80FA3B75F4
+7F481B50719DCF4A142069393593B9AF9CCEEAEC56A35B8787193D7C88113E9E1E221D151E093B01
+9EF89F6118BEC4735103CC8003CC5AD1B6727B3226CD44C497DA7052DD681695DBEC3397F9598C91
+77701C73BF0594CE93F23D50EC5BEE2FB9DA1FC966DF148B27B28EE3C89526DD6625E2887F9FA076
+7C127C609EE315626BC14D274FBEA56528DC06A27B2D476D46E9E7916590B156A5DF04A6CB15E362
+45D77021767B6E5BDFCC679670263FD891446C3371B11BB6E1DF60F960AAB4149D7753E6A5C33810
+C42C8BFF4E935003388506F8278BD7CB672F132E065AE684DCA0B9064D01DD620E7FFDFE04F14277
+EFE8E60159BA0FCA3FE2F28B902D4AC275D19F0AC6971EBE827C4A232D87650D2688345BCA78F879
+077114F0463C5F058107B669566F8171E4E284D278405580F04BFFC9902784216E0C9A17AA9B2935
+E66E18A783F723BE044389B7E9D62AA36818FF2EA406C3C1A9D2F3436F3EE7DB8BE86AFA8DAA6A4B
+1B84611350D8D27605509612B515E16AA843164D5D0805E36A2B9EF74C5F6A0B9D59A04B55697123
+27F4B1B30E9587CD103337639967CBDC655AA46E80D2CFD24BEB50815B5338E522B3A7AFE8362AB4
+F05D8BC52BBA9C5089ADA8C89529B0275AF422EB540D31A938B8740860756325B966B36817115213
+FAAF92DE63F6BAE1E0064BFBC5588098B61EB83C71F1C2082436D37DAF1ACBE186FEDC4BE7C1233B
+6F18BEC5F99002D21CB7864E4811F7AB3C03003E1E4490AD1AC793BD28FCD5EF0E6CC30EF39A08C5
+2F71939B0CEF620DC69E31E39D6DB969049031B0C92EF2DB653D97F370141456A52985076B268652
+FA2648C792780BAD637C4D7581FB2D62011D57E293719487CF2D1F013CFAA532E1C2D39178D51272
+A6AF041440BCA174B5CC902BD7390C7D3695056CB4BD7791F9FB6D88E7A70DEF2C97869F5DBC5BD8
+23C517C7B7C39D624DF627DC9653EA5347BFDA80B723F05F6DBB4C9EA501D862ACE05B9DBDF21B70
+56FBCD8C6D4B85873DCEE6166C8B5ADC0316CA12D9639F361B15A42F00E1D62EDBCA1111972FA0F4
+5758BECB31DB38316F3CDFE1B41748C93ED58B67E9B57ABBED5924A6D53E99FBC9A994A6489A8BDF
+13EB685548B4DC6D62DA7426C22227D4D43B6FFC7B5EA91C896730253E8941AFEE588359C2BECF6F
+FC415B9EB6D31CCB0F6C7F85853E6449FA6D627A97A3CE8303F148393ADCCCDFA2FE085C6908BE5C
+3C05AF00A6F02840206C3253A559AC5C049BDDFD11AD9B118403B84DA10AE3C470CB9A9A2D1D7B73
+2F59F5FE146DEDA60AE750F551AAC934621B4470E1BC324C436303E25F81D0DC3188BE0D6FEC5414
+C20E4CB18952E12CB6423DF7124627ACDE145500D77A97A8BFD9CB50D1FAA008E2CE2B2505A4749F
+1EBBB092C347023714055A9B63353AF9E7FEE05BB54C9843698101F79888A91531773830C2C967B5
+88D3ACD2192883D5CE3962D51084FC653EAE2C5FB2DA41DACEFB5C76812D2EDB5B109677289CD199
+8D457FB1023A19AC67295BBC1A9A20A426B06A368DF3C5DD083CB1180D287F5500F2C635EDE157EE
+FCEEC5503447382D15C748C1E35F68753992E5C90F900DE54D18F8E1B355D1076ADFB1F3590135FA
+D1A36F028E44F48ABB149B80CA9A54614D467F8D71CB310BBC7AC7100261092DB8C5BFD39E0AC6BC
+2C9D6CBC3A8C05FF8A74CB21608EC4A4CFE4CBAA2D056DBA14206106044DECF59F957EF8A9CADE4C
+9B19D8D30DD4FDE6A9548E50DB51ACA73330142153FC36B69C1C8D5B26D0C689B7040E81AC2C864F
+D7C097C99BE5953843E172C97AB5684F35FB03A725A89DBF371F08DDF40A1531FC1B676DB0E1543A
+EC6E97D3D2E4AA3D5831D8B3C952ABBFA112352814FB6FAB61A0D680E6640F6AEC8426200CF61286
+F7422CB2F78C61EBAA36D47EC16D7FAF8B4AF31D090CDFA255D9D7C61D46CFB22A7D6E1758E71ED5
+67E00CBD8E8F468DDFB477F091A2F915627F22FF47B876544BC1F03B6BBB98385F009C20BB1AA2A7
+A78674692B8EAC2E3C8069B79E679338DA57F72976810F845BEB6B9ADD32B95D78E5E60F16DD1668
+9C05FD82D36A3115BE8ED494A74DD211D58A2CDF983FCB9CDC29BF7F0E29988FA23560EDF514BC1D
+183F3B2A22C09FB179B47E05ADEF48DF02F31C29875D1915037B19407764A4292FE44E741651A8E3
+BEB5F0D972B6327090F664417C84F84FFBF0AFFF8B1D85C822D90730AB4140C42A51AA8B1DBE4398
+4EA8566040EB8B341CCE23FD3F69DD235A080BA5C69AECB9BC732BC2D7D40617DDA6B79FB6EE40C3
+556C7DF9B23DAD89E94054B1345DB8402AE679FC4655A4A776C0150463F8DB2BFC0608EA1F124E22
+1DDAE6026B5E5D007A7E4A0D6B3B0CF3A2669E67C5E4F01551966A7BC48F2F4B6A87E740D8095E63
+F77C7A027F26B52F2299DE5B8A2F6209BCF3D31CB0235F998F781E5CC81E31DC424E008D46EC0920
+2951E5684804A0592EA47D6C788A20487BEA2EC8F2E6C1D7F378B62DB43CA43C4B366F8B4319631C
+FE9854F0E10321CFA3B01C873584863BBEFC23C72C05E695B56E8A52E89AA2DAB543834D34DCAC5F
+ED08DC51825C5257AE59850D101D84F4CAA1D29FC932F9E0EFFBF7A9A7F3685F61F0490CD3CC8988
+2DB52A757A6AF4C4E67B407BD2316B1C0FFE7DC54E43C87B874F57E4903334E2140B011484863CDC
+ACA331175F2CF3D72E0042855983AAF8853D3015E870FF0807014C31D55060DF3FE1FCE157324481
+2744AB51322444632F9AFDA6706E320FFE82B8CBE242A19DF00CE73EE48E25FF49D5871BD3E60652
+298FE3E8D400609E232E0DDC794C0579ACEF89E841B2EDCA50D51151F65E8C1CC3B01EF1870558F0
+BF5743718C3E068617E81BFE120C6CA16E0924BFC2541177D53671CAA3AB641C41557DCDAE1A3461
+47B5E999C4541B08B4AFCBC187AFD653D5B5F8386DF6AD8FE69E21BD0567DF494F736C6A184FA4DE
+48DC9F347787CA96E2E00A296C2DA05C2AD9BC423E9CA428D7F1FA12DC9353A302FB8C529AF8688C
+BB543B45B2717EBF8F6C497935F4F3BFFD285E0402AB7544B3CA4643AE5A8B5250ED987A95FC1F27
+5B9707ACD0641BD0EE2AE9758494F8D8A51DCE408A38AC20EAF0852D72D84D0C6BE973326793AEB9
+55EAC6FE0A2813A355DCD22F6F2CE56588D1C055CDDFA98878BCEB6A018DB22922D2B600A20F8184
+2E665DF41013CA0947C4237C2BD60A75E2FD1A3FB8C8FA19485730B87461AD466ACB02DF8CA24091
+4FB090B3D2B41EB6B8FF05E1A59D9FD668AF70BA5BB72778953BA55FC5F9F626043450E1D09BC83D
+8605098ABEF884639A37809A32565CBEFB3FF39EE53D6C18C58C272BB928E4410E361E59A50F242D
+69747A032617C52DEBBF62364AB5A96EFAF642D9D82BA679B1D70FAC10A4EB62FA5CFC308E86368A
+AAD7E75948F43598CD1C544A0D4091374D7E88D4522CBE902391641327E888E7748FA889DCE67ADE
+61699E7D77763681CAEE9B1CA8837B2F7EF9C18CBCC538C465C8E2DD34616953CCB6030A222C728B
+834911C1A179E2C770289407AB28B303E724D97F747D6134B425216A64C6E0B60F633E2B85300047
+E4C90339CE030A0FAE31E830C8ABA5AB3386A3B69267351A7BFDD66356AE5E57FB2994452993E90D
+E7C4E260ABAB93C37831856A650D56E44172FECA01D6C7C380F250B82473960D2A2A5FB6B4DA668F
+46E624ACF7FA0FD4490F485D640A3ADFC9F8652E7A38CE5799F770C3606DB4B8B947F93967F779E3
+A3C0572F13A5A187D31D7BD12A5C7BE23CB6ED6192086241B76C5BA6983DB9C93E4B208D707D3760
+F03CD6272EF3A4CE89B8E52E6AC5871A3D03EB975759AB4BE239E5EC7842CBB333E692CC607C722E
+185D3C39164DD320C6945629C70FF66A5237C0A9520A1FAD6EB9816069351AB0F135D90CC0982B14
+7D2294AE4A38A527EE40BE9CDE2512AAEBB590E134388BB171D0956A7C4566D65A9A041BE6C4F883
+6B3EC3D2ED1B48B566A783292B15B6127920D247D494F070BB20BEFF60640B11B276DDEEE49706E8
+B2B21BB40B7F00AAFC594C492C25DCA774E0B80D82E927448DE2E74A9D0DC7AC9260096EAF187B6C
+D6AEAA6D1DC4205B4411122751A5B22688404EA7C5861730371FFAC10F5AFD4727A0E402AB5EA757
+606B75EB86A05E8F774D6E430A1A3FE2A37EBB06700474239FB1CFA05EE44B91B82244C575B52E7F
+AF934B04EEB0D933FEB57EBE326D75821C8B23EAA85B583AED4320B7F04B9F2DC591091216FDE52E
+064BAAA9C2C9D9714B95A4558C21F3CEBE624B5403B31508F178581AF6863083ED762F1E2E34A45C
+FDD71660D626FF8648F5D6C5E580D4765A67FB6159EC8077A9F0A88038C8D3D7C77FF0926E2123BE
+874F7BCAF129D55A5B5960F824BD1728ABCFCC51D23936DE9A25C408D786E44C3A2BAFA4423177AD
+060D21D38E15E23EB6FFC0B4120E814695D423EEFC2744A1FC81B4DF89D76F0A6803D8B14E75538C
+AAD03A72517B86514F6952F6FD619D9E910D980F00964DB325318C045BDF79647F453D4A5CF4E61D
+D5359782827229310405FBCF6107C3AD9DDEF9A9A339D5D5A6EB2E7838A0A43221BD62CBDF732DB0
+A638A52016FB35BA7761AEC846A023D3BF2D1BB183543E81EB7CAC1E5970CDC6F068C5EA118C7AAE
+528D1396E6DC939112DA4460C890EAD5C01BDC438F5BB734218BA6270ADD0DC1778FD8AB16831D6A
+302B814A1A44B07EDC65956C9E6CF4875DF521F3CE5B422F71081B6D69BD270F739095C9E81C0377
+934A8BC6390C420C4E4CDD9CF7E32544C68D884E15ACA3BCC07FC8C132D8FB9D752C15D75C52C288
+57E2EA461A6FCAD90C56843513F74461F18D7164BC597A28AE4BA7C86EE1703535A9B9ED50122627
+71FC12F102E800E0E1AF7BB46681BD2B14B614CEA91B7B2AAA35235DE76C0E113C92688F8EC81277
+D58C3406778E1EC1CC15F1CD9A137C8FFDAAB99ACE3BFC782916F1A877170589A92DC921E6740A22
+B84DC6BACDABCC76E64C79E3A588D80F8F4D376E1B426F15751CF7391102102F0AFAFD8B22DFDEB5
+48AEB5F30B1673023D22054A13391A0EC08DE6E7B685A0D031AABF20B7C62187C0284892D5EAADF1
+21BA28263EB863D5E36EA9C06A77CCFC0E17F593961591F84D82AF823EFE41044C8D606FEF83CCC7
+B0E961E7994DF8A3CC36B209D953E250ADAB8D22D7F2B4E2C9CA39EFA2D93E56195C1560E30A5190
+CC5B17FAEFCF250DF79F6B624A4B917E11C332222FCCFEC4F6A47BD9E75DA9854FC3F7AE554E91ED
+DE144D7AEF38A0E3EDB5E5A5626374DB94F022C8CF549093041DE00D7269B7CE544E748439BA2870
+718C08E58FB4A77D93EBC04B7957D272AE1601D41BF85A2BADAA0DF73B0D3841D4839C85677FB2E1
+5F1D6CE592669FF4BBC9C69DBA334DC37706F2F6BE83D5863E8CD6A30C08640AAC4C233684E66B4F
+E6B62D4A8BE9D531E47BEF5640D9B5C27D990092BE1597F6995C8A77BE9C18AAE6C1CF130775DDAC
+41D34438FC7AD8E042CB56CBF2944932EBA7D053E9376FF398367450E35A1945FE23E05C921096A1
+5454721FFD0F429A3E06DC3ED36F1C170BE79C66996EF8337AFF85B90C5D3A4A94455AE9FA32E211
+7A63E59001F052D5F6223125BFAFA40901E98960ADF7BB886729DCA82FC3B8CC52B37FF2517299E1
+D769057F8154FB95582F02CB0BECC873A9C71796ADBD3E91324FAA94F2C41CF57C30B5897D031C02
+D256C909E080E70BFD1F32E69EF67031138C2DDCD1A8E4B65E485C23C3E450ABDD9815512D6F34A8
+4B9DB715DB2C7A93BFB424316E1AA44397749CB01088428F149A3B4324737ED9957FD388248462AC
+1B2610D72BF5C073ECA567E7385CC959E37CAC7E05470160FFA5A9F63B8E9B082937E911586EA165
+374938F492EDF28CE6020953A5B5CCEC7737F9D9CC8538C4339567AAED3794ABA3B9F4EAE65466E8
+E326F6C399B36355935FBDCB9972F10B13494DC25097FCEC5A6398F275C8C151558E74C5175F7BAF
+4155E36B733F75CF9D5C5979B0764F14D8306E06BA24BF791141E404C69F3F8FCCD91B9C58C2C671
+AAE7D4F9E5D6414E46ED633A5F78AA5BF04E652246A066EAD9E582B181CC196EA2D3CFAA383B5D0E
+4CAC9336E119C08CC6AC55CBFBAE147C623B400453BBF447E96DE036FC025624384359EED7C7D5F7
+858DC0521377CF647A157FC3F188DE5EEF094DBA125510FDE34C570D7BE76AB5DF0A28BF45DDAADB
+EA7EEEDB936332DFE93081E0AFD3FDD46BED08D6914B2EFCFDC41662A33B90B03D76D34F48D30FC6
+BBBB600E90E6AC7243FDF026762A44B4D6E4ECBEF48C9D7B696AF29EEE063E557D8FCF0F09E0136F
+45D17E608DA36E59F2AECF8493F8D62536119B5F7E1554DFE3F6E8D7C9A2C6F557D18B4AF92C9F6E
+050975C3B5C54F9B5F4E39D600B6FA2CD6DE203A174028CBB2A201AF126D1013C229BB82CFD013ED
+199D01E51EE2780FE896E01C63C655087A3E61A7F1029FA5E97EA1872F1B45F22282DDC317E17926
+7368CB52DA9444F6055A3C653659CAD2A1D8712BC2B1B32C1DC6906D957FB88524EE066156ED6BDE
+B8D832F9338F9912E29A250A8C4674E667C1C278B677AEC9972BE83CBA3FB779893FCB8F81A323AC
+91474BA2A2334A07BB5628E905C518E634F6761A3289056F83D5DD7B3890987EEE1C18FB2D379CC1
+905F1AEB3B3D2AD578F0D6C845D2D40C4BCEE3F71C90E68E5417BB8CDDD878D83BA80AD8485F4067
+E5C3CABF28AB56CBB219C0AAB8FFC6C7E192BEC8CBCA1459AE4450AFCC81B9548F40CE2622E5A7C2
+81F74DCC02DAD57EFD92D072318DDF05BF42F1EA8163071E23949B0179CF7DE64677CA99B23CB926
+B3E294194EC13397EA1DC9A5E1CDCD828156CD71F81B64167D4FB01E6002713BD8AC6F82B20CD369
+9C6CA4704DC5C65A2D66EB155B7AF1C9BB46469416FB49C1C7E17A30A5F045271D7DF3FFF2F42C6B
+470701C381E3456A500C6BB3D0E47B4D91C5F34B49BB6272F1F8698B307D89EDA3A1565DAD1C0864
+627560CF922DCF5B34C67860352390B282F95394AA2CDE0E97CE3ED39546A6AF1C52BFCF81A29BE8
+2C47C99E8050E4889E4575B75F39E662F2DB7420673797E2ED3D67CDA7AE2C15D0A0A794D57D168E
+BE13214E89E0209AB2C0EB7784E9491AEFA3C02D0DF3AE5365A0FC4AE023CAB528162C7A1B173664
+9DFADDACA8DA5FA18B7D6489E4229E9E24D38A620464A744A5C60F6F9D334B908706B738AED18669
+8A8B278341FA4D65A0A88680BA484694921512F7DE93337FC1C02BBE6E64AF2DAD07603279D87329
+1D1F4D39C1DD6D89C90F65240F4808F6F1115CA55B88E242565E59F3BBF1F10EC7B88872E9AE61D4
+4CAE185463EDFAF7DF63DE4D2207D307AFB61501892965170D2945846FCF5973A1D458607F50C15E
+06E5BEC715E0C156259AAA6C735593E5564F65F443B78CC7512EC35A56F126DF9D30974A40872E42
+65E1AE5FD483CFCBBBA26DEE426CDC4721F19C3FDA86ED7AD4FA1120F63669BEFE7002B128CEAFD8
+C63E8AC09943B6CBDFB3D2476A026C00A8FF81B1F651B97F310C82ABA5F388CC1DB5AFCFF5996D52
+52A6A42FA4D972E41EE56088F78CB966F9051171C472C774879AECFFF08BFD9CEA40D7C298922ACE
+64F28C14E0B81F4DCADE81D71DE3983D87D905192EF13CEE71B2D3FF1A88AEC671EC318917DF98A3
+C9054E372D22A3CEC82FCC217F47319A40900312F6E32B536B9E7A7FA0837EC65CCDB5FB0D414371
+17596CB39D9382262DE6E65379D3A9709B2CFBABF5FC5D5B352425F06F88CD31012A2A4147B112F0
+C1C0ACCC808CD625E0228EEF66661F70AF96D3DCFECD402700E4F6522AC9A856DA466D55C84F65BE
+2810A1565163872D62EB81333A698ED7B68352CACCA2D7AD38AB55C19E4F5582F75818302F5FDADF
+1DCED09D94872F2D48FB636C8E38C7563C72C771A08C6B1F041F3532BDB39006C89A33C09BE1E3E6
+03622D891F98010BF1DE5355F557A1E09448D486ADEF565705277B31B8BF2B86761E32631E3435B6
+88B79D566F1747BA456DDB43CD239FB47FF7B425EAA4C657C8EEC26EE01AED07CF916E77D53634C1
+37AEEA009C6B515B6342C54BE2C7B95955B1A9DA277A0ABCDA2346E88018C726F481F71D6011AA42
+F8852F2E5749518FE3B3AB668213FE1A05C10A1C53953D75312631D6BBBA01D418199DFEFF8CF548
+6109B099FE8E2F606165FE30F532C03567785D5362AA873C9D3EECEB20F1945D55F49B0CCAC84967
+59FCC7292E46938943C262D78F3212D3F9D0F7B103157F423D71B1ED54B2A603F4C269029918F238
+EC6828FFCEC66009DB9C9E59534EABB183F31D7AD4C57B1BDF0BD2CE5A421882BC10CC1BCE6A970E
+2B586BB221567CCA483989DD0B8DEC424C1D1FF042DCB7834423CF244EDA28D2D969B17440CAEAF0
+24A6119DB010CE366821AFA424D1B8299609C04148275AE6E5257A7ACB3C766C747CE99CBA2D703C
+F19B7CF301B634D8B613DDC4AFE4633A4D77BFF8E00CFB5E289EBBCAC90A24307E7941EC1685CBAE
+400CADD876FCEF7F6557EEE167D2035A05120293527700DC510B038A496BE1D5CBAEF24ED39F7421
+1A93AADF22214ED606A80582485AFE358E3A46D0671148998A3B3BE209467009B43400870359D418
+9A8CEB4D5866AB52D16D9CEB1EAB71C07E6CAA34B70E3096BF7604C22C40D5FBFEEA616DA3BABD59
+DCDB97D883FC8742B8267A16A99B7953225F7144568D566E64542C92E538AC140C851E5D295528EB
+7CBB49909B1CAF6409C9BCCEB325468FA0B5F7CB2987382616B477CCFE4F4AC79E4A6F7165363543
+F04DE5B6F6E1C2E910CDC3CDD6C4C92737198F892337DCB6647BD226C820AC99C65D8E7772BBB74F
+E65DCAA8A22C33BC168BF48E40A82700A3A7668C5A9A71E397ACDFEE7D556C5C19467B7AA69C260B
+727407AC837BDB7D67DEC055C1F45D8BAC61048C45BC9FB3CEFE7549EAA2992D2EDC126FF7A05EAE
+58613332A2BC1465B2BC0429162B907D65F793D236EDDD8D35405866D71B25F62DC4A7E06D4DEE82
+840ACCAABC0774F8A63E9C0F7FC980B3583E7A8B01C46590E3BC04EBA565C2EA94F057D964A78A90
+EA9F52ABFD70F84E44E434BD10A42E98C794065724341F907E35D3CB257161E01C7084E3A0166D15
+CED65DA7BA87DBB2EA33D39BD99AFB93D3548358D08330E807F8552CECF63C84F805205491BA3A1A
+622E70C232FADF3BF2DCFD6F0539158D3306506F150B0518371912A25EB96163D73E9EEED42EDC84
+D688BC7F7708D9DCA348FAB4DF62E5809BD094842D0A31DBB7C4B41F94D946810C5EC10B69AABC2C
+91A59500B2E5D37F4755DDFB7AE4ABF757F4C5BCF77C7F95E6A616646456FE8F18407080BCABBFA5
+7704287AD26222DF91AB2613951E2D679472F8ADF06EA2A20205EC19972299A78BAC52114334470C
+5F5890C2F846B4C6042D73945127F2E3910ECA1C4CD7A16EFE4B4BE38A15AAA710682C3836A8CA83
+FD384970139D8B46FB0AEBB002DD224199672FFA02250FBCFA4E649E335428FC71F50F45E498419E
+DB0E970F46894A48F65580881C9C4250FCEF65C9B28699408E18B26FE6DB7F1CBDB767564E73CB59
+54C6D639CE33220C894F36E70F71C9F9AA3FE2AE0AA0E3F2E304EC5ABC661675CDE2E70519E4220A
+E26FBACBD01D5169EB844750753E6CED53E3678FDCD08AB93E10067E9C64F38B40B76D99B6CD92BD
+F4155A1EA5CC824998B59AAD06E09E5F15EBB2288D66EA71B296616734FEF2796F07FF0D8B047074
+A1111D68B99C2B70FC56E74A51B062F4998ACC85B1943C9477E436E5CD7AB18DBC898D21BB93475A
+623BDDA71D7B895BA2D4C10F4B90BF335126F4FD57D73AFA50170F6B3C364922E551D40E35DA75FA
+891762FA23401D39260F2E92C7807C746F13BB35CEF9DBF2E76E66A72FEFF095DA482A4DE8A42091
+7065736CF4DE904FB52E649A32255E2030A7B31B686353492F31C064A3C4B0448C4BFD44B8E15384
+FD809B8761EE26A7DFA1758D57CE4F0BC376EB2B3833534B15A83436BA553955ACB5A7A66796AC5B
+92DB5388BC53EFA27508B08E82821E5CF669BCE52BB860780F749B4F38ACDF5FF12726BF3EC2743F
+01014CDE96FE6B4C40A034E9EAFCA2A35CCC776C2669E6AD138070A40F48ED79136D7FF57E993E09
+B81C543FBADD350FF5B5F7A46F060F88E30FE2D8233832D18B6C323EE017EBC1DF5C838321CDC8A8
+4CABCAB20B60A1A3AA028F36EA6E87C850AF8AF7CD50AA6359038BFA8818821D02CEE8F51DAB8C05
+F7AE9797814D97F3DB8CCDDE45B21DBB15CEE292FAA534A5F317B357F4091F3DA357325B8B9F5EDB
+45865415973C143E5E5BAA483FBF2D06CDD4246675EC58B84C6AE65CA743117FF00F229243772561
+31A7F2BA26A9115AFD96C18216CFDF41B7220ED0CB3FCC26C36380007B382A02AEAE428887DC8BE5
+FDD630AC57EE3DC156C7B8B29E687F24442E35CE10BA4087295A641F7139C831F7CCDA6CCEB5DAFE
+537CC1A97C5A337D3C48A6AE947F58A30DC08CC7B58DBBB4737AD52783C573FC1E9408F55495A80E
+7FDA61F0B9C4F090158F1A416249EBBA936C27BEFDEF19D1BFB839EB70576A010706D8B95657B218
+9C2AE04C11EF9E57FE09880273761FB4302C388BD608FA0C7F00F033C9C00F4E3D5CE2D903E0DA52
+E69C7745EE9FA75E2AD93DC6CB5CCFCD3782A699B807AFC36AD1F62B05856D5DFD6F88831B90EB3D
+CD523582A49732E3FD7253126D39E8AFB8458B5F7AD7F94A8DAC13365F433C857AF4A42C0A08C4DB
+9887C4957259ED22D13CFDF5995DA957EA5A0F620B0214FBFE08AB6D552DBF048D62CEF6EFF12F15
+3511ECA7833E0E3E95F85E6AC0F95438AC4C126E1F1ECF336ED31CCA7EB216D279877123FD9FCD8F
+B5E52B587CFFC4428456DDCA816819A8A4A211D8F1629E5D42BA4C5C356E580C8A22C61D987552FA
+A97893816DA73D423686E4EBD44375C257F031318865A20F22115E72BF1EB9F93AAA169C140A33A0
+6C35BD4526A38BE79CF40AD1EFA10411E8F3300A8A8B97AB140EE6734E1BEE6C8EE443D698D34159
+97649C6F10F20ACD80236422E215E146D744A262DA3FC88DC0D86FF66512F49D3F957D3C5CFFEB42
+4823509F33F155057A4C6F37B52F4667767BA94F6B8B62856B553F307E5D230C44CBFDC9A97A45B1
+39FFB2F2565EB0E22026972FAD0FB7B9576FB6F368B61979943A398773600E7EE1DFEFBF26D45D40
+BDA66EBB96A56EE9CAE0B2420C5DD83E24DBA9FF885BB844BF3D2BF93B07325DFF60C0CB5FDCCA0A
+C8FB5A2E119D5AF26E53AB8E3B428481C2871DDA26EF0B621CD8572B3C664BC7AAC01A1D05B98F79
+1A7080D294BE81099BDA7982432F3DFF4775C44D23F4F1B2E0162B61A8B2CB5EE8564BF98E2ED403
+2219085FE6194C19DAC98A421826CAED7F1AB1477AB327506010217283894235D7DBFC1153D5ECC4
+8AA7293F19592B4D7E95FE55151889BCD1D7FA7DC2370D2DFE11D7E4EA34B5C7A8E73BD3A348FD38
+9EF45B6167FB90BA44C23E912F9A4F2FC0427ED070592F7110183BFDB2C400393BA7569058227926
+351F07FED4F33633BA03A72AA2DC6B598E49B96021DD868DAD0F352E5722FB714F667C15C68D49C0
+3D822D82677EDFE86FE9668E537DA284068C9B0AED83074C92A5B939296D505B837E6A9DDAB1AEAB
+7455A08A114C2222B339284674B74BF4CA9EE0C020BF2A148B439C71C6BE51A94CB64FBE4A7EB295
+5A455047CF5CB348B062ED4F6471CBC3E9ADD9BE9B96879AC7BC71BCE02FD02F17C6063985A5E898
+3D205AA1489DA13C408990ABA1C54F2F501AA172F530480D789C848118C0A74EF98D5F607A067BAF
+F6030D887AC6A6497F9A0B38F9705F328AAD4BFBB634F739386177B07F22D5771282444E5EE17335
+B4D0EC86117C697E79A5F4F65FDC08E4904DAEDAB20067EAE2448FD4301849E456D085F392DD1316
+7ADF75CCFDB723E2904A9C0C976D6B84DDEF9D92B0E15FB246C3ECC2D0BF314CFB957757B3A3E8E5
+801F520644E4601D291DA0F7507C06F3B9BB36FC1C70EAA444E14E56C0CFF06C7F853DF36DA9D8B6
+AF2544B853DFFF535A7E5C6FC145250CDDA229956019659D0D253A19A7B51A4E538BDC01F74D7704
+9949C2C97C7EC6392C2E61CCC0992B66DAF1AB08551063E53180D2A67DE496716CCBAA45462D9F91
+B66A22545962DDAB120511FF08627131B95E5DEEB8B4DD9643E7B2AF65C0FDCE11F5F1E8DD468DA1
+8D41C8C4F00EA73836F4F70EC50FC3EC6D358C0658A4261C6D15A582A2C7C994E7882E661855B352
+014576858A265FFBC425160669CE159D07EDAC04D060B44E5800A7AAE8E339C29B929AA81D2F515C
+46229D2080D5917AB20AB6B34FDCA8E4AF64ED660A3173786FB1A1D005D575C2A5187D3F7CFDC94C
+CC44A38C5CD523E9DA726D8EFA6DA7B6131DFF3435FEE838B2C7D6B97934295F06202D307FF78D90
+6699CB9C5BBB10D1D4DEA5FDA5BFB094E704607083B646D37F5DA1FC7AD21B813F44D8C1AFEAB666
+55AAA19703BEA2E77DF3BF350E17C74B3447A452235919452B5175570A006C7680AC05E8950A62E1
+1D7E3ACA35A397D1E19630D094A86807593C97F4C484E4E06BCFF708B6DCA972E3A0009E1CAC0EA4
+141530F5C1B8AEF5E1B933F37FDDBC4BE22B74FE346D1A3F5FEC0818F8E61765568A2AC04713E828
+F98C449D9A1CCE52D10D61DD8BFD084C8D099A75D89DEA64D5A7CC68BD5B0593D97953DADA976383
+F5015915618AEC56D71D1DCD55B89736395C609B315A3F1E1255432FDBD37F38CC43C354FB4B7C44
+F1A7318B0B7E99C3C08C33B953727B6A6328051783A0A33E3CD9E498346A3CA6A77B517096EDD52A
+E443B87643A646C3A7BB97F742888D33F9B3127E61942F4103C1DBDCD8EAC8F9E259773066736CA6
+53CE57E8822651261D847C131321BB9D6626A1AC50D047C0BA47B411DF2A995545BD68EC0287CC9B
+31D5DDCA8755EBEB10ACCB3903AB0FD5788E984220443B8459E7C078DA4289F1350905881AD6DFDE
+C47302B0ACB0D4AF8CAED02B4B70DF3CF8FEC118F0FC2D3DDE3E494CD160E676E300BC464BD4400D
+B50EE43B314E0517037BF971ACD7CD327CB2134893B8A0410E68DDC518F5DEC966C7884CF5FDFE74
+723177F20DEDC039D879056CAAB4BF045062D3904F615C5CFE109AC7A35599C94024B41019B9AFD4
+04A80ACAA4837929F5C9317680A13D157A03B59A5588DF79D2E113F5F51021D6F6F90E8BBBA2C252
+FD10651BE80BAFD59C53A3367BA3C28DB6EB9DABF1EA99F47B503F627E15DCF3FD645FC52C5D5D0F
+2F07DB4C25C0D1E1C00146E1C4D973E613CCDBD3F9450CC0F5343D79F05E9492E86A1BB889ADF405
+03BD7F3E7543436859184A5B20BD8A172F350D846B7570803990ADAA48D4B9155A2B4C4BFBEF1E1A
+065C08E03928559735BDD442FF1E83E1FA20A5DA57D8BDB2FF5427C034CF0128AF111E6E73099E04
+6E0C240E80A73D7BE72B87834E45898D475521CA3306707631F5C6136199F354632D1A085F12A1C7
+C473868B62E534D15F5484323E63D0574196A19EF175214EB35A90873EFCFB92D6CF68761D45E37E
+AA61E1A1979A82009507CA193E44B36A806486665CEDBCF387053ACEAB979BD35D30978FC7659ABB
+E844F4ECAB3303318ECE80777A5FA5A9DD91B3D06804C4B4E9B4EFCF07EB89866D0DD8CA390CFD15
+98651417114D78776B1A1D36B4BA17746D6BE7FC123D473EF1EFED1C3BC1D555F914536869FD5B0C
+35F9C83F65B0E6BF7A627B9202D787D72C600DDB6BCCE613D88492E13CA0AAAB196E8A49928C62CE
+A4FFE2D0208EDA334ACF47F20BD793124D2C5546C03F4A364369A76A0425262F9D9118AF54E37D32
+E33AB25DD533A49DF5FBF1BAF4CEAC2D9D378CDCD13B00FDA432D9042F623DA41AFB80699B5538A2
+5403B0B3EABEC9E8EFCF42FEF3EA9F91766902CD206B0787C187D5370B60AD6DCD002DE2DE8DCDC0
+B4719A797C5E26BAA67665016DA0D967FA1346F9588AEDA174CA001B31213617FE19EA218EC23597
+79D979E2663166489C06993230B0D07973A117C4E3F4A4C93CF8428248DD5389414D679C69644142
+67C7FEA17E35B0CEE456667A9B1875C81B2302BDDEA2818D6019FC1622A82051F60584ABC904CD91
+8676305DC03FFBCC64FDDAC8D8AA9CE2EA00D6C97BC63C8A617DEDFC0E40775649438E9F61AFD179
+5E3B20560B01BE5E0983F136CF48AB206954E41DEE0D9DDD953DFD01CAEB569151D6BC0DFEF29D70
+FAE3E198E7EDD8922C0E0BCB8BCCF1C016142C1A8B337AFA7A05A9D7534B184BF3BF827F371E9BD1
+9A71244ECA1BA73D484CD2FAD54DB2F0EEFBD54B536EBCB5094E6BC2F5B2AAE41F05B4B311115876
+ED42C34F8E643B53372E3F6350DB8A38445822EA9A33E27FB0CC42CEDCD1FE2FDF723FC47C996EE3
+56C402112F24D0AF899B2D00BEA1CFD427998BD22B2A09046D6737814448ACFB10D387547D7009FB
+384AF0562C85694C071584236D0F1F3D3FCD0CFB38B77C81889061E668BA7AB37AA60F58A3967DE2
+6F939B79CBF10A9DCC42852561D8D6754F1B660D216AAB1E133FBAA321C56E2584BE5C9BAE20CCF0
+0E8DBE6D9C2FCEBEBAD945C3C04101D2387351F132628786F6D9D4CAB83419288D31F9BC600D9664
+12E6AA457CE6CAD26A4C0671097B98C2384C81DD8B9A3222D4F4BBDA7017895C3EDC26662779AEE7
+40D9D7E24185FB821970B0A3A94041A69E4805EC88EE1EE521981536F2844FB8F5EF645F67D42CE5
+148E2DDE43AD5AEF200EDB3A2C7866C98458A92666E5F9E070178BCC39F65A893102A10564AF4E8C
+AAA5075D2F8CD7FAB0401C03AF299EA3515CC93066744EB5AF7CF0ED06675BF049A6E3C211A89E16
+DE5BF0445A7CCA6EE8EB0347454950485D884606651E5887FE8B24323E2AA16DE22FC1FC8C4F06A8
+2A1FDE5758976024068197E1F4506E4D3D8A16D40461A4586338B374A592DC60334402F76388AD6A
+457DC3F54E6169CF7AE3959676E966A45609621055EC3AF80E182633300A4418E34A66DDFA6B569E
+5A13C9115B5FD3EC1CEBE50FBA247F60803AA83976F00117536342DC3D9890C49B2AC701D370E43A
+955118967827760F7091469C5406F08F18D7E3548148CF0E312B1DC71DF67A5E7A1656CF2F47F3AF
+F3DD50FFC2FCDAB7177285B29C17CA43019F62AC6FBA52D1493ED7C427526470ACC8389BAE827759
+4958908F517B2863B83292EB5AB3F57FFFB08393CA610FB1FE905D88A0A16AC395E2A2A6DD033D6A
+0D68992F830B2E1B95FE357BF672716E88FFB92FFC3D62945D1EAD22BC68C51EE0E10A43011DB94C
+44685A5C4576F6EF44CBFB45F2A4BF110A01657DB51FD499767E78058199B31DFD60813F1A344F86
+289F9378231D5B151C92385E3650B4FEB1DC91018EAB8474CBF69FDC1496A4D078D2C351C8196451
+247A9DCF8117E5B637371D8E22E248C64D999015C3FD2311E9950B8EE0922FBDD3D7BFF766BFE9E7
+CE0BE12F318FF2A7B5A9C6D00A54401609304ED2C55F5C1EAC3D4B38355BBD85D66D61636FA6E30C
+2E82829376BEC979A6FEEE040E452359768ECF90CC539A546F17AE906C76F14F86FF697797322B05
+1EB311A759FE260C1EEE5DACF383816AAF1294CFFA7BF87A4D9BC595EE8F2C2F86FEEE11AD959D86
+F22FDAF4CEC098942A57E57813A0FA99239E994FFF353C1E781D666B8928CFC648FCF0869FC68468
+BDBDA7D280DFAB8B0B3A4CA35B074B686DE8D372C61FB32305169A1A9912F6541DA16CD6316A6EA4
+51524757BE5CF6E820011BE3859FB8B8578C100FF029680E05F0E0BF11D33FE19460C85EA5E4C0EF
+28E29407C8AE6BE01CFA0D5022BF9FB01416FFF722A784DFC8FCE330EC95737A854471D334FDC58F
+AB42867A7B62836A8B56466E9A6C1247D46EBAFFB905CD4321970F59FB8D6FF65FDDD34BF913AD32
+2E68455C5FF2D23C1A5EAE687F259BC982B6A384D35440F7C693CF50B9ECAC0B5578CAEE87588B56
+2EB6B7F42034C9F2E545EC866316552354EB3728C7D26527ED75174EAF635E048B08DC5D23E88981
+070AD5641A652F2344956E9CF4C16E652A99F4A644D1787D6D36537489DA4D74E61B2FC4DFDF1D1D
+9D58F9C26C5EB63200526AFD168AC57D5611ADE4D4A382FC28BB60F9E7D626A6C67AFBCCD1183C5E
+3CF2EF210D0BF5CFA7BB10FA3887BDD4CD96EEEAA8F9219AA2F10ABC0A960C3B57C0EC0313AE10CC
+FF1F522124CFC8D2D49BFBB0C193EAFFC5B48FB3FF30B21CB76F0A4C0F1377C9223145BB0468A5D7
+1B9BC25873EA12E1C60334571C67385C00D0B570D3FFC6C7FF0DE62C183C76AEEB12DFFEE1459E0F
+C818C621B8D12FA1357E2B55D48935D70BF140B4CFFE8813DEFD479350B20DC2EB1D3CBB1A2D3DC6
+EE975D58C89D61FC50E6A0197DA9A586B72255023DE47DABEFB11E8AA02414C2FF6258A281219B9D
+DDFE41BA7D7977D0D6F18224FE22F7D4E9355FDB35BF7ED3418F4F68D093AC48F7D8FE4194FEB6C8
+0B9DC1F74E023C604DEA27089F98C3973FF9F4AD7BF7BAE601DB89B08D5D8139B95EDCF6C885FFA8
+B3E4B0477E7040225733826BACFD1EC4A0DD72DC41734856AB9FB700DF83CA2CE812913BD142D84C
+5C83C0B2583768198AF9E885F2BA74877A414233207234AA5F18840557CA11682AABDE8993533887
+7C6D404BDE4153C9827EB16D66C1D73A8143C8A2D3604FF72CE579FAA3C5224BAC48EA83BA848429
+9472007DE96466B5B29ACC7C03B05DCAA38A48BFF9F214DE43146AE4E04FA705421917F99BC54533
+F0EBC01849E396216B9F0794E6F6C6B61B52EF1B1950C0FB609895C3C55FF574163FC8B6B09E66AB
+AED1810E698FF37CC1F926B2CDA3B48C7D77790EBD2D514B6F385D397F713EC3AD3954EA9C846158
+6031D369E8B99E53408A79D64C34EB5A56DE8A67DE91837960E98A66FC04DFA0EBDE21DB003234BB
+78665B039D0A469A0221BD541AF7149A2A659C300132C14581EF766FFFBECBA8B58A5EB3F95446DE
+F49AF863A8113D17B2E7E6ECDEAFC3834D4DF900E3475596E86FBB4E2974C090DB4AD61A737D611D
+92B4535AC291C56AD8B1C031D2F9B505BB77517B737D70AB3723DB52AE2ACCD5DD2F617423ED3CC3
+9CA882EF41757BF7151806A9B8B0F312808863E3673FB54DE939B35CDECA7FBC4DC3BDF5A5F47D35
+E345916C39366C8B4F439CE1C6F1835C320BD1E67375B03B5DE18C93256F251761A4C8CEC01019C0
+68E34447BCC503B9571FE8000627A6B3DAD5854CBC0A2D69E5A8F46BC78F6A7B1422334EC7A98ABE
+FE9B83E01DCF3C6C9273B346F3240EA225AE4A4083CC7B0EA141A0773FDE940768358EB4B13D82AA
+304A1386D450C1C0C6A7D5A8FD2BD313F78F85248B5196241E31E5595F3BC01F37700A2DD3D4A0EE
+2DD01A36569CD507130E8F5B1E96CB560BB7DA15560CCADF3B2C9804A11D9E8055C9EC70E48C1D21
+3EB756A1376F2EDCB7189D78CD3D6CA5865537EEC31C17D801605EFD860B0B629472690588D02575
+02C6F7A75B9A1C1B397781329832CF3EC43C09F1559CD562C48FA9500295CD3B0A790DD3FCD4684A
+7C7AC49AC9BFFF36B39A9FB148BC28D37907433943CBBF0CBDAB46D3EA86DC8F81C859C52D15302B
+94A9B51C199B7104DEEC9D769C2634CECF8B700CE9C04152CC59C9326BDACBEC4312DEED92DD087A
+1C4840868D9F97CAC046581F762F75E8D24D6445370A3F1E0AE74A6478D9DAC37E7FA5BEBEC0A1E0
+81AF89C1BBF7F51E3E2E22C8C405E8671BA85F1BF0DF79A465DAC7EC07F731E00632E017D190A99D
+83E27E5C2E63D7DABBA23B2E88334C63721AC5A4CBC5D45F4C177259F34C2EADE01FA008AF65EBC6
+01D8DD16436D86AA94C99F3CC0A2F87134E73BF22F108B825A8963B49C6C685474AFE4A542C8641D
+C0375D7EFE9AC1168D9700459BE52D0DA399023E141969F25C0DAC4668534B6647EC85454BE945E8
+26B26DE6E3C4584B97A38E2B40A0D23481BCA78084FE80E00A71A790BF31DF468A435ECC88E60A57
+860BBCA3D65930186E9917CBD209C230E8F8255A7ABC7D3F043AE4D7AD63D9980BEDF062B7D5C298
+C40225B6D03F29A0339E0FCA02138E526F06B9EF47F5E7A8068A846CFDE2BFDEBD24F5A73A66C079
+18662AEC80B43246284FA4E2EE0D9AAB172B1E59A6CC46B801149D8C0DF6DEC9A55D8E1B0EFD9D30
+2FF618075944CCCB6831D336B11617107B0530D09885E5CA11A5F1FCC8D69D603DA16BEA51116D42
+CAB1AA1E4D7B9B4D79993F2BFE53EAC904FEB70B2D330A89780EAC10D12CC0C35B8399F218AC2976
+E57A26BAD20CE2FA2AE2363D3FD2A8A971747556F2959DA74A8963C20B504711AE1CB0D0C02457FF
+2E9BF696B159AF031DD5155F21C0F5549B0471A3C5DC8918B675CEBCB23E29322B959ABC05283A70
+2E878DE8EF25EA760F3C5C7B7B49D398283DE2ED837FD59F7C22D62C58FE4448B1049FDEBFC8787E
+67D7DAFE9774979BB3802254DA59BCC0219F98C219F84D995CA768B8B5D9D4A32525DFECE003675E
+E4BD5D8DFFC11025AF2B468F9207B5B2B42349B98232BAC0759758C1F4A283405815BD7145C93FA0
+8F3ED2826655053A3C2559073D8ACD199DEA2C5BA5F616A2E48548B4370EC73493BA07E197165DCA
+774438B0766867819C1154D1959FE6E01E6312E0AB91FC2E2BD240FC8652A2D456A1DE7F34EF372A
+53794D4C4E050BF3CA5B7BD2F1B8DE93B4C8002485CB219AD2D029739FD3C81CC6E78EDF38723576
+1A57143EEDE5CC887F282FECD261F6A25D0A7E154ECDF5DC38E426811BE86AAA458577E5E0C5F0F7
+5AAFA9C41E5D1DC9D91ECD79B514F8CDF7A5F1A189470D35FDF4F9B8788879CCBD91B427822ED658
+389E981E0EE5F7FB87692A3E3E931DF8A1D1573E3B0166204240B7080089A09EF7487C9AEE2D665F
+5A82F94C877FB5B0DC531CEBF1E71C6592CEA2401E4B5122E5091DF03D203DF979B9A6EFBA12E2F6
+B422FDF15D49AC0914D372D21E871DE65CBECD105FD4A3E4714B9CCA5C6803FA39DBB015EA8A88BE
+7913502E562E5B170B87BFC8572DC9DF49AD63694311EF1334444BDF0B4CA3245271C1F7A4D7FAF1
+703E3AA0E1EA8D5C6E821B28707EE0C9B4F22F23796FE87356C58AE2CADC191F4C58E1FB58DA03B4
+5A25AC95DBAE13A293474217BDB214742B9D9D6AF35F70FED2891942EACE3E625E55FFB820543FBB
+250A062D3D395BC0F219ECFE0D76686AC148BC41476A887BC494DDBD396BE200FD3E03CFA12EC9AF
+6B934A283C42AA05589AA6B4A8D16946BB51F50419CABECEAEC5AEF9085C9989289E9B46BAFB6FB2
+782D84DE2B068F91A9744AAB237CEB1BA513E57E4C307108E993C972A3E0A898D5A8D27833155031
+FDB98863C3BE7FEF3004CBAA5CB60A1F2E3EB4D7290FF5FAFA088B1CECCB6CF51A58DAAD998F0839
+6CDFD68F5ABC9C1CCB8F6514107773C69C26873E889D1F79D10E866910E4684186FCD71C965ADF62
+39BA3418B313A27AD632300969B6F284519366ED85E7CD968D64823F8C59B5911A72D0A20EB72B60
+3A61E36F52F256FFCDF706B4560B4DFA5D918FBC530D83A4B3C01BDD3CB4572E24242D141BF9E775
+36693A0407D002E09CDA5B195BF1CCF430AE9824C07928A050D0B460F2704BE8F9E647A4884C4567
+0A81EACF7CC038643EB0FF18A376FF6F32B6FE4F197273327FBBDEC6443A299CAD4B26F7778A99F6
+5A11BDE047153E764039EDB251936AA43DEE50DDFDF8856519056AAFC4C5AE6F2051AF0579A9ACD4
+1D00775D7DBE70022CC263DCA5E0A25B9C7C4F5C418587666B2FE24816B1E0EC92F9074F1403BB83
+AFC3F1D52CA79C387BDEF864366E34C90BE52F7AA09935373A07E4E026224E76F9EC3CB9E7EDE50D
+EFDA48248D61F3CEC880A3B8843306375D9711E58645F3625BDB8E87052DA67F9794EF4AF8DB0BCF
+E00677C3A26907DC651BC838C40EC39E2B5A5DC0DBD345944A6C32226089D63C52490FA10B215AE7
+03CFB663EB8A47793B84CE7364DA1C4E7FCE32DFEF09490121222774915BA59C78C2275F829D15CF
+4D8686B095C38C731B83D48738C25F40B8ADD487C350A2EBE846C3916AE384CB1050F9F5DFE09FCB
+D9129C6270FD86D55A459618FDFA4F907E6B4746196BB717865AB378414029017551161A52E9D24B
+E4F7EED553A927933D4ABC8F25DF607779A717909CB4D810DE8F5762581900E224E4B91598149BA4
+71CF8068ABE8744356B261600BFCC57FB8BE45036CF6571D9B2A95304933BD4F17215F8EF53F8E08
+1AF61FA7F9583C34EB5655CB0ECB82246959F09091F36989EBDD646BEDCA614B9A61AB7696B3FF18
+1058A150FA6EC1BE2EBC7F64357A3FF2A2B0491D2F4E0B970DE5B7788B467CA678039B5EF55C88A3
+84578D427FD2CB16C87B0BF0A3D37CE8ED43E0F049AF2436344D5F47C948C632C94A287509282561
+6C64C5D262FE5B24916FFEE982A69A6CCF888BD01D62EA591EEC51F4B7DDFAFFBEEA93FE08D736C2
+0129E345D06B10246A5F57151C198D407730713F32299638EFBDC01367E23EB59AAD42A83AB41B43
+2DB462652E29813740F4680A5D4BD47B18328FAE6BDF4200CFA4CE3773809B45E8887C9B2E423698
+9F6C48D64F5986F563D9A7538A8716082F81936AEBD0461E6F4BD470436D8B7656F0FDF89108E6DD
+02ABDEF907731D458D690BC608EA9CED09EB1E6E64C0790C7A2378201CE997FFE0317679EE1D4EE9
+F91157449323E53B4ADA8096CD628B5861BF794543A98F2FA2AB54FF0F25A13DAD43DAF9394329B9
+5AA53CA32749FECB0B2BC035DD1EBD53FF9FB5AD8BCE06CD89E5568091C1CC314CFB1D9821D7F9AC
+7C55F55E0A16E39A87D43148201B928F3C42B110FC056189DEF183745F3B637441DE8BD4C3C7EF12
+F4258E306B2877ADAEC63441010750DB4E6269A4C78A0AC01BB3603C386651FE814031CB5D8C1F14
+9EEAFF652A53E57BBD4C8C0CE36A84A319A53BC1E5FD3F1ED1EE72F4C1A9BF264B594062FCAFB22C
+C1FDE3F2E3D3C17DD3F7FE0E15EBD812D550227C06D01127385374A11438ABD50048E17255FCD2BB
+85122A6FB9B7DA9D5E9DE8A747FAE0DA45A1FCEFE92B9E70A5B2CAC668D4D07527A5C1403267D823
+048BE671F725CFC7474B44FC5AAA348420B2D7C23C6CA066666FD6F2208E329878D90CEF1C2E77ED
+22D3BEBB9D547810B189F08920A27E7107F208591A84D463CE2576C70C3DFE6643E4EA93F4E1DAEB
+41D46F0E2F56FC10C69AD5034FC9859D31CF27A3A1EE256C93111F81C11ACF1FC0CE20B90BAC9AA3
+27A5C85A7985B951519FD4B03C40BE637162AF41B2FDA68F0D1E9B7602FE2659D3D75955C579AC51
+DF6A552EB9581AC3F712F083F19B52A6C4F560F36C59CEEB0C996AAF1728A2AA45DCAD79BD7B23AB
+388D5B0B64A2B95154B6259B730B0F4A72C8C7F7CC93C7D64D9D8810D1F63FF8ABD4DB89824E2D26
+4FDEE916C41E299211DB1A53256E1DB5CDD04862F034D9404B73183A99D3D13D642A663F129B6D16
+7095BEB4EAEFD03DF2FF2F0B6B594C1EE90FDB203DA89FACEE23F1BA3901FECC75FE1811BD701259
+343011262B6A0A9707AAA6316BC3C17F787BB80AC8DA5AAC942D90F80C5A3BB59E47EC767244AA95
+C63E50BF809998957936D3BF6ABC24B0A397258F9EB4DC8F65692CB023D9091FB180C69498CD0C08
+BBEBADC84A7E0016E8F8BEA325D924EB0DF82E75D2CC2CCBF039B11934363D4332C5FBC5EC556BE8
+5EE4E707CC2753CCC43D2ED50558E51A104221C9323CDCB0199B7B83454DE3FDC810D0F362C0299F
+5DD981B31D8E3DDA284FEF9DC8F9C8DE138D3065437A7FE8C30572AD06D62E8527AD37AE39AAB0B2
+25F76A25F6C6505241ED73BA494CF923E919F688DDEBF193E188F8C4C154F21631080763B4D091E8
+AD1D2FD6649E0CD9360E8D1A67A5B5FAFC67547CA31C95A5EA8D4EB5D68B9F6D6532DB9B54584735
+9558542A2AE58C09F3BD2918EFBE1699E9C8F2C2A11EA4D224C726D2ACD4A8D8ABAEDC6588CF2AE5
+66528B94F55B823A2A1F7BE19000F3E7579D094E047075DF18C8C868760295533B26EB3ED90635B1
+29C17ACA679C3E88B06998CE5A7A2544B700229F5A6A504BD3E45B276471959C8A3F81917A534287
+39B5EF9E3D463B3BA7318448E2A3E79520D2D245A2A72F31FF7070B6E4624E3A5E216BD103640C8D
+F387E49D732529C611F8B971073F17EBD2F6EB18F9B74A67E1997926DF178D4C9EDED435B9682F1A
+279C81BB9F60DAFE125845A2FF3B02979E5481C78A45C479BEFB9FEF3CE2BA9BC46C77B50B03E48D
+A6D17B76F06F3AD118371ADC69E178C52B5FB4B261C9311874ED07DD6D5B3226A005FDD7A6D53848
+09E7063F036CDEA41619122635E835D2D74CBB6AA9B38CAA4D819C26E95115FE0DBAB4198FC5838F
+2C91B7A87B07D734C6D4F4F83444C1E90AA9BFC908A2BAC4B3DEF9157AFCA5248F2DA31CA87BD363
+AC25E9E77F741D4B2C6E02F04987A6F49D30E9038CEFC41BA172DD675AED8B392164411144E5B738
+F3210B0E66B17A13CB9631C33D44484E792A7C082DD0A5382F34C5637653261B1EB6D2035B08B4D9
+1FA9AB770CAF40A103629511F7B43F2743D7E583433DECFB19C21FD4FD0AFCC22A4119E77C87BFE6
+FE50068B22479015BE5A9F06BEAB4D37412E062A45E0CBCD7BB39FEE747E96306F79FC4F2E8942DF
+5D9DA0E55AACCDA547DA19D30B8404FA121298B44C9CCE198C708C69A8D6BF17591C5C50D3FC5BE6
+961F7ABA8F366DAE957A1C3730DA4A5B4F035A9274675EE3BBF0CA8CE9D8349F50CABB1C3EA4948A
+BE6F9F143592F1EA95404E6909A909168E3279A957AE1924245C356331A75E7008BEE92BEAA304BA
+40B7C3F48F74D9018B3247DF50EBD7CE541DA48ECCB1B0BE51A455C3C13C279D4D8676078C3EBE43
+08748D52C9B041D3E7244C745B1F2F742D010A9E60695F3EC4FDC1050AC082B905D6A57E8F407A3B
+472F731011A5798965B7B1A307E252FE02C8F79CEEDDEB6E165F1A94D7FFF18DDBDF79477F14E9E9
+3981ABD200FE7771B29D1D2D120EE79D28B9543818527039AC74085EAFF241B56D08220C958B5D9C
+87C0C04A14D52AFD475B542D391BC54FF33DEF8D9484AFF6873BEED32DDA4B371112B523B6CE22B4
+0D1B416B64C9370F1CDF2C548F4CCBE9E12E21C36CC3EA52DA232DCFB65F66B22B5E2EC04852510D
+5E264EE939BB67AEC4764B87062AEB7F680B40BCEE04AD45C7519EB3B6199C9E0E332661463647F2
+FB7EDF303EFEF84891CEBCF0FAC5F723A9D0476C3F8C092604C87FC69C7A90F4D64AE45A478EE8BA
+2DF50FB93F55A3546123F0B0E2C1C40C98EAAE9F0F26B8F80FFE6E6B94B7E27D2884D58B8A119662
+2DF6BE608C5569D7864BB756DF2EDD184B90812B44ED4A32D001C31383A40AEEE9743651F7950846
+15C48E402DBC01C818D477EAC0347795CB2792E9C11E8FD4A02E194EED1C919D4598FEC003B6D9A8
+A0BC7D456047A1C0579453FC1D7CB2D158D466939A23D7A7B8ABED7E2777EC7487973E73F2266D9C
+250CE30729E3C5223AD93B9AE8443B35711E446A3DC660123ED45CE1942A1A2AD0610467E081CE2C
+8B92A6C82F0B17B5D2429E99F1A6268072C6B5AAAA6EB6283A872C54D3694CD825EB2926E57DBBC7
+C1663075E687A144E4D61C225781D80FCAE1497B442342B4A3F1CD6BDB50E31791CC3928C30835FE
+F845B6BE5E2D7E3F2F5F085AA3FAEB45CAD0D76BCBB1ED859A9CEBB9F7457036F0BC3F195CB1A98C
+9C8648F6583CDBB23894BC719D68C2DBD8003B10D08C8CAA40BCE784D7BFB4EEC9EA5359AC056E57
+B8B0F2EBCB1F4CE40C87FC7861180133E0CB6CE2FC4FE690756D327A2B5AE063E3021C0C0BD420D0
+56F0B941E6B36088A55BA11D0C35FD0132D5F48E5D9673572347171B4328D4807B972831C0D74CFF
+A5638C145B89C989E6EC942148207D6DB82257585958034D9F9D4221C7C9F7013790DBD130F277E0
+BC88BB179DD09E27062379ED06F25EEA8B7FB33C35861A0034776E3813D2E9E5C10E227CC569AB36
+CB2D9DF2E7B7B44758F9DC4FFAD7A24AC7E9F47AA850C221048C3CB35A37CE8EA75632AE65FE3212
+175146FECD6334AE3D3C5F492F067F795E1E8FF386BA198CB74F0BB4DC0000DA383BC4CC3F070DE1
+7721431988D69C8B1A5AFDCCC83C22E16A87E01C6D3E79DC7AFA3DB0371B0866EFB8B6F88900472A
+FEF1C4A878243C52D4E02E82658979731C841C489A6B97E271C4C93800EC7D91F93EB9B9C659A554
+E1FCE42A5EC65AC39190EF4B66DEAF6FC0569A000A9E1495F42F706FBEA4D32EB7EF11A648910259
+6A65CF899C2F322F5679C6D123469192A9BF1A7F1F2C81C554ADB97BD19ADB746A4F81A4D5559E60
+AB94C483DBABF6CE2F28CDB412D50FF3FCFA3B3DAAACC6A83CFED910CCB3B8D2C19590AFF4D75303
+4A6CE7F4156896A13808E0DFEAC547E69D3C886691728E4A35ACD575B40D721E8FCC5385A2EB28D7
+08101DC50811529528F5CB0C009BA7E3C88468E37768FB0D83895AB54DB2DD5426562AF9D8AF304B
+F6EDA54E9C92643DF926F5C3578269750120302A37CB140A18BA56BA01108D4ACACE8FEAE640A6C6
+958EF156B588ADB0EA5F3B0F37BBA12B7BCB221C811415387B024B7076FA4403A3AD6EBB5D9C26EF
+EBDB7ADE7C60B444AB9F90EA493B658B7767AE2BE649BDBB3FE85F460F1ED137C61BD95F7CD3D8B0
+15CE45138538930AB62AA0E54B4CE1A5EC5FEC0A2B28B345B67089A4E4AE14D2E1F5A9C8848DA688
+CA298F93860649EC3AAFEF3E820D86988C8E3E5A4D4BB937791827994AA3E81D0BB3EE115EC36D5F
+B9A392D09E79AF514D11C7B3A03C9F9C13355CE79E119A19177FFDCA34704D38118A8976D1EE5AA0
+2D14FEB1414419F5E85244ADC5C0A765A522EEF36170064BB19FEE3B5F7B441E4DB967DAE0BAC2C4
+8FC6A836E0EF5A69F073BEE1699F55E9C757EBD6FD8B514E2B49D6333815B7DBD1E0694695FCA3D2
+1320A0C4B852D9706DADD8369A95FDD917328BE93DD33818954DBD2C212D2CA81560ED5BC284EB04
+7A5F389E24E43F4FA8C97FECF46589FA7341076555CF55B1C21B28E0C1CBB00AB8B6F67472F27BC0
+D11148F407824B0159B5188D4BB7386FBDBF1C0FAF34721B7BCB5C0FCB7C4010DCB6A1284E9D7883
+9E3C2111A05D29AB7997073B590A81C6168020F1D48951BC7D8476D5BA593F4F23CAC1F9BB0E091E
+84B4E99E5C584D1370DD12DEE8DF16AF8BC6B7B23E2FEABDB7F32779AF8E2B5094A6E9B7A7225F24
+C43A8E5D2B977E1E19E633C26771E23017ED233DBB02C64F8CF03992C6484528D0C8464B46F24F9E
+8380F385D5D01B8893C67FC103498983CF939432AA380CA576D09030CD52FD99BDC3BE16C7204CDC
+3365BF76294A83A1FC14A236F5FE5321904E779B13232A76F8FE521F425562678436359C2461BEA5
+AB27209541F557AE2AA60009C9CA0A9FC7898C14306CE35A50017BADEFDECBBF94EE2905220706DC
+806409EF87DB1D73EAB0698AD2DB72CDCDB293E7FB13C94D9FC87E74502E6927A212F0D7D2F2D194
+64F7A66AC07872E18CB1DDE8F11835DCBC5C4EF039333FFFC0FC1456DAADE7DAE3EC2EE0D3415B0C
+ABB69FC5006F4D14A4EE1A5CA99AD4D5E629C0DD1E0F097B5B93DE2DD001A8C418234C9C45E8C13D
+1AE04E9466DAB8CF1ECB88A4E059C111A6468D2DABB90DA79C7C79E94DB28F6968B1A632F8C57D9E
+565FF91C6916026FFAC0661856B9FB8DE9C81661816221B1FC159CFEF1751E7E403F5F2CE32529DD
+540792FC17A12A3DCD7C50D38EEAADBD10ADBF5D8A82442AA900CE6150EB7A4639DD9FB6E385B2FD
+093493DCCD9014B23EB172E21AA89643A6CAD1093343D85D81261972DE0ACB16A4C6B5F0BE4C978B
+FA12D3CAF0134F9EA49F6E9687C8F99A456745EA252F0BA9968C7F9586E3DD841AA92DC7705BDD68
+2DAE41518A09DF0E209F321D7FA3417202F4BA76A984DA3ADDBC58136885362F02F0A24EBC439B3D
+BBDACFFD8498EBD29F88F016B1FEABC10785438EAC860B554525F3266097A675299AA0967BD3B7A0
+EEEE3FC578D1BE99D3533BD91571AED904BFC9DA1A1451FDC5406E1CD614E0C7FBC733563CD6CE6C
+C31E9237CA153F1F0411114361D731636BCF98555ABF12848AD109371A42B63675A4130B81E97C2A
+2EE2BB5D8FAE2640156001AF0F55D9D5DF8FF23C8AEFE14F120000F14149A36E5C94CD9081DEC277
+C2C34870D05011F99D48B0875A5FF542F067F7E9880109F586BCF2B50522A1F23ECE44349E539E70
+F84E207DC9BEC7CDF856A046F1A03226AA41F541719AD1AF88FF211E57DD0C1275DD0B7B47440DA0
+89B98C6EE92A7D94700B83CEBE19EAEDD8A615F6587587BA8BBA3CE3AA5E8EAFB1FB0F486BE3609B
+169EFB178A4292F4C0378AFE5D24EED1CAAB514DDC66C696D8E37F294A6579131DDF5488E9436609
+ACD750C3DB0A940C84FE022B22ADC2676F62E91E8F891225F891FBA537679B24547BBBF35F04915D
+20B11739F620D18B5B216921D222F15044368569AA302980B9225BB839F494588481B94B0C724352
+B2DF600A22B062561D86CB8F81514FBDAA4F8A043A0265F992FAB71FC9124A45B8475E1EF3DF6B6D
+E35CF329777D45F08325E8505EC0D979F542807AE77E57E453525F23BC59A50740371EFA98678AEE
+6C425374AEB745B99DDB5D8D908FDB551FBC0DB15832107BBECC4E11A1A8DEC69358A574A2ED46CC
+31D564549EFF23102D92BFDCBB2BB985F78F36033E34F59C0EBAFA3BDD71338736464CEFDBA91398
+33995EDA4207BFD4A9867D32E867FBEB7DE60D132803EF9347CB17BD91315484EF6570892297DD8B
+7D966103339535E28A00CB1EECA4A9775F60A9F5FC9BD8B06D78FE8E6318C31DA2E847E3F9CA587C
+B01AE2BA0A2EBDE308314413F4F230A758184ED60D4F71F6CEC22A93A01B6C54E0449A3860FCA895
+4A347B7588329A80974ECBECDA1070FBC055666375229F13DD995E99265DF870BC8B8CC6347FADBC
+1A6AF64599271A475B9123493D46BEC41289BEEB67EB97A8DED7A9C9730D37C65164CFBDC22E5CA5
+89D2E7954C7136EF4E084C43A6C7F361A3E96989239BDDB9A593CC2A80BA16DE9EE90E95CD39393C
+212AB22EECB677FD36D34DEB46C4AD0D21BF7E6D7CBD0C8083842FCD87B18FEA7CECF939987E99BA
+34C214E44DD84C176C9CC5A4CEA76D380CB316BB4EF9DE73D73B4AFD4ADB54451591DEF86621D138
+D5A0A29441502BF6C2ADE671CEC3CB5CAB903A657EB2D70C943F976C110E46C5D9D29BC00A875F27
+38E5D22496A43E096E009C5D3CB724B4CABB32838DBE527F83B18CB457E57B092C302EE557FD4F00
+DB9C56E66C9FDF4EC9FFAAB85F60D02BA79694FABA476A199A0331C30A78A92E10417BA236E23364
+8174C826331DC1BAB87C5F95027846130C6A2B4027930EBF9A97BA1B039D386FC51C302648E25980
+212F6A582CDE2778C677A01FBFB3C5D1B8A374ADAF6ADBF7DC94075F25ED66D440B3922C5F255FB2
+3FD8F6E21EA65B1D93BB225684B50F11310E242B087575973345B229BA62C1E2C35BDAEC04D10148
+F5B2F3BCF7399BDFDF1F3F79119714AEA697245BC647316EA157484ECB951BE367234FD02E8B1F09
+1AAC3D29BF282DFF4011BC0CBA8E55234D943DB3017CC7A766720BBC29B2D097A956C0F1067177F0
+12D42ADCB473CDE8D1BA35B4030757FA1D8211989DF3BD22CE5D501C21EF8708FB3449DF47D88650
+9FF7B59B76C0DBAE443F336FEE2D615D7EED1C284F14335BC8A26BF4621E10DE9611FB2F1DBD52E4
+B7565D8C65B54EA36D508BCF0C578A49A2665227CDE1F9768EFE847F9D94F1BBB7DB83701C232198
+5C7283D47B2E40B27A268428AAEFE75F6B2F8764A8494E5827573758CB9CA46FA93208836BCCC8B5
+564A69F5AD882052AF1C1417C3FA7F580569528682C77080F3688B65E7FC24D2A3AEB61574B4A321
+5927281544DDD7A6EE0A3E9388F8F631CE7251724DF70726E5912DDCCC8C652DD6C9608F8462303D
+867F589DE0F2F71711B35142EE6EF93B64D6326C4DD7DC83278E057100EE772082E6BA368ED91A55
+53ECFE2293A481E42F83BC8F9148C70EACE91F7B7D9CB8A72415BDB3AF66F68EA733A17ABE9DB005
+3BF148629132969589F38D30EABFA96A01FAC72650B5A6FF3935670198A1EA33810A9B11E330EB8B
+451F24F93544263436F669AB5A90A53B16CCEEAC36B1445574EFA7E802DE73522BE725E68704822C
+B7D3912717333367895BBFBE06966A5CC653AAB5E9B3596702086BF0010085B900711932A95ACF15
+CA4DC45A754EA334E9EB84D6FC8E3FC4F897456BED64BB93B593549FF0D5352275D8E417172A6664
+C5E0ECED1019494A7ED49AB0B965BEC1A82E5873766BB38D7D856049CCE2FCA65AAF61E961B60634
+E2A69EF059754C9D8163D87F928C222772D070D83FEC6FA5AC734AF65E40BFDE521F7D9CB1650FDF
+64754BFF21EA3FF0AF7611A93D525EC9B28C51AFECB04E7FC8323DD6C9B0D8539A34FC3CD8CEB795
+8E8EBBFED4313C77ED469C199552A9FF70BA5423B03B6148D4EAAE17B71C5B39DC436AC53D6BA8A7
+AD81AA8B02335A8B2B11E9F4FA913159A725B8AB60F52F1A2EA50EAF4D56656E615BF382CC68A690
+BF83DFF24FE986570ADC0290ED1A37C1C2AD469CE789E0EA0BB5CE01020100E729721AF3B5BADD33
+A2DAA6C33EB8F9064F5292F715F820B4BBFDD56F76D42E7A1A068C1CBDCE4640082F6E7D582D1939
+990CE6EE8D270015A2C461798B37DCB5798EE9F7512168B76D26C28BE4A49A1BF96C89D235F21A1D
+B6A96E5DA474D0B19B808D13D7A11BF39EA8647499C410ED9894A1ADF33D41B6FC2E614D8087F4C8
+4E437B136F3CB32DB8393C49177A0675A0C9E7EECEF448A97AFDBE840FA01FC7E5F2E8FECEDC1884
+84C312E8635CD79195475DDBFDD4D38D5A0246DE2C7F21608F8D2C0DA1371D302E941572E5792A3C
+F4E51A33228B93A814D03FD4FC223C314CF3714BB3A34BD4F7ED6348577FEED9DEB082C4049E57B5
+D3CDB7F26629E9F3BA36893E09E3C7463D02A22D7056BE76B87763260E46E48BB832B7EE13F8DC05
+37EC8E81E9BDFEAD8C27EBDF1AD706933EFD11131E12814F236EBB01BE85B7F1B2D627413B324918
+D247604F56EC128909873FEC3857028BEF76A3494364C2A7002D104D486236C30B48E2B75D851C34
+EA50BA7FFEB4E19190898AE21768C157C0CAC628A2181A32796FBC1A7271D2473CD88E5395DDBDB1
+FC3AA8DF0F3D588637F19A8B833AFDEB5F655A8838EECD684E2315B72C75CEEFBCEF94344ACE8D6A
+DBE355008EC72FE7CEEAB01363A895F4E73F867639BE0A0BE67333848816B05B419221BE8F9066C3
+62C23FE85B7F392930BFE4C12B9526FF2FDEC38F23A159ED61A0718E7115C24597D849FA76369153
+54A40C965D4D72EC94DA61A03766AB39AAB684E134FD1407A5B1B19BFEBA52AA0DA5D99CBE5C82DB
+AA663711E6DEBA180E1D4A39C320516A4350D296BC19BF1BE054859A0889C7E9727A021F3176FE62
+0FB0C837E4141FECE531A950C03D319E3255703220B7185BD20FE5DBA673F8129AB211EFCF36EE39
+4C7E00EB0876624BC840FA86E58B2F584754CB6BFDFD76810E300741EBE4544E5AC17413ADEB21C6
+2F66CA4F075C32381796BA709782DE34A675B717A2C7F6D88104CB924FDE5DF775B4F0B68E0E2E5C
+2F788BBDEAF06D8E1FC2105CCBBD5827C0B03FD6CD64F0D073F3192D5F94839644E5EC6C5185BADC
+F04112A65F49A8C83174A9AE958E76A2F5AF469E8B76C833782C5FFB8BD7B1BBBB3EA0CB7C9786C3
+BE2ADE5E7AFA8C8F20892659A59BC421E28845A108E34EE17864042EF587A6D67DECDFB3F510EB40
+D2229585347A0035670FCC76C2837A4E4D68304FE113C539B35C1F0234B5079B8E32934546982978
+C5E4DF955A454EA263C3CA5D7101F31A318D82A3F9FCB5A8AFD7A65209663B0FC9DA400B26F285EF
+46D0E1EAF8ACB1F1CB805E3986D04BC585073FC64895E4DAE1CCB749BB439CB32EA91176D5C39C36
+50D10AFB9C9884D5FB90183424CEE67EF2175D01D2478D67511EC9F54F88763C152697B06D948BED
+49240096EEE3D06AB4575E8E8B2CB8263B5BCF4FA1608720F52B675309833071879DF52C3EC2871D
+20F398B5CAC8F8A4D41D0F1D47584DD90DCDAEA4A1CF160C4B3BF1AAB890B5CEB6CB3488672AA68F
+BD938281DBC1D8BCFE92FBF514DA5358443CB6E0147254E91B38CE6787B2BB0DEDD2D38F5938737A
+977B5EA42892520C58F8FBB53C994B57382379E9490F0D6970B980E1BDF8CF9F4C3C5E0A18F66E86
+EE93FFE7FE546DE50F41364BCB3721B637072571FA1779F1D672FAD260C16D7F13CBDF3E4376E7FF
+56D2A710AC5AC35FCBDBCE2C9C17E523BBE6218617B13C1FA6679B308979AE7C61DA6E68369324C6
+CBC7DDEC364E5A86707266C0B459EE7B2C03FE584E529BFFDCE98C90A2F3D9305AA74D3ED8430DBF
+3A49FE2ECFD9C4BC9FEFD22618FE9C8A973AD072AB6F713E4DF02DCDA7AC5359B2D652013E131B76
+B3ED6C75FD53BA58D862846264627F6B9E70D8800F6D9B32242B747A67BB2B45675840D34F852AA8
+062FA6B01E31ED24DAE02F6CF788A17F7B9368175195DB0072259CCE0FFB2C1035C1D26E1777CCA3
+D56A827C3242069E76D6DD69B653768614B9ACFF16567FEA61508D51454BC02F6C60F755AEF6AFAE
+3536BBFA1823F8E1A53C41124DE983E51CEC92AEF4F99785D554488A51C20885346D1F761DA79017
+940A0C557D93F1DB6B3D00FFD61D08E96FF3AFCE5FEDF545CC9F47A2B1BB26713431D6D1E47FD6BD
+6E3C668B0368241F0EBB5FA9C991DF79890E52E83A3675EE699B61BAF869DE91F67278F510061C6F
+E41DE2D883F48CD0E068E2A652B244128D82E5CD52F35F210DDAE3054691ED55A7D99088AAE8FB04
+F525C2084AC09F5EDF80A4EFAFE981F74C0DE9D194320709B3464F3FF2C0F6AAEA6D973D9C323F53
+DE3D741F698FBF01036716BBD62957CB32CD81D3A2674560FFBC5BDC5C6E4F547E589AD0B1CFE14F
+5E17FED1C4A8ABE4E67CCF8A49F32C4C6044F1431E1CC382E7758722A6D0DF9ED23E51F8AD14D11D
+7B6428E27443715EBA4E9C05D6F238378F9498AEF0E7EE4FE6856622CC8E6ED141EE5F109E343CB6
+695C4BE1E0F66601C27975983BF557C04ACFC19227A1AD7E6C44C00529FC7EDD7F886D24B7E029B9
+C395260088BBFB96972199A7B32796D27257DE83A7402291C14FECDF7998C5C96B1EDADE0280F856
+8A8F5007852EED303969180B3329917973C2D32C080C9765B6BAB0673BC7ECFDBBFBEA980C263843
+39B7F1052591D91667D4FEE413AFC23DE2D4B9DA742F4269C6C939F5FC32A38040730A018155AD73
+3F231E4D5B9D01C03A58EAE7B5F590CCFAF25EDC8552CFC8D95C60EBAE1837D7A97CA137E9D4A4BD
+2CD34AEFD68D64B3F4F62326AC429921D7FB3C235184FE0899690A0B775F1A566EC29D5830D32372
+6526F7E7F5AFDD71B77E07613DDC4FC63EDF49051AEB59E6337AC0A4B6DD872E776C9CD0CCB86130
+5322D816732124F5978A86C186BF0A0F88E733CE38E4D7C1BA5378C5629B1EFC97806059990ED42C
+5CD183BAD7E94070E4058569DA2E51831FFE0D080301AEAB4350BA290318AEC582C78D05DD92E5AF
+B4424EA808629BC972E68F4FF2489C245593F07555CA6A2B25964794CF31CBD3AE5C229AB9B8C298
+06C01D116EBD0FF0F159ED2D3D7DFC73EAB4910BFF5B0B0B587CD9EA6E6FC45D63C09766224D8346
+1F0588140B258B1729F70BAE7962189B1554483392988CF230AF4077193E53330519394DD99BA135
+6D4730AB221DC6A66019BFAE564893DDAD7B177DADD16ADD21D396CFA6C3DC818052E2F71149FD59
+4A16DE0C2FFDD366C99B486C55A6E991E4D22CCB15843F0C3363676AF2F5B2D1B7EF66CCF2F12DC5
+0D63776BFFB058D70A9C76DCE96C754872D72C82A0C33F90D49C935402CDD26B6D743B1F43BED5D8
+B539424849C1495DAE73044E885A7D0F307F1816DF6244A6F2D97BFD4E200E93F69B08AF39EA21E6
+E347A47CEEBF803F73B978ADBFCF056789BB8E6E2563DE87DD9A8C877157B934102DCEDAC54D487A
+1BB2694F0034093C48F10A17D32E2BDD0C723CAF59ADDD1BE373AF8C9BEB4415AA5AF36310C31F24
+354A53C0B962573148BEF91D994FE3F3D8450DD4D686725799F53C373A0A3E3C060C2E1A3E800504
+9F26D716E1F381B9F83125E4683264A07E2D8938F605978E2513DD2050B3D8A1012797CBA8961632
+BED260916338A812AE751C7B657E086A0C7DDCD3BFDDFF3E48B84751925736D1310C4910FC114387
+F3ED7FE163F91895EBF55FCB425CEF5729D99BD8F2C072E36C310523E75CD8E5DE49C031C4263410
+9D56E91A46C8C8E89FD92012A00C33D0DEC52597B5C6933291A7BDC5CEDA95DCDA5600F9AE1C8250
+54E7EE1067458CCB66610704C58E4A4FC0CB5FC933D0322A716B2CD430A3AD48DAB3D4CBE9D23F2D
+092368CFC4E1F5495C133A92942EC62118D45C17723646E69407B4A89DCDFD2AB3FFC099A21D9D29
+741D68270629AA3A414FE58658DC9170C247B6E23F35C4BC5FF83009F462F2EEF4DBAC5FD158A658
+57F9B6DC1F5192DFB169DCB65621CAB2F1B07BD22F4155A8E9E2B6388D430FDE5EC1C834D22EA035
+C52E1E34482EADC36B4CAE902AAE89A7284E62B3C84B608D6BD05F75BC31310B2DD3B2C08A00E073
+7F104F03A41989D5F6B9A2C38B22F1D1803EE5D7A4D8DE44E4ABD496A1DE0C0E12C4BC96D0122846
+3F0EA9CE9509FEE987139F3DD3F9D0DF4313F555BE85433718F6D05F197C41A9D9C7A8B0D2740196
+82D49F58DD5F66B12A6520D9F226D1DF1F1B65CDFA261F980CA25A92645B86B64606293F8BFDE364
+C47D2AF2C709BBE77A70A5712F2CC26F3D66F5BE2C307A48E6F887F681D30121E32BBD87271B5DC4
+615D28C309F15AD263FB37424E56DDA6E17B998B45BE6C7FC6C28E3394A8764C9EB2DF5C06626593
+B5C665D550D4600172791CD208AE9F37BC082B0B242B0A504B751B18F4D7495172B697EE217834A8
+A4FB7CC16D6F9E8BB400BE8AEB0850960283DCE725249FCC4DE97D9886745AB6066C3E2F64DD8AB7
+9AA11667F11188D7965DC11EB760B772E282DBF13249F31986AC6898FEBFE23E3E8B8D2C33E00EA6
+FC493850ECB2E6D831D1EFCA3C2EC8EE2E394599091ED58BEDE97D7A43B6F739EB0F845EAC1DF6B1
+EBFE876009CC5D804B15ED4B56761B3CE1AF59C07B49DC798A44532297AD73D5101ED47F36A3678F
+818297CC27F6AAA2AACCC9AA9B6F5459911D8C56CF499E390AE607F3790450B2B9C9BE0F006EDA0C
+715B5CA0481734CFB0597478E7602B0D2C1E4F78F03C68C17C70E4B42D7D2D3C95CF40F73488B371
+8E2CB05A549944D86944D78724E266C3319AF89AE430E777E95F0D792B1C654306E421F3D63A26B2
+1E74B6E8B21B2E2B9DC596D013CDA16D08E65E8F24A84B12B2BADC653E6E1110DE2E709C1C1BED13
+707B70A421B384F20CA7A9A9D20324DD383F28B2D3C7A9C53F5D4C6B7C378D26DF11CF55238BE1B2
+4FA70DCC178DAD3D35670FE4919085EB1CD905971D76A368FDFCF9D2F0A23739851A3A6D2E02D65D
+54DEE69ED5D81315D3EA5E356F94EF256DD267FD1E1A9EDC9CD63E743F299BCC4A4506233B8DD765
+2CA067F741603F93250C087D368F9E9CC4CC1A6DED567487C05BAA992B0056A77F630A72008E3946
+15A9DB24FE56A956650EC9DE90A6C2259189440247970541CA198748928215C0E132A81AA13208D8
+63C1FE817F70CA573B54577D10B73100AF8EA088208A44FB92ACA314AE5879706180788C17BB1D0B
+81B6B95A1C4E0F9EA66F9B39BFE12444A6446691A7BDB03E0F03D9F07A10A7598F2166F108529F34
+CD90E601FFED3479ABCFCBDE8F051C348E48C61D95B00C59EA1287423F05666C3D36288844067E83
+E14F6B5210842C742B89F13ACD126B9FC50ABE2CA7D7ED513D43B6AC7F41EEDA416BFFFCC5C844AB
+2D23D4DC09B2D510504CE98D02E72020D9E669DDAA344C63A1B75632F912A1C0DA3885DA4AF7E243
+E4A4C6493D6595BB6D56B0359106957259E59E336BAAF35BD1CEC5CDE735272EBCCAE8D4904AEBD2
+B32610C6FEA2B69941D6542ECB44D71092A3CF067708A3D087AE99FF29671AB7DD8758759B971A08
+AE1BAD78270D2FBEE37AA2DCB119D72F6C7B0C8509018A70D0B0BE2C6830EF8E0B24B1CE1141EF87
+3A4D7DCC501F808BFD94E4DC0F2915AA023076BCC8006490A43685EA25AAFC187302EBDE7FE1965A
+04A5A398985D29F08E085127B56B057334D88EB638A4DDE64AFD204974C3939536B1B66A54B4DB81
+151853915718F70813F096CC1B0EA25E363B49264C2AD17158A4489F91453FBEDBDE15D7B74D7F98
+E81DF23251785D58295BA297F295AA6248A912CDD4F1111E6B628EECBB5139709E76EA4AB743CEC8
+26621D08E6BC64691CC90B3C3C1778931A28D3D5B1E20E96C643316613FC487C9B604C43463FA453
+3BCA1236286E6F5A6EEB2F1D9C34BDDE4595495A365F88055D9268541CF1654ACF478D384A5496A8
+772EA1402751A093582A6625A0A44816B5FDBE166835D598644296249B92CC90AA3FD6445C9A19BF
+27F59CB0616C7306070F33C7DF4E1DE64AC8C5BB2FFAC1EF2B1B30E5A0275E6004CF64BBE2C6710E
+DCFC3AA4ADD60106334708862FFA6652825BC84842736E47AE6917180365C75B27505EED3C6108E9
+898A780E20C3F606A860229AC46D0471ACA0187D6D539A1B8820F620F72B41AD1D3BF3834BF48CA2
+AFEA8BF535AF74C4562DEADCB63D2F5C7585722B77C989342D190FF926C8A5263B4F25286F99CF6F
+C62EE6E2AD61C82B29D82468AC10FD27764278E5558CE8B41BA111CB2F040914451A480C93084237
+CAC8F66BB7C6689F340B8ABF0150E06D5B1177278A4C08742FE22F42C28680F190900344ADFA486D
+59718C25D37275BCE4DF981AAC35D2C7E85C72A0188B8953CFA516FD545AEE0BF4B8BA301CFDE214
+4241FBDF3D204E3D2823301572E23F204C97305A82401660E12926EE7BA6EA1A81FF5C007933AFC7
+3266FAC4C134ED818A48E7DA01C71A46335C845F9DA5E960B25339D551582B375814148D94CFB781
+FC56093827B78578A73D4FF67B6B87F40CFA5E3F4325D9108CDB64BD06427B88C84105187316FA29
+90B4E3E8EDB6C78ABF164F4A9717D523794B2FE772A04DABBE688CCA977090979B5F47CEB90A1DBC
+167D305EAB231C9F4260C4AD10889CB785169902FC0BED78DA15B8417453BB65856EA0BEA5245BA0
+573F623D215F6C0CF801851C305B355D26B52B0B343645FE25C78A3526841EDA480919A1BBE5F56F
+C10ABEAA3E1FCCA7C43EE560F067F1AA2AFD642F769D1ACE8E2AAAF38850F0D757CD808C921D716E
+96FBC07DA7860DFA70CEAE2888C0ED3CBF9586443532B68DAED9A926655C157A416C383A53D8F283
+2A4E67468112A09ADC837ED8EC95F70852921F50D4417239FC42EE3624CA97F682745CC5E76CC7C6
+7BD99F2180F8C0B7FB49539C8CC474C25C0DDE491671FF329E51BCFA779346D4686835A3AD6633FC
+B5E0F67E0CA9CED8F215BEF4D240453EB2EDD6ADB22278AA5B985FA140C9834D38753DF2014F8C0E
+E6DAD19E8FC54C03C1F6CB0F858986691D99592562CAD95FA0A5B2ABE4A8B54B457D42E8C33A2D19
+51C0419A72FB94FDA78ECD92BD2A1416459E9DECA9469F35E4C47DB531726DEE8F203D7042EDB32F
+025DF3D582547BB1D45F7A5B70D317DF4EBB16E36B0D798E0932FD2A85B04FD67143E4B287A50416
+2C1F5A037CCD780088C5476385AF8168E12D97D44B0630621759173C8F1E3006B5B1C6D7138B7EEF
+C3CC5F54E24B2C3CA7B41AACFD25E554880AAF406EA4C3C6E21D3B550B040FB1952598A7E8E6488F
+E38288B2AEB6C4718338598A2BFE4D2B9D14C65732DA304C16FF3E1F8F03046EF095B65FD609DA87
+EC24A69278BFE65C905CD0329F6A486B8525B7EEA4F7AE56C2633CD83543269E8ACD6D71F500D82F
+DFBDE7F7F7B1AEE67328549232E26CA55085B6E84D9E2E7F74068F93A90C4654F2F396E57C5F76F7
+E61CBBE523DBFBA6E76638BBA3064DA025A79E3A294FE7F1CC28A3B4C57DD6FDC48E541A85534B25
+E1BC11B4F78019457239EAEFD4BE9007D205F1D985F389DB22400B279C10948551A6B4A17FBDA0FF
+C9428B18B43DC76EFB15FC2182216F1B60B4E344A03AD6C00F141EF99F89F24C819C3E32877A927D
+84C2D006940F39CA8B71E5951673EA9BFD1749923219DE38929ECAA9CE43B06CFA7DA1BBEDFDA56C
+61FF6C24F40E59B13870D5FDEB82D981154FAE5D6D5152DE69339359461A41A9713B6BBE47E868C9
+33CD74C75DB71D13BAE4DEC85E02FAA14EAD6C0A253B16C79514657B15E68CCFF9EE6AA385CFF9E2
+C53D9AE40F85C793E4E8FF50B2B7420F4FE69807BC5F37C3E300E6B3C3549D1D3246A2E70F091054
+1135BDF805E0A698E236B6496702D061241687B7B8D1A0E517DF0476DA09D89667A7AB375FD2672D
+CBAB8124E511502DDBD08BA04D941DF1CEBDCCF7ED48405CBCC33774A68C5212FC6F132641FF413C
+984F8B43BDFD7B1A2A3435F15AF07EF4970D3E4A0BB947C181E9CA27CC14A35BD1BD096875B45873
+8CA244F88C28728B74E25CB8C4FC1095A56CA75E4569AD3082EF194ADD11350DB3B74B96761D4538
+596FF7243B1E1B724716A144106E080D42036444FD472998460CE9ABBD05B42AF9389AC452BDBBA3
+A13A96890025789F16B9D92251FD3B3BEB2C61EDDB370A20456E3BFE5F4039E2557C451C524F8087
+015BAF3FF05F51869FB97512968BDB2B49589C1C7AF1E085250A47657465F480B7023E24C76731AC
+0EAB6704123D77977D3A2C4C56B691346EBE589C619C04515D34F81FC6A17527D5D8319013C5D4FF
+27CC3925E24C99231AC7FB9EAF0BBA482D3B75807AC85D03CD09DE5D9AE0B07B7A813F0449786500
+0AE8A7E00080300F0AB8C399057EDDBA273DD2E1B2A0DCEFAD3B332E6D4AC1FFAD846167DFD70E03
+46DAF84AF292D4F424256ED5AC4E104F80697050D50844A708EAC9E7F7784FD01646F3BD0C595CA5
+1EE6BD607D254E78ADDC5E15C3B6AC4940EC865A5C23105B6BE09EA09F2C05D6D76960A843B81EE4
+33977FAAC3CBDA85CDD2F4DB7C28293A77825635992AF8F3B38B4480D9A139B1662345A8ABE1634A
+77496C3F57597D2985E9E54717AB2E99CA35789441BCDDEDE9A9E2106B401D9684ADBEFE40D607F0
+75C179E9CC03E59E65430DB70B441D43DF03F2AA6FF06F224B6E455B01C64FB89EEC9103E48453A9
+749B4D602808C7E408A8903091D85E06AAF635D0D529C3CDD1B8479AC0F4208C284BB678A547F2BD
+77BB17C86D4560434F7AD1937760A6AA55B614CFA9FF8C9C96561AE6C8F2121C4E20237428BC51DF
+2099B6C49E3EFA18E6D439E6E6981E746EBB1DC461259D8EA0F8099C47CCA27B2D982B72C9A07CF2
+1B3C05D6E26E6E286E348B8944078E24809F9C5F3D014B4CBA02533F5621BFBA1F0EDB776C634746
+703C9F73BA89B1960A496420C68F54E5B901A6D733D7ACC79F275FFFB253F389AA480084468BB34D
+A1E797E43B7F6E8CAF5E8C93069A3A2730E57EC39B677BB73E3F07C2055599F7062E53B37A5F0099
+907D2ED87FF7A82C95FBAEB888033BDFD67BA3A6031A4CDC56CB1E4CF5B06B46E16D988BECCEFACB
+9E1C037023D7BF5CCF5D65AA66A17AB361BE7981F132A578F3ABFB97960A6034F052D9D5AFDC0679
+782EC90F240F943A5F9A3D969ED7399254FF67D89DF668F7C56FCEA1FFDCF20481474AC8495D3AF4
+B6D7EE093E369C057F0B70858220693B398ACF8E8143558132E4391405E30A73937C53402E459F4A
+A3539CF7A99A3F51C0307D045DF8B77757E92EA2F51BF0BB4F77D3904DD355665870C2B59F1ED7F8
+4FC71FDD7F0B6C5D3182DB77827CA6A2060D2B8C83C4EA4A432EF43A4D0A952CC6CBBE52A9F0CD66
+1A538973DE41FFE9C5CF55F2506B9EFEE51FBAE5E63BDCF5528499A47C031163C88D3022606784DE
+2F46A9C9235AEE3D4F71D4959B0CFDC5B7E78C8C0A8F9DC99440C2263DBACB343C5C648577F5610B
+50EAB1CF7FD02419EF3941C7CA0B0E64EBAD4B2CB05A0793DBC38F1946D44767BD287F5E9779C611
+CA0DAAA1E7393DBE0683C8D3455CDFEBC0E64B54B737E298DDA605227C0C4BBA87AA3EC7FA6EBAEC
+39E6EF2537D5974391D31739D9FC42983D81AEE44711C823F35F8E2321AC74943871739D2DBE9748
+FE68592263E7713F27E0D49B9B5CB7A4E55DE54E6B800D15856450FFD3AE5F287B12AE4F438B20AE
+9E27E6CAA00F3EAEADBE08432684FDF9931E925544A680182602A3C1997DE5D0630BD5A010535E66
+E1C123013D23966B3545C7431C39B97295BFA4099D14461004C42C85095EEACB9B47C593BC6DB863
+533A8619BAE09095DE8ECA432D4DDD49AA600D277E75DC3F5C6631E2A05382CB007825FADB77438D
+CFA78E252D79B6A196D5164C2FEB85D75ECA25FF80B1D97FE10E87960CA0FC47C41D3A213BF141B4
+8BC3AAA93FA86245064668394665BFD52D12C3BE4CE39EFD8111754398A944C3FD1AFA98EC337BAA
+AF899D35E804CF416AD7FE45FFF13FC6354007501043F98FE8428DE8013901BA6A28711A2CA85A27
+0BB135B72F1D5026E8217581860729E94F2F1878A0E96C59E9F62714FB5F8F25003DFC7347E99007
+8A9A331CB3A6A535BC61866F02513DEB982C4A13ADBFBAC3FF70A7335F40D5489E48E5EDEDEF1619
+1973D932479C62183B0E25EE8C4F76D4F1AE45DAEA4A12AEDD9EF81D248E8D19F8C8A5BECDD1EA1E
+98783EB7A38149170851B1942C96C53DE06DEF80913BFC04E539EC67C110498D15B78268853E5C72
+F485F8A27B768569E54241F6115875E2973292CF48FF91D45EBED627AE9F0766D22201B20AFDD40E
+5B17CF337F2999E0BD15B86E46EB3C18FC12B7DCADCF9DD50C6C7E3F37E615A892DB3F57E250A072
+A49F7277DD6A2C8042698233D35A699B17ECA5DBDA6D250ED4A16FCC893BF0DC2E33FB1EBD7DEDEA
+3C1C39603C8B7E1A5A833A8FCDD5570BD088749BB232615366687962C7E56ED089CD7B092505CAFA
+5A80F503C4CF337F07ADF0D106937E25670839D491F7BFF7A523DB609D126328C16113ECBCBF9C40
+04904427A108618AE5D4ED809F8CCAF72251104C94EC5BEE21F91B179D31DBA79CEEE5EC7FF698EB
+84AB1D2D1A624F58B3622A78844CE51498B2CEF38EAFE259D22C7BA61104651A862008BC1DDDA58C
+C45F663EB26428DAA85E7785363A69D2790996EF5D9621D53042F42F794962FEA46E46F37B8AD1FB
+76FC8D5CF2146843F8CC625139C75FB42DDA71A752BAC48F294E4C0C8289FC46DA5EFD9C91BDA6D0
+27518B7E81E8B21F755A9615627D5812ACA674D1527A1185EED4E3C628196E7D0759B1CAE6B9B7E9
+01E9599A65230F1EE469CD33B9BD9C104C44E3C1AB966C9678BD0AD78111A4E0F2D07A01A038CEDE
+7036D0534D684A1562A17AD64A00F279200C0371B1CBA61747671D2A21D3F9646CA290F6B82418A9
+6FA177C6278277504B7FBA936325F5FA124AB018A15DC18D2C5E8F93CDEEA52BEEDB78A57828D81A
+3E6C38B9FAF3DC4EB7273ECE3EA4482A1C6242A335862C2C3717F9C9ED95F77B140C4E1569B2192F
+C7DCF702D0BC9A50428EC406F8BD0CAF886B4D979320D3E429816D88F7C7146D960AC12E70F2CB7A
+9F4E3E366665AB3F1B4B6440F55EEA26DC9EE0096BB7763731740A537766490C8C174723BF0EB40C
+53701AAD12B21D436ADCE22203C1053A9DC4E9F17AE617888C4B4E6F3A720E4E6366BA628221A387
+D8AB15E04AD69387C310D3528BD2FAA5B22BFF3FA494F5FBFAC4F771C9C7402B95580C5AC4BB3AF6
+92A70CB2C851FA5CF1173EEC3EC29B5A05A0B728BBBB51D3B7AD8B0AF17A1563E82FAFD93F8B7118
+1FB7AFE352874F4EC6D334AB6747519AB8E847B7BCED33EB5458A828E074E74BA621BDCD03FEA604
+7F7B6ABDA01FC7514BA1AFF0D4D0C0CB8F4E42D5A87E395D9ACDD02CCC220C157153422018725846
+009A3ACD8C8CDDB66BC6836B4026FD9F526AA275D06C813179E5924F26A25094E7BDA8BD26AFC4CE
+B41D8964D4FC4AF1DFB0595BC5D6714C32F15DC7194E9A3A73013C45D8FA55CC0550A12D9AAE8E9F
+F199FA28EFC2426D8D1DEFB93A65717AF3EA8E2D5B4AA8EF0EF38E9600F7D4E7D9F1D67A2E63ECE4
+789FA74B159BFE2F91C19B0378BA52E93DF12830D99553B6618645E26126842AB70262D96E35E5E7
+50ECA0CE3458B3E51BEE2F21191136DFDBCA39BDC07939E521E4F492F392DEBD029C1EA237BD89AF
+76BC89F618D530160AB16269FA6B693CF14BDC4EC7C630025703C5337F61458FA09104EB15C7CB20
+AA4C9BDB7CEF3A09F25BC7F3149951A7CD75372993B80CD2112F7674CEFD6AFA764AA3486730D2C1
+897A264D82A91709FEC4A21E30D812F558451804EE6F3DEE2C4C437846BCBDA07C5B6CBA1D94AF02
+9163B7383CAC6E088AB1DC14ED3743EE77E26EA7AD3119A76C0B5F925C4DE305CD7BB3A09A453947
+5B9BD79BE28FC462D8718CE05F9D94CAF3387BA55E6E447BF81A9EDDD3A34E17BE66BC52B0C0BB6F
+86F6F008829173816D205182ED2ECED319864A796AB65D4E3950288BADA94FA32B6F453AFDFC6C39
+A4FCFE60353A64627E2057D4B379D3240012B3BB0ED0C7876CB83C1BA5EFB6E2A03F340C2B576731
+F848F762A7E1CCAF267EE06D621BC33FC245D0E1547ADC12CC0EB58B26BABDB8EAE9CBFBAB93836F
+FF22BDA1831DD01B7346AD377AA298D84628BF1C07433284B0A90FC89F5AEB2651BA2CEA405D4F52
+DDC0E74B871D43F71EB4ACE0D2B401F9348EAC3A2EF0AD295036BF6CF6F870D58E00B619D50EA7DD
+77BC28DEF91D805CD527DCBCFDC16C042BF9B874E3B1567EBA4C1E70744B9E7E5BD1FDA6A5FF6E10
+1613FBE58DC46CFAC1A65ADAF65E49757E9304E2AC9A91E0588600C709A61D4231730073A36D473F
+518A145E141D0A5A494441B9EA99AC23F60F54F8127B477E1CE698BB4129B4B1DFEEDF10D9E665C2
+47A62F112F5CA30B0AE5DBF3E495FF06EB28EB438CE8AAAD84D5F50FB56A3AF002C23BCF66ABC270
+7AC233FC0F2723DB99D2CFE7D3B3667732A531F5DC315CE74EDB9050BF75D29E6430F57CB6778B2A
+CBD57DFCEF896E6766C8FC5C9F9FBD701CD62CACF33EE0FC95E78DADD205B5F42CC63024624BAA0A
+B4DD447832B4E1DBA77BDFADD223989F8E958C8D759AAA37930664C6EFEC708116248A2A7AF3D656
+DDEAFD009B7F5333854608E67E5E588A857167ADF9225CF6C641F5E19C3E08678A281199EDDAC831
+B57223B1BEEADFDCBC8F6F25D32FCA2336C808162E8F381656E847FB6CB13969572425AA05AC830C
+33DE6E030F86A3A85D2A66A77F103C7042C97205526DC882EA9A00EB8BD5519847EB424C15F808A9
+1652A6CC89B66A5731126DEBADE123C63D88A2E550FACDEB3886FF98646000C64B3A91078012CA30
+904B71737CEF6BECABD43DD702880538F5A70085E6CC6015D2163681067C3D513A8C66032C34A0FE
+17A58AD4BC97CA69BF41F11D5E910FDFE9729652D3EA21F8DD8CC19160A8FC77573B1E9CEF4E790A
+79D8AD6723B6804E9616466C935303E063DEE29CAA6C3BAEBF278B818C2EC2F13ED645AB452397BF
+00DB8B26E115026E256746CD0C78A959364FDE6DEDDCD0F441A61A1EBA32C7BC172BB09512148D1E
+BAC9E791B7D51B71CAD2DC9B83B2F99B3726607D9CBE58B499A13753CE87FCDCE21C0AD0528ED0EF
+B9B2C927F57C78C626248AA2B835A0791244C5896686A66173EC9F802C4C633A42B086334D2A4878
+0E53D00809247BE64E529F96AD2F8B3922A6097D414DDE1EC76F9552F9B8D58B8E34F359AD792B2B
+E50C26DB05035E7497162E7C49C38D3CD9B98D620AA67492BE5AFCA3A81A7080185C7F0B5105223F
+1FA77805502A2E8C5FEEA27699858D84A95842C5F2FB68686D59FE24091FCDDE139B6463BC6C7B1E
+0E90D20A83651AF00C85797BB9F53ECEC1675C7EE636D0D9E77DBD8F89670F855EE4D4800FF3F695
+0EFF09BBF8A0DAF6B8242840CFA5BA73BEB95115F4A78BCC02D85ECCE0C0F2EF6F328AD1DD6CC049
+5A3315B414A4D61DA50DA46D7ACCEFF6EE56451805D26B0359AF193531F95F6589CEAD6FA041AF15
+3067F88A0A2FECD135C56682DB2B45A71D1FA737C064EE9A4F404BB72A70B3AF0330359393247EC7
+81512482579865240A23CD8479F21C2C44A119EBC4E81B308DD8AA86E60C3DD8ADA50E0DFE8308EB
+1A7F201EDE8DCFDA405AEFB47E0E6CA7DDB376DCB21D37F7ACC4D3E9F26B03A8DE0E8940CA3A9E75
+963A389DF8038D2C486072F61C0CEAF500753C7A6352B1CD0338D9212B42A4D3DA23D5BDF44C27C9
+4B88A415A3242FFE2E1B332477A21D2B9CE075EE479C6E657A4D8874A8C53964229310E01ED4F3C6
+86FEF5258EDF3B464DD6FFD7F1CAF473BBE722D60FB14AB4918E93878A8AE4773930B8CEE110F476
+7F42A52D9304C55BE12846C911A10AB9B2E036BF9DFD597F5348D42233315FA80D0F563C388BC253
+2103F05E90DBF1923F229F980A2F4585C7A373511372D07DCBACA583099EA972C03E5AA67E663882
+6DB134564DB993CEEB6E7A6659C7C5C05C310267D5F8A24EEC2D5CC3E3F3C808E6D6068D1A57646B
+37FABD98ECB7BAF99E7D9AC4414A491A73CA34C52F394352F6B5A15F0FC4D88622DAC694699C2464
+84ADAC3B1D366AFEDE2A2CD2042C90516A666A19A91C80248B11224BEDDF1A320E230739E755D098
+B6A67315535F4C187CFA67ED817A035056353FC859BF286317996FFFB478A2248B908FF12ABDE705
+402224A3EE5F463DD3D243875C84E02DB968ECA1CC52C75171EA50D6A88CA91327A7AA5795019F36
+C0A19C093A1C9D3723C7568F9D41F2E4FFB712FD47F897703D7A620B586B81936C84AAED61D84332
+B3BEBC4F95B796B93EF7A1F565C494F8A65EDB21E2EE18DC025522EF8E599887CA2836069CDDD889
+88E5862977B7472584303198CCE97EF9F9E1446D1F1F5ED1CFC666A8A0C3A03E1792EFB60A9B4065
+49E0DEDF6ACCDBD98742568B4735A747D8E5DE21E630125AE0C691D054E42199C15B1F80CAFA6E7B
+B2005F374A9A5F9900ABB7409CCD50C3AFCCAB1214E6A856F7C7EBA89BC3291801E1343DA9DAD2C6
+ED075C8ECA1423B43E587AEC67E6145272814B3F191B3C285639F9E2D6E148A02DC2CBC0E054D629
+5CD05DBAC1950400A9189316F0265B86A732D302C5BEE8ED233768F237C62600CBAAFF3A110D5EFB
+6CC7CA3B92D965CA7C5E8D3E64ECF239FE2507FC797FDBE54C1112B28D4DA44C60AB09D994C5BA78
+D663A2591934CC052BC70CD1DCA3325C66C9CB982E2039F5DB70C848D3DCEF655B1C2CD0CEC8865F
+E8E1C0A267BE4F707ECE6F5A3DFCA3CC1EDF92C760439F51AA69A4C1801E96CA4D6EA4AD980258F3
+D15C893913ABCE09101984C61B91D603053E49A97CB82FBA707DAE8AF1D579FD69C8481CB7B712CB
+CDDB4D287BE995E32C02B399602A08B9DD849039B5673F1930BEC7BF366EB082D2CA5DB2385C8CC4
+5BE3FC0E31820191A814EBA7C4F23B1938E6C4D800732787CD2CB97F762DFC85D4B798809B5F2254
+D826CA42B32695428D120298B44CF38494E56240B75DF1E41E46E53C44DC505452256DFEC819408D
+605FF14D6C1F3F152F2FEA96EA0AB3B472D8704E06BE9F8C3E8395CAADD06D6DA033E81ADE5DC3B8
+3DAFF743C6E9E48716003D358DF63CD7FD3E2F727D1F2D0C29962F76D5C95ED44B6F08D052025A66
+5785F264A3D5F5593677B630E628B5EA81FB37CFFD7A30B7FAD226B6FDC82B0878AF4C0EC4F4243A
+807B9839EA62BCBDF7C2E9B30A623876E632E084EBF4A21EDA04FC88A1C07021D0C72EC3E969D449
+FEB08E5826EC20E55B21EA71EA59F6E3B0710B0DDAB3261B4A2029ECAB68C19ADD5174E55D5E984A
+4E5F38F592A302FEE6ECE732DDE841A28672C620CC5D687455A5C06FA9FE688394A04F96312ED025
+B7AA6FBCE2925F3AE559CC1886BEECDB70822E2E5CA3F732A87404B1536AAC469989E9610CFA440A
+CE43875A70CA51F36CB6F629D9424C1E35A88F92D5DA3CD8CBAE6E8425A36968E21F4F30349749E0
+205BFF8D552837D6FC39532525370BBAC833F75F1854C93FC533A4AA53ADF7008173A70D94A4EBF5
+38EA9E62BCDA7C20E0A073BEE2EFAC34D2EF1D03BABD5147659E50B557045B2EB89DB303749B04D3
+F54B43FED612FCC68206E001A7AFE90230D9C12F74A32C7EDB5D0241DC3A5D51481FD7C8FAE08FEE
+263FBCED7C7D911B3A303C835AF5FADFD218F61A9D6DE80485ABCA88200047B094441F7767B97A24
+E8C612590FA2407BAB1E8B56C71914EEF2355DD97CFAFCC192BC06FCE063D3D9D1A629AADC75E3BF
+207234C208E7E30663EDD691043065C9CBC473D97C6D4DD3DFF59D6A9ABCDD4412C3128F603160AA
+D8F81C6E7A4DCAF35F3A99B4EA10A34375B477C2BF846521A7EABD4D28078E9340452A198F3F5ACC
+3DB7E3908939FF6E3709C6A3FD9889439A4AE3E10B618CC92E14B68429A3AD2C80940A1079452EC2
+66F254657BE7D79A2A24084AF73F6DF71FBCD32BF6913A3FAB25F977787F7BB0C3A3E8BAB38D7A2D
+B0B4826950643DD1E03BD7DD1FB149A33862A89226B7CB454DAF613128C2075470E42E70A9444A8E
+6ECA526345AB48E6F5160BA23B5BDDFDA6049EC44ED1461C7E0DD514B16E2FB285F72039DE3C7982
+EFD40D7F6C8E8F4CF35AC71B467BFC578002E8D2239A2FD2C4BCCDD8AF3D7DB1F4AE7F2D2E0811DF
+9D0155BA6EDE50B5F052F14F6AB884FFF244D8806C07EBCB49ED22D85DF696995991A954AA97A1EC
+D86ACD76E061B7541E87997FEF0657A826BD88EF3A4A5920462C6595E7A156F453291CA044CED810
+860C3B0149BCE73BECA713040664AD0591304106129600AF71317B0D2907839CEAC99515D357E980
+B1937B6E1200AACADA205421001F1B2F91753E80D2263C56AA164A74701A8D5FD28E46480B0DD963
+A683A1F355D7FB4463C7347C94EA5E2CA40B60B56297CB22D972C5BB10E56715A955605256C1541D
+9F3BC5768A6F355CD3B863F0FA1A781EDB49368F51B29481CBB41D4AEB07AF9DBE8F52C5D0FF75F7
+FB6431D37D6AED84D78C778871CB0F715B4F07580F23B586C969C81B471FF6A6C7276F7E141E02A8
+584D4B9AB00E7BD643D2C3FAAA299B1F1E25048461952EA42D4882768A70DE46B213A287F8D31AC4
+6D5436F22A796C05D1FE50A9BC2A928066627A0D87DD57A3AD91DB446404B41557D1457873482005
+EA20916BBE46C613F456C849D46BA79D20627B446B2F49E3FA309AE14F8C420CFD94922CBC0FB9D3
+5A0F7DBEF577F1849A1A80E0011DA8AC082A8C6F61658E65AD177ABDF23EE17C8CF0D26B9FA3A6E9
+4837EB9E930336889767A8D7EA3CE980A8EA95528B004957BE6067CD9BD8E02A0F23CC1762CCA656
+D33412FF45E917FD4A03EB6E8C1F43FDB0A8965A33B4FD26BC24A20B304CA817E88495BA9B361A3E
+933717FFB0271F7F70C5D3CBA1E86D0F51BF3ABA194DAF32C35C796627D00C7B2271ACE2463E37E9
+7B3C826CF3DB60028F240F9452CBE08F7EBCC5FDB1BCBB3C327A9F450B9E5671916101D6E3E5E458
+CA31F04D12F592F83BADA2C3683D3886AA3B403963AB5DBE220FEC00037A745839F67A3635DFD3BF
+F08F367482962DED88ECF6322852D643A54D5D303EB04BFDDEE9BBA1EBCCBA7C653B3A613A8E719A
+DEBE3CE1BD7E754E5F4977E863E3C2D388A65227B451D4F3A4F94E06513CBA4AC1F2F511613FF035
+611684CCC461599000E546E4D972CA6960E095A526E4735A23421A4C9B597ECE08AFA2753592BD16
+DED93255A1E33DEECE3C5EB77B94670E8137F2A4A4B98AC193258E7DEA5DB8408A806188F2D1DDC4
+40CCF0E9A6E2F0C78FDBD7B68DD4939D2458C1965BF8BED4564B32462FFF3EC892C03B11D3EA813F
+AB4CFBE8D3016329C5B7E3DFED0F08284D44AA0B7A2F6BC96EA4503E8EF52A64C22BED6B452581AE
+8FF8917D53976471941A9116A2D878FB2541B561767ABD4E31CCD8A590CA03494C62AFFD64EA0A1B
+C779173DAD84999C7A8D844EB1259DE7BB5B25CD023537A474A524EBE4660B22568949E624D8FEA0
+AD37F4CE1EC75955EEFA49C6BF1803BE87E9C9865FF3F6B8525B8C15FE8835CA153D27E6C0FF0CA5
+1029A7A9185D25F0F14D86FC797DCC1F99EE97E2054B9C2A2E06FDBEB8DEF6CDD368BF23A858D9F8
+C1DEFDCEAF1B4A8DE5EAFC604CECCF0D285BE00AA912EAB66EFF4D37AD2EFE34853BBFD87CE09B18
+749B489943EECAE7887B006FB827D10191DAD18466CD1F86505879310A8B171F902EA0C26A388E13
+B53C700272CEE2BFB47ACB58247C13449C6BB9D01232C32517358F1A3DE064D43C18F8827D53789C
+CF3CE2EBE78949A6ABFA1A6B8414CE360A5E22AFB7D1DCE6F5A06182C3B984B4F9BB1A905A9D5A14
+83750A1DE0A857CD5C06945EB7D4A2A6BF1237F32A154FDC06D51A703D44FE052FD3C53E9E8F417B
+35D1C851F9203A8997521529F21AD8498F96930AA77EBAF82EE02A57BC77C792D9F220294B45F48E
+A8FD94E01CD25645D36D168923562F3FDC93CB79DD4760DA0C103C2675722D7A1B79FCB4245ED12F
+A0DB52492C9CCE58B333CFEE822812F7DCA68E802C451B5CFAEBAC608B950386B6C58239D1C62D62
+4DD5D15782FC552222CCA06DDF387B373E32C3C2864C63C768350C37283760F3515A5B0AFD66C48A
+B522EB3E808C061F5CD6BD96CD18C9839D30508E7D4EDB88E8F11E31E10919B16B7971F06D7877A0
+58D8A4944C84FC6CAEDF3341B48B6E0D3C7B85D710E0C35F5B5053CF4B4798B3778CC28B2DC7AE0D
+F3A49F9F3BCD8E95D746C35C3F47D68B8AA35D97AA08E711B5FBE70D1A623C82541EBDC51A827D0A
+69E6C049087AD26F256EB7577F58CCFFBCCBA5A95D093DC29464C9A38DE95BC6B1853963B2DEB0B5
+7AD1248D6F1625E115EEB9510B5772AAE4E3C866657DB0B3BF0E0AC345E116F8D4976B770876FFE3
+748C36165522991F46A36F193DD1A1C94713673C7E4C81582391B636C72DE94CE6254374F99B623E
+5686C13D8A8322E83E11BB0B0A896C6A8C2C4F756C5385CD7017F26D23F7C3EE97372C868C8C9155
+81723BB6B76B4C3CE8998E4FA6CA40B633DFDAA59BA902A4952DA90EC4FC3CF0F2676ACFA7F76F78
+236FA2DE10FD3545357215246BB7E527F277C28B353CC6D79DCEF21BCC8F77603CDD58A2CCDDBE3A
+9802F941CED8E035313875319548C41992A2BE939A17CC109426E33825AE59BCD17CB19F50D972FF
+CBE7D9B4B0BB095303D9DC9D406696C2508D6CE99E11CF00F6461147E97449ED5F486D480A86D3A7
+ACECB7E9A945984724EFC21C5079B1FD03ED803C2DEAFCE3327D2D7827715FD65D9506216C88B0FA
+26935E95C64114A51919D419038B1A7E9C1E829FBFB53275093752DF19891A97F3CBF7719C1FD6CB
+17019A6D2D25360ECA804C4B35172662CC4769D2B785C6C87E5A4ECCE31704E59F71263B7C3CAEC8
+ACB4C7426EC25F11A0042323EE6C3EEB04284DBAE2C770BC419DCE79BD4560AEA41571C3B595F525
+60191DC7A8FBF63D413A77A0905E517441B16C2B501EA2F9E99CC38D052679F288FDF1894542E3A6
+6989A0090185EB2E75134BFA3D9147C3DB8A621D9D35E37786853779E157B47F71626D6B3E633005
+9159C17596C1B87FE2B4FF47ED9D78FA4C2160077276C8B58CEF5DC030B4A5D83CF257096C047FE6
+4DE307C598B815058E72D5F57DF5C369E664E137DE29349E2F9DCD8C9F4EBA6E765B6327D7A20DFC
+B20711273FD8091CBA605C4C494248076F7E03DF65A6A50164980BBBB708741E5BF6056E6F996DC0
+7FFF408C5B8EAB8DCEC315E92873228C805D4440A6470E3EE3983758DD211C9CECDBFAA4C9300CBA
+00608A4B2404A3C7AF017A3B7E67F39F0B51ACF950D3E75CC7BC2B8D3480202FA958E8EE0B240501
+5232EE0D264C7CA02C18CA45CB3C2DE322D3EB7F00F9455DB6C5B1F4E59C3E95520EC36D7D903CBB
+625D70B54BF6F8255E412604BBB29FEE026CC660577F91DB1DB4A613EEEFB20CF7AE3CD89D565AC8
+38416B01B5DE4FFA5550D17FB51FBBEBE21CF1D56038863EE931B90DEC2E211ED42BA92EC244D4CE
+2C4EC5CA87A026992772DC2AF754FC982B94F36EA7B7BF75E0ECE90CBB2A6AA1A012E8898BD679C2
+3CB3827C35D5D02F0569C7AA82615D4AA67518ECF668D3B57D6EF1A8013424AC2268BA0D9A74D588
+79EDCF6382A89D397864940303EAEC45A38304BA8B1CB198967AE23EB81054BE74B16909A405E8A7
+799CEE3C270FE2A6DC50BD7370B6B2C8FDB9A87D88D5D40348D3984E39C693B6F4486D994778607A
+80A3122872DD65E40492107C71C3CF708A9717E9EEFAFBDDC239C53AA9645B711038E59C8B861B37
+411AB2039BEDF9CFD00F08D9C5D76154427FF5DD39878CECC5D7BFB3F1F035087185C0981F3C2139
+BE84872FFAD3408531C4EA9387B89F5E3EC779E8850D50992DFDCF9132BC551E985943B07618AC10
+D1150451F0844C0DC41D6E17EB508DC8689EC726400D5A7F6FEB3CC7BCE05F09228B7CB2C5393664
+D8DD9A4B96B1020EF25D70AA2D91CAE93AFB5F2BF0AA18CA5C599FA1A708EF35BF8F7FFEC9AFC1F2
+42870D028B2B1459063B493943EF1283829783E1010242E5CF4DA39D93D506F3892936E7D6CF1124
+70A521D397438733D053944CFF12D6FFAE8246F20618684F263715AA98E15D72A526383E05C23214
+B78338E5B476F0981D90056E6E5D0DB66B1DF2298E597B2ABE1D817E18BEB056E65EDB4234342D96
+00470B1420C9210419D834E431B82F58608C87AC361A02D0F1FE4B470A3D71E0D21BB87E1023D428
+E23D596CB9E1A2184403A16E36E644BCCF9BBDE27290485057E62827283E7380AF786BF395B3961B
+A5EA469C315763FA59E0F176EF81985F38B882DE56A74D128E256D1B89939728E55A92ABA21A6B78
+44FAC1BA7BBDD8B34A18194A2984B000380FE9F672E83EFDBF276FE797A325815B0F25CC95C97A9D
+ACF56D583486305D7C9E51A7E337D14E3B900333EB38FD93A99587DA2341B10C059C71CE080FE753
+3C0F059FA40E560AF9C4A41A4BE6FB45846FF8F78165E10B4AD40F264BCF5596A1E8EF8CB6EA4B1A
+3A5C69059AB1563843679ECB2511A90E8898F54295649CB73D277760D8D04ABACC7BCC6E777A0530
+E2067CCBC08673F9C8C178F9D672AC8A15E5367F0C5651B53E75E0CFA57C931746AE1A679C246D7C
+9417F1CD89DDDBD1173C2F880B7B3847CBCCEBF99F7122E832D7C9BAFE2B54CBAA1ED48158DE3F36
+238B76B0E67644A28AEA996DDC006F6AC0242E4B667639E7523CBC90A0561193C1AF34481C2EF402
+EE43A82E1EBF4E3D601BB36B2D95CD93550D61CEE7A94E72F6D30C32C8F91A61E964B1F66ACFC398
+7F95D4028F116E9A9A8474AA29C1C1A984BE0E393BDC41DCEF6A6F1018DB60D52024899D8EB5D55D
+324D73F39BFA47377B9E15B3B06A7585589FCF52A54684173E5183367E7B0952DC4BC2767C4C6247
+B1D6103E52BC7B7EA6298F454C5D97AC575F19C10ACDFF4E10C7D3755CFAB4200CAC545269FF1D8D
+B0D607C7AD47F40DDF257AB4E7D0750577003C13E4941960C3DD7B0774DDAC18E8ABAF8F53E03CBE
+F6D57B44F24CF821014C064278FD51B3427593D17694B4ABCE81F49CBB984C5878CDF0C38D1ED7FD
+99B0B9A3BD8D8FF6219588B3B8FA59D0CDD1D9B2F65122AB45E48F1757467B9204926140E3C350C5
+A927A2E700173053EC35D3F1DA2D7258714C97FAA857F0898917BD94625C6D1E2D77138EFCAAAF51
+7B17FE187A2212C24A881A2C6A647DEF6376ED80AE4175C5EE80921F001995B44E49F0D33DD9075A
+CF33BB03671C0BCC34AD5784AD1CDFED3A6D9BA103B3DDC1CC2DE74DBB576A0277715275218CD19C
+A8899209125266D8BF1286F881DCC2C383749D1E768D670F4099F7DE959EDFE852583183C9111601
+2881A56A24AAF020EA45CD5F39660DEBCE30AC1C7B8CFC60387B1B0C3E361BE612FDFA9F01B7E4B4
+A18839A2C7E0E393EBC5AD9A8A4EBC316A740C1C295D9EF5F4DFFA0667F9582C0BB837B142C4CFC6
+B1798E9476D0631111033B8BA75A10FDC800E2AB1E0E829632F869CFE4737BE9E2800759EE0831DC
+7D1195EAF80555771981DD6DC6606812D92CB8EF86447F5F6C6F626D0E265C67E52A6319189EE349
+D48E49DFE6A9E98F76C414A1E3217AE0A215A17E54AA498F4ECDC50242ACC7E2322F63BB2FF2189D
+057E7354E32A3ED1803116176B9B9D0129930F919E2FEC280B2C8924E49E7BB75768A2EE1DA8ADBE
+D4E3589906DF1B923AEF84C1BD327438B731012E69BB0D43A1842CB88BB54EA4516477F704CFEB28
+6E3EA483445AD4D74586FCF32E96D366901084365F693A53C5FB532FBFE7BC0CADC404C4985042D6
+8DBB90A6DCDA3531EE324D558A214F935CD9FCC9A0CEBE9B5FB0323F4B3820529599EF48EE068B5A
+CE85004FEA2984F0A86F5AC9D56163BBFE1142B774148F1EB0A4DC89C3349052533A7DE66729DB24
+41B82F8F7360111DACF69293C9B281A0534F3E9E9224A75C49A832F28B2E497262475507B6DDFA9F
+01CA0A6696E3F5AC7EA68595EBA0C2EB8A47813FF936D84AC1B23ECA7AA2862B793CCBB0DF9FDD49
+31BEF354CEC12FBF478559FEC29F81ADF4452E83963E56541D31F3691C93A50F0BBA5E9552C4F2A2
+3A6E53060729854A3DD71CC4308B91957DB19E66AAA18FA67055A950F1C2CFF78A03BC1A588CF624
+696068068719AFB1001C4581EE072113882D9052B21E355D401ED8CD24D067B99E616BDA5A0A5A93
+36FC499632B79FF2FD0DEFB096EF46B75E2D4E0F48DAEA239719FEC4D9A29818F5875FC5041A9EDB
+D26CAF0ACE14CC80BA49BBA59E918EB3D8F1E541AA16026585A2F72DF7D83541816DE46981FB3EFD
+0C30E458CFAD04C79421AB7C4925E23AEA07F9F018431C790002596D26BD9663B51B699DF53E4882
+CBC34EDE88EB55045B889B6062E35FD1E018BCE785157B85EC3B9CA6C85D4B16238275385B8285DB
+012D8FB7C9F5B946A41D7A0FB878FF72C39683144D8A007CFF631B43748F2D5FC690300F9BC0C837
+006B92ECEBE0605E8C3A4A400E18AE8997D1B45FEE10068E247C647CF82C6DFBE5E881D511FFA687
+B7AEB78546BFD07D5F7EC242DCEF4930D8AAAD8C6152B6642AAC325963FD147F236BB850A9966573
+9D06CDBD7CA79A527DCF461E33F22BC9C5DB00DA2BD3DDDD8C99D99793BC98282AA8872FF96C3942
+85D82D9419EB78B6AE37A5F519397700F75D624A09BD255B576E955A323E784E8FC31131F003B0E3
+024A4F58FEF2A6C043796201FC425482E1155E229D1B2D43EF7B0D22322B22EF5C9A1BE026A1C3D3
+75EDAFF99597E1E5477952A4E8D2ACF5D014BC00DC2A272FA62B6983E27D228881E2EF2B8B95A681
+CBE90C5FDE16331C85222FE2A16F0A3C3000A63E2E21666C0C119F8AF89A543D37977069A5ACF155
+6324F05204CE8CAD50FF4FB630D9CBBFC324DEDA584AA56A99D3A76FF55BDC2C2EA3A021361CCD4A
+83C7A5E2768D210FA6DE889FD48A39D679C94EC3C99A8D33FF11377DA7F6F1B71A2A05B302ECDE95
+4F26773F39AC881542F0D0969C3995C3519A8EF70B4220D86BF01BEECC6462855E7B686E1AFF1CA9
+1FB8FD8B4A69E10EE0C2AD94ADD44449506F9B6EF43641F2026EFF6E605C670560C2B74706FB949A
+A7E8CC6A2D0D6207E457E7FD87EC1B9092DC68B9143947CC8ED14AFDDCBF8FDDA228A76847F96802
+E561F67CEEFDE45AE587673983FC04C96744DBAA83F2DC838D633943C75DCB9E6410474EB27B348F
+26E505F0AB90878940E846C5E9F3C5FE8C3558C3236B1B88C405716949B8506841CABE1717474BB7
+C30DB91CDEE33B0F844811762FAEC535BDCF84C1C747CEF9B1FA61D2AFB5A81335BC42C06A94D7D5
+9B7EDE55BCF6F9867AEE107555CDD084B7684C2C87087475A39A9DA6347BE281CE5635A4D07865BA
+98CE26C1465B1AB0343F49FF37B4D0CA9F3BB693D78DC3B21925CB996A038DCC172527FE57C07460
+EF39C07D4396E7FA970D9F22ABD21A9C794B64AD96762C7428F59A8757C36D6C4FFB23216195A04C
+2A2C2E7B10EF7193931544D782FEE4B91E01119C5553BBC6252270A8D8C56DD62D448F5AD8DC69CC
+B45E1F17F0AA1E445129DD00F000005B23D38DE93A3BE55A4C041947F36B4E4536E307D0180553F9
+2E46B743881CB5D5386C48C7D5F84C2BCD06B9C501F78C7EE61FA23516791FCF4DB278AF688A2E60
+10A56692AD92008497487EDFE4BD5FA083FA544138B20D6940020887E35D46E093B71F7A04A67460
+DC8116B4D4839625D7CA6959D6831CD93F81AC4EA2709036DD738364FDE71113BF22EBF13DFE1642
+E564701E6F0FFE7511EDF03FE448C2B28C64FB7D54B94CA576E481FA56B2B18AF10C71F699B6BFD4
+7459CDE1869D0FD306BF489A6F42E5B2F05CCF55BB6B9526973D19CB134CA7F13F1DB3716F8CC217
+73A832568C16250B5CDB16DF24BF81D49F5B37018BD310262EA7078107868AB0216CEC83CEFCAB1E
+9F2C665A31585CA04DC01879CAA79AAA5AB201B516F7052B01B16BEE5606098393B0E5D9F9E5E3F4
+EB20F63C958E796DF41CF28839F5C62A0431648745D7837B519F3AA36BC6C08EF040CCF53D9B6D8C
+0C7D1A84D707EC57A3C6AC9A62AB37251A01A5ED40FDEC6F5BE6E34C6A91D058319439778A2EE5D0
+363E2E1F33463C33327D05FFC0CBF08D5BC457C7230448972FB9B4D0D782BA7DBF10D3FFEF8BF523
+6EC16D4DD6D0D870D9D5EB5C64C9A46A4F583D4F831FEE74B0E5B33A09ABFD4444929BD8F638CD72
+EAB99CF2E9551DF427683964A592E49D186F285258C5D5F62196A98532421D73E3495F82695FEEC6
+E1952C562D546B28618FFAEEBEFF03A57F4D855021F85B0C7BC37FCC6DA9AECA099B646B99D41896
+09D3FF2D56422F8C37E97640293EC7C90E3380887836F4938FBF495CAC14FBA5648D89282D8D49D9
+1AF73ED36581139D8BD42551E263E830EA3C6EB381D85C42D74C50DB0CCAEC03F535ADE92128A016
+0E811C34748309AF7604919B66CD43EB5CA975302DCB6076FEB6BDD6FF55976FE990FB0CE9ABB11B
+195403FB26E3D6C6A0DE1C5BE79E171A61E21F79EE8DBE7A832519813EF6B33EA098C2C32ADEA219
+AB2AAC8B093F40000995539D1276D5F2EF84CCD099B71FE4269BDBDB6A8D59C86F7D2E3FBCCF8773
+D0FAE97640BC1AD43CB4B992BFADFB09DBD0CAAEB8CD9DA264187C4F97300E9A6C9DEED5525479E6
+05C65AE336CBBDF4E5D7F79AD098F977285E065579B748FEAA97F2A753E1F962FCAB68D72BAA8EE4
+FF6691C23E31BC0F3E981A96FB440404856AE1AB32A7205B17D411D8F21C8C93B704D07EC594422A
+BC368CDA2B1610CE6A973F4474E12B78B532666797F5755D269772C9F5400B3BFC6C58395D38527E
+2CCCF29B56123F7DCEF3BDE5DC1DFC5B0293BB125085B1D2D929BC3EE84F4FAD571A4991C3DEE03F
+2DB3A3097E52B1A7D5C73CCB6148EAC62E8E36DE9A71C57638C6E4D5D9DED18174E8C390E50B4A5B
+913C074EEAEBE390B214B3A68F02862B9A296DB4B409769649E51D738CBBDFB7702E15C73C2AFC6B
+C37CE15171F4E822CF20EFE55D9F061AA43E648989628FF79E65932390CBB15D8E621333B18B11C3
+BDF96F841D7434E01AD501FEA964A75B248A35CD9DF9A37E48A1E5A09C624B93CE44F0042FA00D7F
+9EE89B9F7AB785E9C718CF6E7228F743271C2C9BBA17E5208B920E44E765D99D86650EB454B0FAAA
+112753AA1BD3A24239E9C5FC47EEB1547AC9D23731B8DC48B9707830DAEC60C8D3790BBA1120F776
+4EFAC542CFFBCD5C05F9510B27B2534B704ECD36C8B041FD49A96881302FFF5B0163A2DD09C751D6
+D6AFEA9170A4F4C4AB8D46E62F763FE1BDA51DD1CE4A27E772F3A2869155F762FF26B7AA6FCFA4F1
+292E56F03AAB6322BF867E7710C34D43B5D85B45AA68014AD7879EED051B1933E491496E3E26D9AA
+8B80A07BF2B94F1077E84A9726F08199887D66DE7A307BF33C30DD9CF3DA188088C03B2BAD09A217
+6B110DB2C868B53DA9A66C85737BA66C93C58A259860E294AD0191E3A72C73F40B0BD98699AA08DA
+F03587B78F391F3A4313C58D9F29B53C70785637BD0C58310109C54091AB0A34CBB0C478613A7AC0
+FB8F0A8B4645AC966395D8BA775262CD291136AFFDDF01C1D83DD4EB3B59CCAD18057FE7D92A8CD4
+A58F22508D9FD7CF356571F701BBB23E749BDDCBF8A317FDA0AEFD952BB18545610FFAD3AC143D35
+1B8DB3F66293375E0E50235F0D0466932181D377EDD32A5F0FFA4E22B5A0CB4F343D9A7E4A342E9D
+09DFF6C697630CD3971802C277A5590B8CA94BDE6B38446C794D072BBCCB724D5BC208EEF1B018D7
+39373BB910D668882CAA779C2D686081DE6A2606417B54D7C20E0E7F722648D893E4EDBAE8F00D6A
+6DA3712F91AE860C756D1127D133AB828E9D80023B50B162C5A1C5CDF70CCB3FDD7EA060ED20838B
+E1E50C4094C9E79E1A0187CDF780CAF45A725964F004253E034C5BE46BBF89D94631F1A33BAA35B8
+4FA2A9D08481C6674126CD96ED05DCE48BDA069D902D6836D5DFBA701DC0F98A863E64F0E312145D
+8DC0B77F25B43AEC729A1243B45B08CA228DD6101CAA2AC5ADCC8EFF84A4CA3F254176C2CC711EE6
+C273835D0FD3528ECA2A976B88E51FE347FDB60F32370B66D338931D6581630ED586F349C638960C
+31AE4204E89521A96E1219E696B913DEB2AAB7A3B022D06F34FDFCB810A04E60A4FEBE284C2F063E
+0AE9EDF87704921CCFA193BDC912B747E13570066223A49F1F6E2AF0D4D65DA04CA876FF7A462FFC
+9C0BA2CC545C3BD36DBE762F32B2D6BE5867C59F479195C92440DC165098B74EA5C3AD93CDF2D410
+B04C16BC7801E7956F4E5107450787AA592493171C3628E6B8F49D4F8429EB98DC52EF025F001387
+BC1A7093F7A99F10B5D2D7DD8BBB393BF6E56F08F4F7FA1A343F220D5A1EAE7168C74D41BE1DC1A8
+3BD65B72B982F4F7B34F24F97F9EC9A91011064031FACFF2A14921A32024385F4E061CD07D152E74
+1BF97156D951A342488FA7F5EF934CCAD13E2753A0AB7A1F565C2F7F6B349DF03BBC25BBD972A9AD
+F809BB5C5048A8CCEF9297B2ED3324D18867F293CC66E88B3A39D107B610DFE79A3B4E83A96D3D52
+A17FE8A62C9FDD271130148366942C9CE57558D023DA5F7501319EBFA33DE9E6D1E76D7C20DB8A09
+B657839DA99F3D8143F1EE6253A3295C9651FA4366547893C2DC7ABCBF4BB7609DE5D001E0A36D9F
+FBE01F7D0903B3208AE8547E2E5F14EC1AF4C2535CA8F4EA37E3F3CE172C7A1E8308995B1CC23E6E
+81190246BCAB6E755BF868D449BB02A2AA87C44C9CC0F571ADC72547CEECBE104BB274B8AC16DCB7
+5D5F458D356466B921ACDEEAE384E2EB1DF6EF393B41B9747F0A4FAEB4AF1928D9AD6FB7E06FDC62
+1E4C6FC98CFB43F88584BD55D9B97CC9549093EDE586912161931162B1B1D52D0443260DABA02AF2
+B4432100D5506546013DA703573FA8013685CC798CE501960093DED713FFCCF89CA2B9106390198C
+29A00864108CDCC1984A8BAB53919028C01B26ECC7925E38CBE6CCA8978EE21C2B06E7B3E48FBA97
+8E2A7D186E563C088F84AA23178B60E4729EE87D67B1091F3B6973676C1CBFE6530EB773C62E2C24
+97014AB0E8B71A1F4E86A378AA26591511BEE3CF3D64C94848582E1354E1605B6457823F2C5E640A
+D3802946BB2E7E8E594E8C04B430C2385DD40746CE8534F50842E74D7115F3DB0C72D1C9C607C657
+3B094AEB73B7A79876CFFC3E2F8C9FEAAA07D3BFCE05B61F7749A8793BE90CCCECA2D7077F25E899
+D3331FE161A7E86C842495D584C6E4A0880B2951D8A13B88C4672080A0B1BE36BF47C3ACE7288CFE
+41A8C1BAA6F0814A947FBD6B3AA72B6C73A8C578CA51CCC96F2352316C467BB960E981F2B6485BFB
+44B577E71EFDA16E7405954BC7C9F0759F5A9F1EBCD2FA9CC9648D5831A68887F41B15081A204C24
+B4B992A231DEF9E698D4C3A25B6F5474F5BE6A601F2D337A58A0D21FF37FD91EB86D1D738893A03A
+69F0CD743F611CDFFE69DB2C6ED0E4611D56F803BB0DC06E7FE85A303839612707647B1BE9FAF8D6
+84122CA9E5CB8BDE2936D3F4FF254D31529D7538BBD4D35539489F9E7316F24214B996BCDCF1818E
+749A71CF0E8845AA1E2A58AA62A48E02BA4564625D20AA220EE719608521D7D7A7FCA0BD8904A401
+9819D371F3F59D46C1354E5FC1A6E5F79B20CF4ACA2BF0F2DE73DA193A6F9ACBFE0B4731C4BCEBE6
+D96FE822965DE965232282A3A130361F188B3AABDA95A8A2790D9240BE008B6A6DE4BBFCADA05B67
+86B9BB8E0DFA0C30043A3B07ED46277E07B9808422C8ED16758B9C396F4EA929D769785B2C9568E5
+70A83B989B25CE200F1727D41E2B702E7F88F1784F4C83FA60A74EB26B2DA95126E508ED519A61CC
+151DB6804F61826C5F86D8FA89D06E526FED97A0DB88EDB432FF32C1ACC9B622EEDF601081AF7B96
+3C9CFC1D13E4A9C74FEA0A1C8E3D8653CD92A944D4CA6B0D306619AFD503506D77732D6514F604BE
+4610C2560931BDE0B40939BC1D126B0E97F72AE1B4A9252123B54F7A27E0CFA4425B4546526FD741
+CA77952B10D13E0AC2E32006A903808FF0CD013F936238C74CC75FD915244C56A8412F37F0134840
+347699508D6F3D7F3203A25B7C70100719582CD588590EE34B3AB13E255B613A6D00386A0104CC5E
+D2C646F09A88888D3751651D5646C5227A3C80E8DA1B0A331121DD2429F1F4775D30564DFF47D01B
+BE2C6C72CE4D1FD9A2077C04D2B0274B8916F6A9D1A4A6964A534F47CF241D5A8E34B23F85BE9ACF
+FC2FEA961F277539F215F8728D6788F67BEAF45502839BCF23D8763C3949352F00C579A9A4FC408E
+C625E310DAE61512DFE6844E82D36A2F81709E1F05B38AE9C222ED62C961EE63593CED7AAF73CE2E
+D3667740C77B309B93EEFE1B4BA65D48575A66BE86743DC9E5D3C2FF418D11F7F211B86E827EE1DF
+C3613E7498030F07050524536D1F8A94DDB6698BE7B963C55CB3F74B676CD815A7B3DF4B1A0EA2BE
+1B0B9A11FFBFD5B1FA49668AEE14629316AF436A0821C20BEEF7B3480847934A99F6D85B68F4DDF8
+859A754E009428AF89A90D1852C220A607FF0806E8080726EDC94D691D214B4521C147C4273AEBDD
+BB4A697EF16448CD9B2FC95293305858DECFD406B89B9F3FDAE2AC579E80CF321EBAE5701FB2F7CA
+D8ED04B4A63115886D45D6120F69AEF1A21D80AD3C2D35D2899F1902242B96CD349E0AAADA40F7A1
+1282B6B52BDD97708E58DC5E2D22D1153E5FA3F3B300BCDFAF98DEC2F4E3C82A1C85F985735F3987
+4F557579F422664E07CBE19DA680EFB0FC82C323EC5C4644C51709AC8D674608A8043C91E6C7988D
+430F10BA6CE1FC7FC0604FCD8F723895250AEC36CC35B3FA14FE2A0D24095DCC30B2093F2298F5F0
+A97676A0BE66C3DC9ADACFE2FC0F721A20E945AFC1096A619075D5E9A264C796EC6C90EF1AEEA8DC
+089B44FFC13D27CB2370070A52D4416C53F364393E46EDD7EDE00799960CE6E0D57E4909E88ADD64
+BDD2B0EBE2D73FA6ACF8B40280DAA0637E705C65AABD523B8815F22F23E9FF81E7829C7E4BC980C9
+143AEBE1A04DC0D253396BBB7268BD5AEEA356B610D5DCEE03135E00AE34388251F31714A1C40E18
+2652C48CDA2211A22CB6F02490E69A44CECB169754C53B16028D352E0119F5D5FAE0BD7EA1CDA647
+12A6147374B64244E21E9EC9F0D1381AD22D5B6212B26C3F9AA5F6045F25DD9F5EB4489EA39B1945
+331AC70510C5752557DE21D0A6CFC1EB10A98FA867B76DA6E4249469F591FD154D39E89364A43DB0
+07AA0D7A911CFAE6CE2B557997FBC44F55A27F622BD7B8B10EC9F5D10F2649A646FD964AE1B111B3
+5B46A252C4DEE44E7426EB5739F24E8A390694597DB3A1FE7800C97E59558322F0E49A0CCE2AD94B
+1E2D1026AFA771723E3F523916F55ED866C9FB4A2F759651C613A2CFF362028CDF9D38F05D4C7C60
+24C533E930B64B099FB1AF04B01F5FB9CA6867E6EFF55A772C5391831059987E10CBF987E3F378E0
+1329F73D54DC0484177D3C3C06F67397955FF1CA4EF8AD1606B70455255D631A7D6EB92BFDBA14A0
+FF28B2ACE7E81AD666EA9B3A0F5A6BA3B5DFE35044FA4B3D8ED956009C60E98CC132F2E84967F4A9
+8A67B336D5EE7CAF7DD1F74D1FA08619941361FA7312CF225D89CEF97E864C8369EAFAB94D97F056
+5505D825972B754F6729596EEA91210B75DD8F645382ACE36DE60819A02B3B48DD00F5485F9264F9
+FA926D732E2C267B0BE8CA98526F124F97EFDB86132C5EF16B103908172FC51F286FFE45FF253512
+E0033F037FF182BA536A9EB2DF2D1DB257D9C86C46E1B002FB32AC70CA9462E6EB48994752CEBCE3
+9F08ABD4F4B0889283E55500702185A841E328
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+cleartomark
+%%EndResource
+/Times-Roman-iso1252 /Times-Roman ISO1252Encoding psp_definefont
+/NimbusMonL-ReguObli-iso1252 /NimbusMonL-ReguObli ISO1252Encoding psp_definefont
+/NimbusMonL-Regu-iso1252 /NimbusMonL-Regu ISO1252Encoding psp_definefont
+/Times-Italic-iso1252 /Times-Italic ISO1252Encoding psp_definefont
+295 321 moveto
+0 0 0 setrgbcolor
+/Times-Roman-iso1252 findfont 50 -50 matrix scale makefont setfont
+<4C61>
+show
+362 321 moveto
+<6469726563746F7279>
+show
+556 321 moveto
+<53414C4F4D45325F524F4F54>
+show
+962 321 moveto
+<657374>
+show
+1032 321 moveto
+<737570706F73E965>
+show
+1230 321 moveto
+<EA747265>
+show
+1318 321 moveto
+<6C61>
+show
+1369 321 moveto
+<6469726563746F7279>
+show
+1564 321 moveto
+<636F6E74656E616E74>
+show
+1772 321 moveto
+<746F7573>
+show
+1870 321 moveto
+<6C6573>
+show
+1940 321 moveto
+<6D6F64756C6573>
+show
+295 377 moveto
+<6465>
+show
+358 377 moveto
+<6C61>
+show
+411 377 moveto
+<706C617465666F726D65>
+show
+644 377 moveto
+<53414C4F4D45>
+show
+866 377 moveto
+<322E>
+show
+920 377 moveto
+<4C6573>
+show
+1009 377 moveto
+<6669636869657273>
+show
+1175 377 moveto
+<2A4D6178456C656D656E74566F6C756D652A>
+show
+1661 377 moveto
+<736F6E74>
+show
+1761 377 moveto
+<64E96AE0>
+show
+1861 377 moveto
+<64616E73>
+show
+1969 377 moveto
+<6C61>
+show
+2021 377 moveto
+<62617365>
+show
+295 433 moveto
+<6D616973206E6520636F6E7469656E6E656E74207269656E206465207369676E696669616E742E>
+show
+295 551 moveto
+/Symbol findfont 50 -50 matrix scale makefont setfont
+<B7>
+show
+370 551 moveto
+/Times-Roman-iso1252 findfont 50 -50 matrix scale makefont setfont
+<4D6F64696669636174696F6E>
+show
+659 551 moveto
+<6475>
+show
+738 551 moveto
+<66696368696572>
+show
+896 551 moveto
+1 0 0 setrgbcolor
+/NimbusMonL-ReguObli-iso1252 findfont 50 -50 matrix scale makefont setfont
+<636F6E6669677572652E696E2E62617365>
+show
+1434 551 moveto
+0 0 0 setrgbcolor
+/Times-Roman-iso1252 findfont 50 -50 matrix scale makefont setfont
+<706F7572>
+show
+1553 551 moveto
+<72616A6F75746572>
+show
+1737 551 moveto
+<6C61>
+show
+1801 551 moveto
+<76E972696669636174696F6E>
+show
+2060 551 moveto
+<6475>
+show
+370 611 moveto
+<66696368696572>
+show
+535 611 moveto
+<696E636C756465>
+show
+716 611 moveto
+<6E676C69622E68>
+show
+891 611 moveto
+<6574>
+show
+962 611 moveto
+<646573>
+show
+1063 611 moveto
+<64696666E972656E746573>
+show
+1310 611 moveto
+<6C696272616972696573>
+show
+1522 611 moveto
+<4E657467656E2C>
+show
+1714 611 moveto
+<766961>
+show
+1809 611 moveto
+<6C65>
+show
+1880 611 moveto
+<66696368696572>
+show
+2045 611 moveto
+<6D34>
+show
+370 668 moveto
+<636865636B5F4E657467656E2E6D342E>
+show
+309 769 moveto
+/NimbusMonL-Regu-iso1252 findfont 42 -42 matrix scale makefont setfont
+<6563686F2074657374696E67206E657467656E>
+show
+309 813 moveto
+<6563686F202D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D
+2D2D2D2D2D2D2D2D2D>
+show
+309 857 moveto
+<6563686F>
+show
+309 901 moveto
+<434845434B5F4E455447454E>
+show
+309 945 moveto
+<6563686F>
+show
+309 989 moveto
+<6563686F202D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D
+2D2D2D2D2D2D2D2D2D>
+show
+295 1106 moveto
+/Symbol findfont 50 -50 matrix scale makefont setfont
+<B7>
+show
+370 1106 moveto
+/Times-Roman-iso1252 findfont 50 -50 matrix scale makefont setfont
+<4D6F64696669636174696F6E206475206669636869657220>
+show
+849 1106 moveto
+1 0 0 setrgbcolor
+/Times-Italic-iso1252 findfont 50 -50 matrix scale makefont setfont
+<4D616B6566696C652E696E20>
+show
+1087 1106 moveto
+/Times-Roman-iso1252 findfont 50 -50 matrix scale makefont setfont
+<20>
+show
+1099 1106 moveto
+0 0 0 setrgbcolor
+<706F757220706F75766F6972207574696C69736572206C652064657373696E>
+show
+370 1166 moveto
+<6D6573685F747265655F616C676F5F74657472612E706E672064616E73206C2749484D20646520
+534D4553482028766F6972206C61206D6F64696620E020666169726520737572>
+show
+370 1222 moveto
+<20534D45534847554929206574206C61204272657020666C696768745F736F6C69642E62726570
+206461616E73206C65207465737420534D4553485F666C696768745F736B696E2E70792E>
+show
+294 1323 moveto
+/NimbusMonL-Regu-iso1252 findfont 42 -42 matrix scale makefont setfont
+<5245534F55524345535F46494C4553203D205C>
+show
+294 1367 moveto
+<20202020202E>
+show
+294 1411 moveto
+<20202020202E>
+show
+294 1455 moveto
+<20202020202E>
+show
+294 1499 moveto
+<6D6573685F747265655F616C676F5F74657472612E706E67205C>
+show
+294 1543 moveto
+<666C696768745F736F6C69642E62726570>
+show
+295 1660 moveto
+/Symbol findfont 50 -50 matrix scale makefont setfont
+<B7>
+show
+370 1660 moveto
+/Times-Roman-iso1252 findfont 50 -50 matrix scale makefont setfont
+<4C65206669636869657220>
+show
+578 1660 moveto
+1 0 0 setrgbcolor
+/Times-Italic-iso1252 findfont 50 -50 matrix scale makefont setfont
+<61646D>
+show
+664 1660 moveto
+/Times-Roman-iso1252 findfont 50 -50 matrix scale makefont setfont
+<2F>
+show
+677 1660 moveto
+/Times-Italic-iso1252 findfont 50 -50 matrix scale makefont setfont
+<756E69782F6D616B655F636F6D6D656E63652E696E202020>
+show
+1207 1660 moveto
+0 0 0 setrgbcolor
+/Times-Roman-iso1252 findfont 50 -50 matrix scale makefont setfont
+<646F697420617573736920EA747265206D6F64696669E920E02063657474652066696E>
+show
+1862 1660 moveto
+<20>
+show
+1874 1660 moveto
+<3A>
+show
+309 1765 moveto
+/NimbusMonL-Regu-iso1252 findfont 42 -42 matrix scale makefont setfont
+<69666571202840574954484E455447454E402C79657329>
+show
+309 1809 moveto
+<202041434C4F43414C5F535243202B3D20636865636B5F6E657467656E2E6D34>
+show
+309 1853 moveto
+<656E646966>
+show
+295 1971 moveto
+/Symbol findfont 50 -50 matrix scale makefont setfont
+<B7>
+show
+370 1971 moveto
+/Times-Roman-iso1252 findfont 50 -50 matrix scale makefont setfont
+<4D6F64696669636174696F6E>
+show
+662 1971 moveto
+<6475>
+show
+744 1971 moveto
+<66696368696572>
+show
+905 1971 moveto
+1 0 0 setrgbcolor
+/Times-Italic-iso1252 findfont 50 -50 matrix scale makefont setfont
+<534D4553485F535243>
+show
+1178 1971 moveto
+/Times-Roman-iso1252 findfont 50 -50 matrix scale makefont setfont
+<2F>
+show
+1190 1971 moveto
+/Times-Italic-iso1252 findfont 50 -50 matrix scale makefont setfont
+<737263>
+show
+1251 1971 moveto
+/Times-Roman-iso1252 findfont 50 -50 matrix scale makefont setfont
+<2F>
+show
+1264 1971 moveto
+/Times-Italic-iso1252 findfont 50 -50 matrix scale makefont setfont
+<4D616B6566696C652E696E>
+show
+1552 1971 moveto
+0 0 0 setrgbcolor
+/Times-Roman-iso1252 findfont 50 -50 matrix scale makefont setfont
+<706F7572>
+show
+1675 1971 moveto
+<72616A6F75746572>
+show
+1861 1971 moveto
+<6C61>
+show
+1928 1971 moveto
+<6469726563746F7279>
+show
+370 2031 moveto
+<4E455447454E>
+show
+592 2031 moveto
+<6FF9>
+show
+664 2031 moveto
+<6C61>
+show
+723 2031 moveto
+<6C6962726169726965>
+show
+904 2031 moveto
+<64796E616D69717565>
+show
+1149 2031 moveto
+<6C69624E455447454E2E736F>
+show
+1481 2031 moveto
+<7661>
+show
+1550 2031 moveto
+<EA747265>
+show
+1648 2031 moveto
+<636F6E73747275697465>
+show
+1868 2031 moveto
+<E0>
+show
+1912 2031 moveto
+<706172746972>
+show
+2043 2031 moveto
+<646573>
+show
+370 2087 moveto
+<6C69627261697269657320737461746963206465204E657467656E2E>
+show
+294 2188 moveto
+/NimbusMonL-Regu-iso1252 findfont 42 -42 matrix scale makefont setfont
+<69666571202840574954484E455447454E402C79657329>
+show
+294 2232 moveto
+<2020534244495253203D204F424A45435420534D445320534D4553484453204472697665722044
+72697665724D45442044726976657244415420447269766572554E56205C>
+show
+294 2276 moveto
+<20202020202020202020204D45464953544F204E455447454E20534D45534820534D4553485F49
+20534D45534846696C7465727353656C656374696F6E20534D455348475549205C>
+show
+294 2320 moveto
+<2020202020202020202020534D4553485F53574947>
+show
+294 2364 moveto
+<656E646966>
+show
+295 2481 moveto
+/Symbol findfont 50 -50 matrix scale makefont setfont
+<B7>
+show
+370 2481 moveto
+/Times-Roman-iso1252 findfont 50 -50 matrix scale makefont setfont
+<4D6F64696669636174696F6E>
+show
+665 2481 moveto
+<6475>
+show
+750 2481 moveto
+<66696368696572>
+show
+915 2481 moveto
+1 0 0 setrgbcolor
+/Times-Italic-iso1252 findfont 50 -50 matrix scale makefont setfont
+<534D4553485F535243>
+show
+1187 2481 moveto
+/Times-Roman-iso1252 findfont 50 -50 matrix scale makefont setfont
+<2F>
+show
+1200 2481 moveto
+/Times-Italic-iso1252 findfont 50 -50 matrix scale makefont setfont
+<737263>
+show
+1261 2481 moveto
+/Times-Roman-iso1252 findfont 50 -50 matrix scale makefont setfont
+<2F>
+show
+1274 2481 moveto
+/Times-Italic-iso1252 findfont 50 -50 matrix scale makefont setfont
+<534D455348>
+show
+1432 2481 moveto
+/Times-Roman-iso1252 findfont 50 -50 matrix scale makefont setfont
+<2F>
+show
+1445 2481 moveto
+/Times-Italic-iso1252 findfont 50 -50 matrix scale makefont setfont
+<4D616B6566696C652E696E>
+show
+1738 2481 moveto
+0 0 0 setrgbcolor
+/Times-Roman-iso1252 findfont 50 -50 matrix scale makefont setfont
+<706F7572>
+show
+1864 2481 moveto
+<72616A6F75746572>
+show
+2054 2481 moveto
+<6C6573>
+show
+370 2541 moveto
+<6669636869657273>
+show
+541 2541 moveto
+<717569>
+show
+626 2541 moveto
+<7772617070656E74>
+show
+834 2541 moveto
+<6C6573>
+show
+910 2541 moveto
+<617070656C73>
+show
+1059 2541 moveto
+<6175>
+show
+1128 2541 moveto
+<6D61696C6C657572>
+show
+1315 2541 moveto
+<74E974726168E9647269717565>
+show
+1600 2541 moveto
+<6465>
+show
+1669 2541 moveto
+<4E657467656E>
+show
+1835 2541 moveto
+<6574>
+show
+1893 2541 moveto
+<6C6573>
+show
+1969 2541 moveto
+<626F6E6E6573>
+show
+370 2597 moveto
+<6F7074696F6E7320646520636F6D70696C6174696F6E2F6C696E6B6167652E>
+show
+294 2698 moveto
+/NimbusMonL-Regu-iso1252 findfont 42 -42 matrix scale makefont setfont
+<69666571202840574954484E455447454E402C79657329>
+show
+294 2742 moveto
+<20204558504F52545F48454144455253202B3D20534D4553485F4E455447454E5F33442E687878>
+show
+294 2786 moveto
+<20204C49425F535243202B3D20534D4553485F4E455447454E5F33442E637878>
+show
+294 2830 moveto
+<20204E455447454E5F494E434C554445533D404E455447454E5F494E434C5544455340>
+show
+294 2874 moveto
+<2020435050464C414753202B3D2024284E455447454E5F494E434C5544455329>
+show
+294 2918 moveto
+<2020435858464C414753202B3D2024284E455447454E5F494E434C5544455329>
+show
+294 2962 moveto
+<20204C44464C414753202B3D202D6C4E455447454E>
+show
+294 3006 moveto
+<656E646966>
+show
+295 735 1 264 rectfill
+2125 735 1 264 rectfill
+295 735 1831 1 rectfill
+295 998 1831 1 rectfill
+280 1289 1 265 rectfill
+2125 1289 1 265 rectfill
+280 1289 1846 1 rectfill
+280 1553 1846 1 rectfill
+295 1732 1 132 rectfill
+2125 1732 1 132 rectfill
+295 1732 1831 1 rectfill
+295 1863 1831 1 rectfill
+280 2154 1 220 rectfill
+2125 2154 1 220 rectfill
+280 2154 1846 1 rectfill
+280 2373 1846 1 rectfill
+280 2665 1 352 rectfill
+2125 2665 1 352 rectfill
+280 2665 1846 1 rectfill
+280 3016 1846 1 rectfill
+showpage
+grestore grestore
+%%PageTrailer
+
+%%Page: 2 2
+%%PageBoundingBox: 18 18 577 824
+%%BeginSetup
+%
+%%EndSetup
+%%BeginPageSetup
+%
+gsave
+[0.24 0 0 -0.24 18 824] concat
+gsave
+%%EndPageSetup
+%%BeginResource: font NimbusMonL-Regu
+%!PS-AdobeFont-1.0: NimbusMonL-Regu 1.05
+%%CreationDate: Wed Dec 22 1999
+% Copyright (URW)++,Copyright 1999 by (URW)++ Design & Development
+% (URW)++,Copyright 1999 by (URW)++ Design & Development
+% See the file PUBLIC (Aladdin Free Public License) for license conditions.
+% As a special exception, permission is granted to include this font
+% program in a Postscript or PDF file that consists of a document that
+% contains text to be displayed or printed using this font, regardless
+% of the conditions or license applying to the document itself.
+12 dict begin
+/FontInfo 10 dict dup begin
+/version (1.05) readonly def
+/Notice ((URW)++,Copyright 1999 by (URW)++ Design & Development. See the file PUBLIC (Aladdin Free Public License) for license conditions. As a special exception, permission is granted to include this font program in a Postscript or PDF file that consists of a document that contains text to be displayed or printed using this font, regardless of the conditions or license applying to the document itself.) readonly def
+/Copyright (Copyright (URW)++,Copyright 1999 by (URW)++ Design & Development) readonly def
+/FullName (Nimbus Mono L Regular) readonly def
+/FamilyName (Nimbus Mono L) readonly def
+/Weight (Regular) readonly def
+/ItalicAngle 0.0 def
+/isFixedPitch false def
+/UnderlinePosition -100 def
+/UnderlineThickness 50 def
+end readonly def
+/FontName /NimbusMonL-Regu def
+/PaintType 0 def
+/WMode 0 def
+/FontBBox {-12 -237 650 811} readonly def
+/FontType 1 def
+/FontMatrix [0.001 0.0 0.0 0.001 0.0 0.0] readonly def
+/Encoding StandardEncoding def
+/UniqueID 5020945 def
+currentdict end
+currentfile eexec
+E98D09D760A3C22CF119F9DC699A22C35B5B35ED6AA23593C76D54CABB5E942BF7D6DD84F1664B89
+699C74B472DE9F8E6DF925F6C4F204E9F1C639B4DBA988ED2AC419FF2B2BDE605B8EE3264EDD6641
+2D4F21C64AC522BDFC7C5502F9C3F3E5592B3B2093D33C9BFAEDD2D49E89AABAA832E23F062E91A2
+5032519D1868816E44B4E0747795003D7930299D6E1E2A5BFE0D595DC97E140989CE81D8D7F852FF
+9CDC7A1B1B598C69131DEE005B415805A16D8A123E6A2261C63C769D2F4B60FA2C438AD7D199D8E4
+5F7E7C9A605C8CA14E21FCD81C9A515FB8DB6F99604534D06EA9D87FE0FAA852899C9D0595C7A97E
+6C55F79FAC45CD38E87B10D210CE7501E88C8FCD3444354365FB893A12F596AE2C1E70D5819EE0D0
+87D10BF8DA96F3DABD5405D28C4228C6C31BA4052464859640933FEEFD8071C0C84CDD829A9B1D0B
+A01F25A4D50EE2EA2B45160CA6333B2D2800306ED2BEFDFE155E9D9F9342EB8D5B0ADBF2460CCC98
+643FB1287CCD28ABA7B5CAB92EC39EE2E918990372B16F8487EBA30EAE88708B6CF33B6C015D8096
+C7CFE2F139F52052E3925C0D50FD64CE68236D59CB83EF56BFC584150EC38065059F3308AD6F9A99
+F83EF4E6CB13855C8175E31417D190D036B387D3952344A950F4D8C7781B307A094DF1ECAEE4D2C2
+FD747BC6F7F9C6BD0E90C19294F96C8C5CFE88FB34C477574A1B1630B8CC591529E59B20794DA32E
+61DECDA8ABBD1AE956CF74012AA01D42EE01E861B0AA6897C864788AE59DEF43C493246FDB1ACA55
+4C12594BC7B33657A9ECC9E3D1472EF826073F632BE540C35FF6FB40566773F3BB2204D3A579A08C
+CBC844C14B18C350F003B9DA23A570C362D6003893CA32F86F59B829C78EE3188B6E3F7FA81D7F62
+2825C639638DFB78B7AF1F500F5B450FA54DBFA5CBA277C794ECE93275A3DE0B452FDC8DDC2993BA
+A42F28A636008CDCB03EBF71BDCAF35019778993443F88412AD2AD0D7155A3944606463266322DBC
+0244B07DA1E9C27A27B59664E8566D7A54CC03E995AAD008B0A17E2C3EF61F720CE7F7788599C4E4
+4C709CD5C31B11107F16AD70B17B9AFE2E8CD922A7428DAC171427FFAF51067307FAB0ADB530E701
+FD22DA22C4CD3064067BD4F6089C4B2C87937DD426E4E9D2F60E608288BAC9056554D04947E69200
+61E379CF5E81BFD32FD37EFAC1F61CEBEE551B0851516471A7472C60DF89DAA9EB1DC5A67E479745
+3E69B9E22BAF4E3CCA4192D603295B018C4AB69D18DE52DFDF15E96B557F290A4B8C5B1E7A6CACA8
+1F2351B97ADFC36995ABA43803A6E5AC04A3C93495F6D38106B8B144449C07D1358210F9176E1565
+72363CFBDE576BFDF99FA329DD1346E83F79E06CF68250CA57A68931BC7F342AD295D0CBA17AA95B
+B8EEB53EA6E8E660B814E9F857CECB14F44A43288B69A9E7908D55BF19E844359879D28CAEF1C38A
+36420185D20DFB32C2E002202800E8EF3D67C5D50E919657CA958B538D537D503444865331D79BFC
+40312068D72364503BD0CC84B5F30A74D8B5B6A26AF2DB764564FB65A6BA8F9051AE2B4EA458D46A
+4569F30C6E77DC097356770362E6CF3F1661074778EBB44FF7D1E3B64FF75E77E11FE525BB121C65
+46CFD13300CA1F02D571B82A5825E6226D14FDCF27F06D87452A8B6C5DCA658535CEE2A795E58137
+D48E566B69D53A0C3B766E84C51EAA221C46999CC8065ADB2F129D5B630FAB1814C0C33B5AEA0EFB
+B6E994D80941B53079AF96D90A0B924F9B0E319BED9836B8F9053F868363D3CA554CBB181863301F
+8CB940872ED5FA7BD18CE39218B5AD8AC57D0F752D941076B1C64D99BE0DB86D7A6D96510D772EB2
+4C587F11779BD21CFE5BDE1F29C1EF9022B2B8BCD7F91153C845906722477829C40111D810480F3C
+F62DE8DBA7FD86CD236E656618CAF6FC46827FBC4898EA7672F8C9971AFE43E0E01EC8B77D4AF48C
+BF1210E98C1DB15C16D149BFF58AB0270CF015B107A3A50F5DC8F37FFB92EEC8CB6778DDB7CE4AAB
+C464C4AFF654223006A550EB52485A23D2B4AA7198D3CD54418102F1E9A4FBDE37B841E56F5C2C53
+966DB9B66B000E4588282E3FB80C2C519339F0002D2F83C979EDC5827A3B3C8EF8810A0F9DACB6B9
+998E9AF6551F56313DC4011904CB979AA2D32B11A811BC248141E4B9734D9FB7982A5671002D8279
+CAB93ABE057474628DEFC95D43890DB1ED34CFA8A20BDC3D874E7679A396158E522ED0AB969A4E3E
+C7E4474E192590504D54DEB7B260B7935C4E56548A7D121AC1F741F8CDF259EA1B5813175A77A1D2
+D30BA26F65EB765A04C09ED51F69F41551ADF399E6AA2FC09788137BEA4913F17B8EB838C38FB272
+1FDCB55FD65697FF0B850E7D3D1CE266BF90F7EC06A9A0876BDFE767D3A918B092FC78C775F945CF
+1F96E859C03DBF630D9A940939654C3549D8F7921CB94EE23D5A0535DE9DF31EA0F937F860B4F220
+A99ADDFC343D7CF7BFA0B803C12C26403F0DCFFC8EA786D0D8A8D9C367419CA8AE41190CE93A8086
+583A1E6C9D70B612C84D87D2EEAA71EC2DC12F4CDE6A821303D5F6A9BBDB7EEDCD289E80FA3B75F4
+7F481B50719DCF4A142069393593B9AF9CCEEAEC56A35B8787193D7C88113E9E1E221D151E093B01
+9EF89F6118BEC4735103CC8003CC5AD1B6727B3226CD44C497DA7052DD681695DBEC3397F9598C91
+77701C73BF0594CE93F23D50EC5BEE2FB9DA1FC966DF148B27B28EE3C89526DD6625E2887F9FA076
+7C127C609EE315626BC14D274FBEA56528DC06A27B2D476D46E9E7916590B156A5DF04A6CB15E362
+45D77021767B6E5BDFCC679670263FD891446C3371B11BB6E1DF60F960AAB4149D7753E6A5C33810
+C42C8BFF4E935003388506F8278BD7CB672F132E065AE684DCA0B9064D01DD620E7FFDFE04F14277
+EFE8E60159BA0FCA3FE2F28B902D4AC275D19F0AC6971EBE827C4A232D87650D2688345BCA78F879
+077114F0463C5F058107B669566F8171E4E284D278405580F04BFFC9902784216E0C9A17AA9B2935
+E66E18A783F723BE044389B7E9D62AA36818FF2EA406C3C1A9D2F3436F3EE7DB8BE86AFA8DAA6A4B
+1B84611350D8D27605509612B515E16AA843164D5D0805E36A2B9EF74C5F6A0B9D59A04B55697123
+27F4B1B30E9587CD103337639967CBDC655AA46E80D2CFD24BEB50815B5338E522B3A7AFE8362AB4
+F05D8BC52BBA9C5089ADA8C89529B0275AF422EB540D31A938B8740860756325B966B36817115213
+FAAF92DE63F6BAE1E0064BFBC5588098B61EB83C71F1C2082436D37DAF1ACBE186FEDC4BE7C1233B
+6F18BEC5F99002D21CB7864E4811F7AB3C03003E1E4490AD1AC793BD28FCD5EF0E6CC30EF39A08C5
+2F71939B0CEF620DC69E31E39D6DB969049031B0C92EF2DB653D97F370141456A52985076B268652
+FA2648C792780BAD637C4D7581FB2D62011D57E293719487CF2D1F013CFAA532E1C2D39178D51272
+A6AF041440BCA174B5CC902BD7390C7D3695056CB4BD7791F9FB6D88E7A70DEF2C97869F5DBC5BD8
+23C517C7B7C39D624DF627DC9653EA5347BFDA80B723F05F6DBB4C9EA501D862ACE05B9DBDF21B70
+56FBCD8C6D4B85873DCEE6166C8B5ADC0316CA12D9639F361B15A42F00E1D62EDBCA1111972FA0F4
+5758BECB31DB38316F3CDFE1B41748C93ED58B67E9B57ABBED5924A6D53E99FBC9A994A6489A8BDF
+13EB685548B4DC6D62DA7426C22227D4D43B6FFC7B5EA91C896730253E8941AFEE588359C2BECF6F
+FC415B9EB6D31CCB0F6C7F85853E6449FA6D627A97A3CE8303F148393ADCCCDFA2FE085C6908BE5C
+3C05AF00A6F02840206C3253A559AC5C049BDDFD11AD9B118403B84DA10AE3C470CB9A9A2D1D7B73
+2F59F5FE146DEDA60AE750F551AAC934621B4470E1BC324C436303E25F81D0DC3188BE0D6FEC5414
+C20E4CB18952E12CB6423DF7124627ACDE145500D77A97A8BFD9CB50D1FAA008E2CE2B2505A4749F
+1EBBB092C347023714055A9B63353AF9E7FEE05BB54C9843698101F79888A91531773830C2C967B5
+88D3ACD2192883D5CE3962D51084FC653EAE2C5FB2DA41DACEFB5C76812D2EDB5B109677289CD199
+8D457FB1023A19AC67295BBC1A9A20A426B06A368DF3C5DD083CB1180D287F5500F2C635EDE157EE
+FCEEC5503447382D15C748C1E35F68753992E5C90F900DE54D18F8E1B355D1076ADFB1F3590135FA
+D1A36F028E44F48ABB149B80CA9A54614D467F8D71CB310BBC7AC7100261092DB8C5BFD39E0AC6BC
+2C9D6CBC3A8C05FF8A74CB21608EC4A4CFE4CBAA2D056DBA14206106044DECF59F957EF8A9CADE4C
+9B19D8D30DD4FDE6A9548E50DB51ACA73330142153FC36B69C1C8D5B26D0C689B7040E81AC2C864F
+D7C097C99BE5953843E172C97AB5684F35FB03A725A89DBF371F08DDF40A1531FC1B676DB0E1543A
+EC6E97D3D2E4AA3D5831D8B3C952ABBFA112352814FB6FAB61A0D680E6640F6AEC8426200CF61286
+F7422CB2F78C61EBAA36D47EC16D7FAF8B4AF31D090CDFA255D9D7C61D46CFB22A7D6E1758E71ED5
+67E00CBD8E8F468DDFB477F091A2F915627F22FF47B876544BC1F03B6BBB98385F009C20BB1AA2A7
+A78674692B8EAC2E3C8069B79E679338DA57F72976810F845BEB6B9ADD32B95D78E5E60F16DD1668
+9C05FD82D36A3115BE8ED494A74DD211D58A2CDF983FCB9CDC29BF7F0E29988FA23560EDF514BC1D
+183F3B2A22C09FB179B47E05ADEF48DF02F31C29875D1915037B19407764A4292FE44E741651A8E3
+BEB5F0D972B6327090F664417C84F84FFBF0AFFF8B1D85C822D90730AB4140C42A51AA8B1DBE4398
+4EA8566040EB8B341CCE23FD3F69DD235A080BA5C69AECB9BC732BC2D7D40617DDA6B79FB6EE40C3
+556C7DF9B23DAD89E94054B1345DB8402AE679FC4655A4A776C0150463F8DB2BFC0608EA1F124E22
+1DDAE6026B5E5D007A7E4A0D6B3B0CF3A2669E67C5E4F01551966A7BC48F2F4B6A87E740D8095E63
+F77C7A027F26B52F2299DE5B8A2F6209BCF3D31CB0235F998F781E5CC81E31DC424E008D46EC0920
+2951E5684804A0592EA47D6C788A20487BEA2EC8F2E6C1D7F378B62DB43CA43C4B366F8B4319631C
+FE9854F0E10321CFA3B01C873584863BBEFC23C72C05E695B56E8A52E89AA2DAB543834D34DCAC5F
+ED08DC51825C5257AE59850D101D84F4CAA1D29FC932F9E0EFFBF7A9A7F3685F61F0490CD3CC8988
+2DB52A757A6AF4C4E67B407BD2316B1C0FFE7DC54E43C87B874F57E4903334E2140B011484863CDC
+ACA331175F2CF3D72E0042855983AAF8853D3015E870FF0807014C31D55060DF3FE1FCE157324481
+2744AB51322444632F9AFDA6706E320FFE82B8CBE242A19DF00CE73EE48E25FF49D5871BD3E60652
+298FE3E8D400609E232E0DDC794C0579ACEF89E841B2EDCA50D51151F65E8C1CC3B01EF1870558F0
+BF5743718C3E068617E81BFE120C6CA16E0924BFC2541177D53671CAA3AB641C41557DCDAE1A3461
+47B5E999C4541B08B4AFCBC187AFD653D5B5F8386DF6AD8FE69E21BD0567DF494F736C6A184FA4DE
+48DC9F347787CA96E2E00A296C2DA05C2AD9BC423E9CA428D7F1FA12DC9353A302FB8C529AF8688C
+BB543B45B2717EBF8F6C497935F4F3BFFD285E0402AB7544B3CA4643AE5A8B5250ED987A95FC1F27
+5B9707ACD0641BD0EE2AE9758494F8D8A51DCE408A38AC20EAF0852D72D84D0C6BE973326793AEB9
+55EAC6FE0A2813A355DCD22F6F2CE56588D1C055CDDFA98878BCEB6A018DB22922D2B600A20F8184
+2E665DF41013CA0947C4237C2BD60A75E2FD1A3FB8C8FA19485730B87461AD466ACB02DF8CA24091
+4FB090B3D2B41EB6B8FF05E1A59D9FD668AF70BA5BB72778953BA55FC5F9F626043450E1D09BC83D
+8605098ABEF884639A37809A32565CBEFB3FF39EE53D6C18C58C272BB928E4410E361E59A50F242D
+69747A032617C52DEBBF62364AB5A96EFAF642D9D82BA679B1D70FAC10A4EB62FA5CFC308E86368A
+AAD7E75948F43598CD1C544A0D4091374D7E88D4522CBE902391641327E888E7748FA889DCE67ADE
+61699E7D77763681CAEE9B1CA8837B2F7EF9C18CBCC538C465C8E2DD34616953CCB6030A222C728B
+834911C1A179E2C770289407AB28B303E724D97F747D6134B425216A64C6E0B60F633E2B85300047
+E4C90339CE030A0FAE31E830C8ABA5AB3386A3B69267351A7BFDD66356AE5E57FB2994452993E90D
+E7C4E260ABAB93C37831856A650D56E44172FECA01D6C7C380F250B82473960D2A2A5FB6B4DA668F
+46E624ACF7FA0FD4490F485D640A3ADFC9F8652E7A38CE5799F770C3606DB4B8B947F93967F779E3
+A3C0572F13A5A187D31D7BD12A5C7BE23CB6ED6192086241B76C5BA6983DB9C93E4B208D707D3760
+F03CD6272EF3A4CE89B8E52E6AC5871A3D03EB975759AB4BE239E5EC7842CBB333E692CC607C722E
+185D3C39164DD320C6945629C70FF66A5237C0A9520A1FAD6EB9816069351AB0F135D90CC0982B14
+7D2294AE4A38A527EE40BE9CDE2512AAEBB590E134388BB171D0956A7C4566D65A9A041BE6C4F883
+6B3EC3D2ED1B48B566A783292B15B6127920D247D494F070BB20BEFF60640B11B276DDEEE49706E8
+B2B21BB40B7F00AAFC594C492C25DCA774E0B80D82E927448DE2E74A9D0DC7AC9260096EAF187B6C
+D6AEAA6D1DC4205B4411122751A5B22688404EA7C5861730371FFAC10F5AFD4727A0E402AB5EA757
+606B75EB86A05E8F774D6E430A1A3FE2A37EBB06700474239FB1CFA05EE44B91B82244C575B52E7F
+AF934B04EEB0D933FEB57EBE326D75821C8B23EAA85B583AED4320B7F04B9F2DC591091216FDE52E
+064BAAA9C2C9D9714B95A4558C21F3CEBE624B5403B31508F178581AF6863083ED762F1E2E34A45C
+FDD71660D626FF8648F5D6C5E580D4765A67FB6159EC8077A9F0A88038C8D3D7C77FF0926E2123BE
+874F7BCAF129D55A5B5960F824BD1728ABCFCC51D23936DE9A25C408D786E44C3A2BAFA4423177AD
+060D21D38E15E23EB6FFC0B4120E814695D423EEFC2744A1FC81B4DF89D76F0A6803D8B14E75538C
+AAD03A72517B86514F6952F6FD619D9E910D980F00964DB325318C045BDF79647F453D4A5CF4E61D
+D5359782827229310405FBCF6107C3AD9DDEF9A9A339D5D5A6EB2E7838A0A43221BD62CBDF732DB0
+A638A52016FB35BA7761AEC846A023D3BF2D1BB183543E81EB7CAC1E5970CDC6F068C5EA118C7AAE
+528D1396E6DC939112DA4460C890EAD5C01BDC438F5BB734218BA6270ADD0DC1778FD8AB16831D6A
+302B814A1A44B07EDC65956C9E6CF4875DF521F3CE5B422F71081B6D69BD270F739095C9E81C0377
+934A8BC6390C420C4E4CDD9CF7E32544C68D884E15ACA3BCC07FC8C132D8FB9D752C15D75C52C288
+57E2EA461A6FCAD90C56843513F74461F18D7164BC597A28AE4BA7C86EE1703535A9B9ED50122627
+71FC12F102E800E0E1AF7BB46681BD2B14B614CEA91B7B2AAA35235DE76C0E113C92688F8EC81277
+D58C3406778E1EC1CC15F1CD9A137C8FFDAAB99ACE3BFC782916F1A877170589A92DC921E6740A22
+B84DC6BACDABCC76E64C79E3A588D80F8F4D376E1B426F15751CF7391102102F0AFAFD8B22DFDEB5
+48AEB5F30B1673023D22054A13391A0EC08DE6E7B685A0D031AABF20B7C62187C0284892D5EAADF1
+21BA28263EB863D5E36EA9C06A77CCFC0E17F593961591F84D82AF823EFE41044C8D606FEF83CCC7
+B0E961E7994DF8A3CC36B209D953E250ADAB8D22D7F2B4E2C9CA39EFA2D93E56195C1560E30A5190
+CC5B17FAEFCF250DF79F6B624A4B917E11C332222FCCFEC4F6A47BD9E75DA9854FC3F7AE554E91ED
+DE144D7AEF38A0E3EDB5E5A5626374DB94F022C8CF549093041DE00D7269B7CE544E748439BA2870
+718C08E58FB4A77D93EBC04B7957D272AE1601D41BF85A2BADAA0DF73B0D3841D4839C85677FB2E1
+5F1D6CE592669FF4BBC9C69DBA334DC37706F2F6BE83D5863E8CD6A30C08640AAC4C233684E66B4F
+E6B62D4A8BE9D531E47BEF5640D9B5C27D990092BE1597F6995C8A77BE9C18AAE6C1CF130775DDAC
+41D34438FC7AD8E042CB56CBF2944932EBA7D053E9376FF398367450E35A1945FE23E05C921096A1
+5454721FFD0F429A3E06DC3ED36F1C170BE79C66996EF8337AFF85B90C5D3A4A94455AE9FA32E211
+7A63E59001F052D5F6223125BFAFA40901E98960ADF7BB886729DCA82FC3B8CC52B37FF2517299E1
+D769057F8154FB95582F02CB0BECC873A9C71796ADBD3E91324FAA94F2C41CF57C30B5897D031C02
+D256C909E080E70BFD1F32E69EF67031138C2DDCD1A8E4B65E485C23C3E450ABDD9815512D6F34A8
+4B9DB715DB2C7A93BFB424316E1AA44397749CB01088428F149A3B4324737ED9957FD388248462AC
+1B2610D72BF5C073ECA567E7385CC959E37CAC7E05470160FFA5A9F63B8E9B082937E911586EA165
+374938F492EDF28CE6020953A5B5CCEC7737F9D9CC8538C4339567AAED3794ABA3B9F4EAE65466E8
+E326F6C399B36355935FBDCB9972F10B13494DC25097FCEC5A6398F275C8C151558E74C5175F7BAF
+4155E36B733F75CF9D5C5979B0764F14D8306E06BA24BF791141E404C69F3F8FCCD91B9C58C2C671
+AAE7D4F9E5D6414E46ED633A5F78AA5BF04E652246A066EAD9E582B181CC196EA2D3CFAA383B5D0E
+4CAC9336E119C08CC6AC55CBFBAE147C623B400453BBF447E96DE036FC025624384359EED7C7D5F7
+858DC0521377CF647A157FC3F188DE5EEF094DBA125510FDE34C570D7BE76AB5DF0A28BF45DDAADB
+EA7EEEDB936332DFE93081E0AFD3FDD46BED08D6914B2EFCFDC41662A33B90B03D76D34F48D30FC6
+BBBB600E90E6AC7243FDF026762A44B4D6E4ECBEF48C9D7B696AF29EEE063E557D8FCF0F09E0136F
+45D17E608DA36E59F2AECF8493F8D62536119B5F7E1554DFE3F6E8D7C9A2C6F557D18B4AF92C9F6E
+050975C3B5C54F9B5F4E39D600B6FA2CD6DE203A174028CBB2A201AF126D1013C229BB82CFD013ED
+199D01E51EE2780FE896E01C63C655087A3E61A7F1029FA5E97EA1872F1B45F22282DDC317E17926
+7368CB52DA9444F6055A3C653659CAD2A1D8712BC2B1B32C1DC6906D957FB88524EE066156ED6BDE
+B8D832F9338F9912E29A250A8C4674E667C1C278B677AEC9972BE83CBA3FB779893FCB8F81A323AC
+91474BA2A2334A07BB5628E905C518E634F6761A3289056F83D5DD7B3890987EEE1C18FB2D379CC1
+905F1AEB3B3D2AD578F0D6C845D2D40C4BCEE3F71C90E68E5417BB8CDDD878D83BA80AD8485F4067
+E5C3CABF28AB56CBB219C0AAB8FFC6C7E192BEC8CBCA1459AE4450AFCC81B9548F40CE2622E5A7C2
+81F74DCC02DAD57EFD92D072318DDF05BF42F1EA8163071E23949B0179CF7DE64677CA99B23CB926
+B3E294194EC13397EA1DC9A5E1CDCD828156CD71F81B64167D4FB01E6002713BD8AC6F82B20CD369
+9C6CA4704DC5C65A2D66EB155B7AF1C9BB46469416FB49C1C7E17A30A5F045271D7DF3FFF2F42C6B
+470701C381E3456A500C6BB3D0E47B4D91C5F34B49BB6272F1F8698B307D89EDA3A1565DAD1C0864
+627560CF922DCF5B34C67860352390B282F95394AA2CDE0E97CE3ED39546A6AF1C52BFCF81A29BE8
+2C47C99E8050E4889E4575B75F39E662F2DB7420673797E2ED3D67CDA7AE2C15D0A0A794D57D168E
+BE13214E89E0209AB2C0EB7784E9491AEFA3C02D0DF3AE5365A0FC4AE023CAB528162C7A1B173664
+9DFADDACA8DA5FA18B7D6489E4229E9E24D38A620464A744A5C60F6F9D334B908706B738AED18669
+8A8B278341FA4D65A0A88680BA484694921512F7DE93337FC1C02BBE6E64AF2DAD07603279D87329
+1D1F4D39C1DD6D89C90F65240F4808F6F1115CA55B88E242565E59F3BBF1F10EC7B88872E9AE61D4
+4CAE185463EDFAF7DF63DE4D2207D307AFB61501892965170D2945846FCF5973A1D458607F50C15E
+06E5BEC715E0C156259AAA6C735593E5564F65F443B78CC7512EC35A56F126DF9D30974A40872E42
+65E1AE5FD483CFCBBBA26DEE426CDC4721F19C3FDA86ED7AD4FA1120F63669BEFE7002B128CEAFD8
+C63E8AC09943B6CBDFB3D2476A026C00A8FF81B1F651B97F310C82ABA5F388CC1DB5AFCFF5996D52
+52A6A42FA4D972E41EE56088F78CB966F9051171C472C774879AECFFF08BFD9CEA40D7C298922ACE
+64F28C14E0B81F4DCADE81D71DE3983D87D905192EF13CEE71B2D3FF1A88AEC671EC318917DF98A3
+C9054E372D22A3CEC82FCC217F47319A40900312F6E32B536B9E7A7FA0837EC65CCDB5FB0D414371
+17596CB39D9382262DE6E65379D3A9709B2CFBABF5FC5D5B352425F06F88CD31012A2A4147B112F0
+C1C0ACCC808CD625E0228EEF66661F70AF96D3DCFECD402700E4F6522AC9A856DA466D55C84F65BE
+2810A1565163872D62EB81333A698ED7B68352CACCA2D7AD38AB55C19E4F5582F75818302F5FDADF
+1DCED09D94872F2D48FB636C8E38C7563C72C771A08C6B1F041F3532BDB39006C89A33C09BE1E3E6
+03622D891F98010BF1DE5355F557A1E09448D486ADEF565705277B31B8BF2B86761E32631E3435B6
+88B79D566F1747BA456DDB43CD239FB47FF7B425EAA4C657C8EEC26EE01AED07CF916E77D53634C1
+37AEEA009C6B515B6342C54BE2C7B95955B1A9DA277A0ABCDA2346E88018C726F481F71D6011AA42
+F8852F2E5749518FE3B3AB668213FE1A05C10A1C53953D75312631D6BBBA01D418199DFEFF8CF548
+6109B099FE8E2F606165FE30F532C03567785D5362AA873C9D3EECEB20F1945D55F49B0CCAC84967
+59FCC7292E46938943C262D78F3212D3F9D0F7B103157F423D71B1ED54B2A603F4C269029918F238
+EC6828FFCEC66009DB9C9E59534EABB183F31D7AD4C57B1BDF0BD2CE5A421882BC10CC1BCE6A970E
+2B586BB221567CCA483989DD0B8DEC424C1D1FF042DCB7834423CF244EDA28D2D969B17440CAEAF0
+24A6119DB010CE366821AFA424D1B8299609C04148275AE6E5257A7ACB3C766C747CE99CBA2D703C
+F19B7CF301B634D8B613DDC4AFE4633A4D77BFF8E00CFB5E289EBBCAC90A24307E7941EC1685CBAE
+400CADD876FCEF7F6557EEE167D2035A05120293527700DC510B038A496BE1D5CBAEF24ED39F7421
+1A93AADF22214ED606A80582485AFE358E3A46D0671148998A3B3BE209467009B43400870359D418
+9A8CEB4D5866AB52D16D9CEB1EAB71C07E6CAA34B70E3096BF7604C22C40D5FBFEEA616DA3BABD59
+DCDB97D883FC8742B8267A16A99B7953225F7144568D566E64542C92E538AC140C851E5D295528EB
+7CBB49909B1CAF6409C9BCCEB325468FA0B5F7CB2987382616B477CCFE4F4AC79E4A6F7165363543
+F04DE5B6F6E1C2E910CDC3CDD6C4C92737198F892337DCB6647BD226C820AC99C65D8E7772BBB74F
+E65DCAA8A22C33BC168BF48E40A82700A3A7668C5A9A71E397ACDFEE7D556C5C19467B7AA69C260B
+727407AC837BDB7D67DEC055C1F45D8BAC61048C45BC9FB3CEFE7549EAA2992D2EDC126FF7A05EAE
+58613332A2BC1465B2BC0429162B907D65F793D236EDDD8D35405866D71B25F62DC4A7E06D4DEE82
+840ACCAABC0774F8A63E9C0F7FC980B3583E7A8B01C46590E3BC04EBA565C2EA94F057D964A78A90
+EA9F52ABFD70F84E44E434BD10A42E98C794065724341F907E35D3CB257161E01C7084E3A0166D15
+CED65DA7BA87DBB2EA33D39BD99AFB93D3548358D08330E807F8552CECF63C84F805205491BA3A1A
+622E70C232FADF3BF2DCFD6F0539158D3306506F150B0518371912A25EB96163D73E9EEED42EDC84
+D688BC7F7708D9DCA348FAB4DF62E5809BD094842D0A31DBB7C4B41F94D946810C5EC10B69AABC2C
+91A59500B2E5D37F4755DDFB7AE4ABF757F4C5BCF77C7F95E6A616646456FE8F18407080BCABBFA5
+7704287AD26222DF91AB2613951E2D679472F8ADF06EA2A20205EC19972299A78BAC52114334470C
+5F5890C2F846B4C6042D73945127F2E3910ECA1C4CD7A16EFE4B4BE38A15AAA710682C3836A8CA83
+FD384970139D8B46FB0AEBB002DD224199672FFA02250FBCFA4E649E335428FC71F50F45E498419E
+DB0E970F46894A48F65580881C9C4250FCEF65C9B28699408E18B26FE6DB7F1CBDB767564E73CB59
+54C6D639CE33220C894F36E70F71C9F9AA3FE2AE0AA0E3F2E304EC5ABC661675CDE2E70519E4220A
+E26FBACBD01D5169EB844750753E6CED53E3678FDCD08AB93E10067E9C64F38B40B76D99B6CD92BD
+F4155A1EA5CC824998B59AAD06E09E5F15EBB2288D66EA71B296616734FEF2796F07FF0D8B047074
+A1111D68B99C2B70FC56E74A51B062F4998ACC85B1943C9477E436E5CD7AB18DBC898D21BB93475A
+623BDDA71D7B895BA2D4C10F4B90BF335126F4FD57D73AFA50170F6B3C364922E551D40E35DA75FA
+891762FA23401D39260F2E92C7807C746F13BB35CEF9DBF2E76E66A72FEFF095DA482A4DE8A42091
+7065736CF4DE904FB52E649A32255E2030A7B31B686353492F31C064A3C4B0448C4BFD44B8E15384
+FD809B8761EE26A7DFA1758D57CE4F0BC376EB2B3833534B15A83436BA553955ACB5A7A66796AC5B
+92DB5388BC53EFA27508B08E82821E5CF669BCE52BB860780F749B4F38ACDF5FF12726BF3EC2743F
+01014CDE96FE6B4C40A034E9EAFCA2A35CCC776C2669E6AD138070A40F48ED79136D7FF57E993E09
+B81C543FBADD350FF5B5F7A46F060F88E30FE2D8233832D18B6C323EE017EBC1DF5C838321CDC8A8
+4CABCAB20B60A1A3AA028F36EA6E87C850AF8AF7CD50AA6359038BFA8818821D02CEE8F51DAB8C05
+F7AE9797814D97F3DB8CCDDE45B21DBB15CEE292FAA534A5F317B357F4091F3DA357325B8B9F5EDB
+45865415973C143E5E5BAA483FBF2D06CDD4246675EC58B84C6AE65CA743117FF00F229243772561
+31A7F2BA26A9115AFD96C18216CFDF41B7220ED0CB3FCC26C36380007B382A02AEAE428887DC8BE5
+FDD630AC57EE3DC156C7B8B29E687F24442E35CE10BA4087295A641F7139C831F7CCDA6CCEB5DAFE
+537CC1A97C5A337D3C48A6AE947F58A30DC08CC7B58DBBB4737AD52783C573FC1E9408F55495A80E
+7FDA61F0B9C4F090158F1A416249EBBA936C27BEFDEF19D1BFB839EB70576A010706D8B95657B218
+9C2AE04C11EF9E57FE09880273761FB4302C388BD608FA0C7F00F033C9C00F4E3D5CE2D903E0DA52
+E69C7745EE9FA75E2AD93DC6CB5CCFCD3782A699B807AFC36AD1F62B05856D5DFD6F88831B90EB3D
+CD523582A49732E3FD7253126D39E8AFB8458B5F7AD7F94A8DAC13365F433C857AF4A42C0A08C4DB
+9887C4957259ED22D13CFDF5995DA957EA5A0F620B0214FBFE08AB6D552DBF048D62CEF6EFF12F15
+3511ECA7833E0E3E95F85E6AC0F95438AC4C126E1F1ECF336ED31CCA7EB216D279877123FD9FCD8F
+B5E52B587CFFC4428456DDCA816819A8A4A211D8F1629E5D42BA4C5C356E580C8A22C61D987552FA
+A97893816DA73D423686E4EBD44375C257F031318865A20F22115E72BF1EB9F93AAA169C140A33A0
+6C35BD4526A38BE79CF40AD1EFA10411E8F3300A8A8B97AB140EE6734E1BEE6C8EE443D698D34159
+97649C6F10F20ACD80236422E215E146D744A262DA3FC88DC0D86FF66512F49D3F957D3C5CFFEB42
+4823509F33F155057A4C6F37B52F4667767BA94F6B8B62856B553F307E5D230C44CBFDC9A97A45B1
+39FFB2F2565EB0E22026972FAD0FB7B9576FB6F368B61979943A398773600E7EE1DFEFBF26D45D40
+BDA66EBB96A56EE9CAE0B2420C5DD83E24DBA9FF885BB844BF3D2BF93B07325DFF60C0CB5FDCCA0A
+C8FB5A2E119D5AF26E53AB8E3B428481C2871DDA26EF0B621CD8572B3C664BC7AAC01A1D05B98F79
+1A7080D294BE81099BDA7982432F3DFF4775C44D23F4F1B2E0162B61A8B2CB5EE8564BF98E2ED403
+2219085FE6194C19DAC98A421826CAED7F1AB1477AB327506010217283894235D7DBFC1153D5ECC4
+8AA7293F19592B4D7E95FE55151889BCD1D7FA7DC2370D2DFE11D7E4EA34B5C7A8E73BD3A348FD38
+9EF45B6167FB90BA44C23E912F9A4F2FC0427ED070592F7110183BFDB2C400393BA7569058227926
+351F07FED4F33633BA03A72AA2DC6B598E49B96021DD868DAD0F352E5722FB714F667C15C68D49C0
+3D822D82677EDFE86FE9668E537DA284068C9B0AED83074C92A5B939296D505B837E6A9DDAB1AEAB
+7455A08A114C2222B339284674B74BF4CA9EE0C020BF2A148B439C71C6BE51A94CB64FBE4A7EB295
+5A455047CF5CB348B062ED4F6471CBC3E9ADD9BE9B96879AC7BC71BCE02FD02F17C6063985A5E898
+3D205AA1489DA13C408990ABA1C54F2F501AA172F530480D789C848118C0A74EF98D5F607A067BAF
+F6030D887AC6A6497F9A0B38F9705F328AAD4BFBB634F739386177B07F22D5771282444E5EE17335
+B4D0EC86117C697E79A5F4F65FDC08E4904DAEDAB20067EAE2448FD4301849E456D085F392DD1316
+7ADF75CCFDB723E2904A9C0C976D6B84DDEF9D92B0E15FB246C3ECC2D0BF314CFB957757B3A3E8E5
+801F520644E4601D291DA0F7507C06F3B9BB36FC1C70EAA444E14E56C0CFF06C7F853DF36DA9D8B6
+AF2544B853DFFF535A7E5C6FC145250CDDA229956019659D0D253A19A7B51A4E538BDC01F74D7704
+9949C2C97C7EC6392C2E61CCC0992B66DAF1AB08551063E53180D2A67DE496716CCBAA45462D9F91
+B66A22545962DDAB120511FF08627131B95E5DEEB8B4DD9643E7B2AF65C0FDCE11F5F1E8DD468DA1
+8D41C8C4F00EA73836F4F70EC50FC3EC6D358C0658A4261C6D15A582A2C7C994E7882E661855B352
+014576858A265FFBC425160669CE159D07EDAC04D060B44E5800A7AAE8E339C29B929AA81D2F515C
+46229D2080D5917AB20AB6B34FDCA8E4AF64ED660A3173786FB1A1D005D575C2A5187D3F7CFDC94C
+CC44A38C5CD523E9DA726D8EFA6DA7B6131DFF3435FEE838B2C7D6B97934295F06202D307FF78D90
+6699CB9C5BBB10D1D4DEA5FDA5BFB094E704607083B646D37F5DA1FC7AD21B813F44D8C1AFEAB666
+55AAA19703BEA2E77DF3BF350E17C74B3447A452235919452B5175570A006C7680AC05E8950A62E1
+1D7E3ACA35A397D1E19630D094A86807593C97F4C484E4E06BCFF708B6DCA972E3A0009E1CAC0EA4
+141530F5C1B8AEF5E1B933F37FDDBC4BE22B74FE346D1A3F5FEC0818F8E61765568A2AC04713E828
+F98C449D9A1CCE52D10D61DD8BFD084C8D099A75D89DEA64D5A7CC68BD5B0593D97953DADA976383
+F5015915618AEC56D71D1DCD55B89736395C609B315A3F1E1255432FDBD37F38CC43C354FB4B7C44
+F1A7318B0B7E99C3C08C33B953727B6A6328051783A0A33E3CD9E498346A3CA6A77B517096EDD52A
+E443B87643A646C3A7BB97F742888D33F9B3127E61942F4103C1DBDCD8EAC8F9E259773066736CA6
+53CE57E8822651261D847C131321BB9D6626A1AC50D047C0BA47B411DF2A995545BD68EC0287CC9B
+31D5DDCA8755EBEB10ACCB3903AB0FD5788E984220443B8459E7C078DA4289F1350905881AD6DFDE
+C47302B0ACB0D4AF8CAED02B4B70DF3CF8FEC118F0FC2D3DDE3E494CD160E676E300BC464BD4400D
+B50EE43B314E0517037BF971ACD7CD327CB2134893B8A0410E68DDC518F5DEC966C7884CF5FDFE74
+723177F20DEDC039D879056CAAB4BF045062D3904F615C5CFE109AC7A35599C94024B41019B9AFD4
+04A80ACAA4837929F5C9317680A13D157A03B59A5588DF79D2E113F5F51021D6F6F90E8BBBA2C252
+FD10651BE80BAFD59C53A3367BA3C28DB6EB9DABF1EA99F47B503F627E15DCF3FD645FC52C5D5D0F
+2F07DB4C25C0D1E1C00146E1C4D973E613CCDBD3F9450CC0F5343D79F05E9492E86A1BB889ADF405
+03BD7F3E7543436859184A5B20BD8A172F350D846B7570803990ADAA48D4B9155A2B4C4BFBEF1E1A
+065C08E03928559735BDD442FF1E83E1FA20A5DA57D8BDB2FF5427C034CF0128AF111E6E73099E04
+6E0C240E80A73D7BE72B87834E45898D475521CA3306707631F5C6136199F354632D1A085F12A1C7
+C473868B62E534D15F5484323E63D0574196A19EF175214EB35A90873EFCFB92D6CF68761D45E37E
+AA61E1A1979A82009507CA193E44B36A806486665CEDBCF387053ACEAB979BD35D30978FC7659ABB
+E844F4ECAB3303318ECE80777A5FA5A9DD91B3D06804C4B4E9B4EFCF07EB89866D0DD8CA390CFD15
+98651417114D78776B1A1D36B4BA17746D6BE7FC123D473EF1EFED1C3BC1D555F914536869FD5B0C
+35F9C83F65B0E6BF7A627B9202D787D72C600DDB6BCCE613D88492E13CA0AAAB196E8A49928C62CE
+A4FFE2D0208EDA334ACF47F20BD793124D2C5546C03F4A364369A76A0425262F9D9118AF54E37D32
+E33AB25DD533A49DF5FBF1BAF4CEAC2D9D378CDCD13B00FDA432D9042F623DA41AFB80699B5538A2
+5403B0B3EABEC9E8EFCF42FEF3EA9F91766902CD206B0787C187D5370B60AD6DCD002DE2DE8DCDC0
+B4719A797C5E26BAA67665016DA0D967FA1346F9588AEDA174CA001B31213617FE19EA218EC23597
+79D979E2663166489C06993230B0D07973A117C4E3F4A4C93CF8428248DD5389414D679C69644142
+67C7FEA17E35B0CEE456667A9B1875C81B2302BDDEA2818D6019FC1622A82051F60584ABC904CD91
+8676305DC03FFBCC64FDDAC8D8AA9CE2EA00D6C97BC63C8A617DEDFC0E40775649438E9F61AFD179
+5E3B20560B01BE5E0983F136CF48AB206954E41DEE0D9DDD953DFD01CAEB569151D6BC0DFEF29D70
+FAE3E198E7EDD8922C0E0BCB8BCCF1C016142C1A8B337AFA7A05A9D7534B184BF3BF827F371E9BD1
+9A71244ECA1BA73D484CD2FAD54DB2F0EEFBD54B536EBCB5094E6BC2F5B2AAE41F05B4B311115876
+ED42C34F8E643B53372E3F6350DB8A38445822EA9A33E27FB0CC42CEDCD1FE2FDF723FC47C996EE3
+56C402112F24D0AF899B2D00BEA1CFD427998BD22B2A09046D6737814448ACFB10D387547D7009FB
+384AF0562C85694C071584236D0F1F3D3FCD0CFB38B77C81889061E668BA7AB37AA60F58A3967DE2
+6F939B79CBF10A9DCC42852561D8D6754F1B660D216AAB1E133FBAA321C56E2584BE5C9BAE20CCF0
+0E8DBE6D9C2FCEBEBAD945C3C04101D2387351F132628786F6D9D4CAB83419288D31F9BC600D9664
+12E6AA457CE6CAD26A4C0671097B98C2384C81DD8B9A3222D4F4BBDA7017895C3EDC26662779AEE7
+40D9D7E24185FB821970B0A3A94041A69E4805EC88EE1EE521981536F2844FB8F5EF645F67D42CE5
+148E2DDE43AD5AEF200EDB3A2C7866C98458A92666E5F9E070178BCC39F65A893102A10564AF4E8C
+AAA5075D2F8CD7FAB0401C03AF299EA3515CC93066744EB5AF7CF0ED06675BF049A6E3C211A89E16
+DE5BF0445A7CCA6EE8EB0347454950485D884606651E5887FE8B24323E2AA16DE22FC1FC8C4F06A8
+2A1FDE5758976024068197E1F4506E4D3D8A16D40461A4586338B374A592DC60334402F76388AD6A
+457DC3F54E6169CF7AE3959676E966A45609621055EC3AF80E182633300A4418E34A66DDFA6B569E
+5A13C9115B5FD3EC1CEBE50FBA247F60803AA83976F00117536342DC3D9890C49B2AC701D370E43A
+955118967827760F7091469C5406F08F18D7E3548148CF0E312B1DC71DF67A5E7A1656CF2F47F3AF
+F3DD50FFC2FCDAB7177285B29C17CA43019F62AC6FBA52D1493ED7C427526470ACC8389BAE827759
+4958908F517B2863B83292EB5AB3F57FFFB08393CA610FB1FE905D88A0A16AC395E2A2A6DD033D6A
+0D68992F830B2E1B95FE357BF672716E88FFB92FFC3D62945D1EAD22BC68C51EE0E10A43011DB94C
+44685A5C4576F6EF44CBFB45F2A4BF110A01657DB51FD499767E78058199B31DFD60813F1A344F86
+289F9378231D5B151C92385E3650B4FEB1DC91018EAB8474CBF69FDC1496A4D078D2C351C8196451
+247A9DCF8117E5B637371D8E22E248C64D999015C3FD2311E9950B8EE0922FBDD3D7BFF766BFE9E7
+CE0BE12F318FF2A7B5A9C6D00A54401609304ED2C55F5C1EAC3D4B38355BBD85D66D61636FA6E30C
+2E82829376BEC979A6FEEE040E452359768ECF90CC539A546F17AE906C76F14F86FF697797322B05
+1EB311A759FE260C1EEE5DACF383816AAF1294CFFA7BF87A4D9BC595EE8F2C2F86FEEE11AD959D86
+F22FDAF4CEC098942A57E57813A0FA99239E994FFF353C1E781D666B8928CFC648FCF0869FC68468
+BDBDA7D280DFAB8B0B3A4CA35B074B686DE8D372C61FB32305169A1A9912F6541DA16CD6316A6EA4
+51524757BE5CF6E820011BE3859FB8B8578C100FF029680E05F0E0BF11D33FE19460C85EA5E4C0EF
+28E29407C8AE6BE01CFA0D5022BF9FB01416FFF722A784DFC8FCE330EC95737A854471D334FDC58F
+AB42867A7B62836A8B56466E9A6C1247D46EBAFFB905CD4321970F59FB8D6FF65FDDD34BF913AD32
+2E68455C5FF2D23C1A5EAE687F259BC982B6A384D35440F7C693CF50B9ECAC0B5578CAEE87588B56
+2EB6B7F42034C9F2E545EC866316552354EB3728C7D26527ED75174EAF635E048B08DC5D23E88981
+070AD5641A652F2344956E9CF4C16E652A99F4A644D1787D6D36537489DA4D74E61B2FC4DFDF1D1D
+9D58F9C26C5EB63200526AFD168AC57D5611ADE4D4A382FC28BB60F9E7D626A6C67AFBCCD1183C5E
+3CF2EF210D0BF5CFA7BB10FA3887BDD4CD96EEEAA8F9219AA2F10ABC0A960C3B57C0EC0313AE10CC
+FF1F522124CFC8D2D49BFBB0C193EAFFC5B48FB3FF30B21CB76F0A4C0F1377C9223145BB0468A5D7
+1B9BC25873EA12E1C60334571C67385C00D0B570D3FFC6C7FF0DE62C183C76AEEB12DFFEE1459E0F
+C818C621B8D12FA1357E2B55D48935D70BF140B4CFFE8813DEFD479350B20DC2EB1D3CBB1A2D3DC6
+EE975D58C89D61FC50E6A0197DA9A586B72255023DE47DABEFB11E8AA02414C2FF6258A281219B9D
+DDFE41BA7D7977D0D6F18224FE22F7D4E9355FDB35BF7ED3418F4F68D093AC48F7D8FE4194FEB6C8
+0B9DC1F74E023C604DEA27089F98C3973FF9F4AD7BF7BAE601DB89B08D5D8139B95EDCF6C885FFA8
+B3E4B0477E7040225733826BACFD1EC4A0DD72DC41734856AB9FB700DF83CA2CE812913BD142D84C
+5C83C0B2583768198AF9E885F2BA74877A414233207234AA5F18840557CA11682AABDE8993533887
+7C6D404BDE4153C9827EB16D66C1D73A8143C8A2D3604FF72CE579FAA3C5224BAC48EA83BA848429
+9472007DE96466B5B29ACC7C03B05DCAA38A48BFF9F214DE43146AE4E04FA705421917F99BC54533
+F0EBC01849E396216B9F0794E6F6C6B61B52EF1B1950C0FB609895C3C55FF574163FC8B6B09E66AB
+AED1810E698FF37CC1F926B2CDA3B48C7D77790EBD2D514B6F385D397F713EC3AD3954EA9C846158
+6031D369E8B99E53408A79D64C34EB5A56DE8A67DE91837960E98A66FC04DFA0EBDE21DB003234BB
+78665B039D0A469A0221BD541AF7149A2A659C300132C14581EF766FFFBECBA8B58A5EB3F95446DE
+F49AF863A8113D17B2E7E6ECDEAFC3834D4DF900E3475596E86FBB4E2974C090DB4AD61A737D611D
+92B4535AC291C56AD8B1C031D2F9B505BB77517B737D70AB3723DB52AE2ACCD5DD2F617423ED3CC3
+9CA882EF41757BF7151806A9B8B0F312808863E3673FB54DE939B35CDECA7FBC4DC3BDF5A5F47D35
+E345916C39366C8B4F439CE1C6F1835C320BD1E67375B03B5DE18C93256F251761A4C8CEC01019C0
+68E34447BCC503B9571FE8000627A6B3DAD5854CBC0A2D69E5A8F46BC78F6A7B1422334EC7A98ABE
+FE9B83E01DCF3C6C9273B346F3240EA225AE4A4083CC7B0EA141A0773FDE940768358EB4B13D82AA
+304A1386D450C1C0C6A7D5A8FD2BD313F78F85248B5196241E31E5595F3BC01F37700A2DD3D4A0EE
+2DD01A36569CD507130E8F5B1E96CB560BB7DA15560CCADF3B2C9804A11D9E8055C9EC70E48C1D21
+3EB756A1376F2EDCB7189D78CD3D6CA5865537EEC31C17D801605EFD860B0B629472690588D02575
+02C6F7A75B9A1C1B397781329832CF3EC43C09F1559CD562C48FA9500295CD3B0A790DD3FCD4684A
+7C7AC49AC9BFFF36B39A9FB148BC28D37907433943CBBF0CBDAB46D3EA86DC8F81C859C52D15302B
+94A9B51C199B7104DEEC9D769C2634CECF8B700CE9C04152CC59C9326BDACBEC4312DEED92DD087A
+1C4840868D9F97CAC046581F762F75E8D24D6445370A3F1E0AE74A6478D9DAC37E7FA5BEBEC0A1E0
+81AF89C1BBF7F51E3E2E22C8C405E8671BA85F1BF0DF79A465DAC7EC07F731E00632E017D190A99D
+83E27E5C2E63D7DABBA23B2E88334C63721AC5A4CBC5D45F4C177259F34C2EADE01FA008AF65EBC6
+01D8DD16436D86AA94C99F3CC0A2F87134E73BF22F108B825A8963B49C6C685474AFE4A542C8641D
+C0375D7EFE9AC1168D9700459BE52D0DA399023E141969F25C0DAC4668534B6647EC85454BE945E8
+26B26DE6E3C4584B97A38E2B40A0D23481BCA78084FE80E00A71A790BF31DF468A435ECC88E60A57
+860BBCA3D65930186E9917CBD209C230E8F8255A7ABC7D3F043AE4D7AD63D9980BEDF062B7D5C298
+C40225B6D03F29A0339E0FCA02138E526F06B9EF47F5E7A8068A846CFDE2BFDEBD24F5A73A66C079
+18662AEC80B43246284FA4E2EE0D9AAB172B1E59A6CC46B801149D8C0DF6DEC9A55D8E1B0EFD9D30
+2FF618075944CCCB6831D336B11617107B0530D09885E5CA11A5F1FCC8D69D603DA16BEA51116D42
+CAB1AA1E4D7B9B4D79993F2BFE53EAC904FEB70B2D330A89780EAC10D12CC0C35B8399F218AC2976
+E57A26BAD20CE2FA2AE2363D3FD2A8A971747556F2959DA74A8963C20B504711AE1CB0D0C02457FF
+2E9BF696B159AF031DD5155F21C0F5549B0471A3C5DC8918B675CEBCB23E29322B959ABC05283A70
+2E878DE8EF25EA760F3C5C7B7B49D398283DE2ED837FD59F7C22D62C58FE4448B1049FDEBFC8787E
+67D7DAFE9774979BB3802254DA59BCC0219F98C219F84D995CA768B8B5D9D4A32525DFECE003675E
+E4BD5D8DFFC11025AF2B468F9207B5B2B42349B98232BAC0759758C1F4A283405815BD7145C93FA0
+8F3ED2826655053A3C2559073D8ACD199DEA2C5BA5F616A2E48548B4370EC73493BA07E197165DCA
+774438B0766867819C1154D1959FE6E01E6312E0AB91FC2E2BD240FC8652A2D456A1DE7F34EF372A
+53794D4C4E050BF3CA5B7BD2F1B8DE93B4C8002485CB219AD2D029739FD3C81CC6E78EDF38723576
+1A57143EEDE5CC887F282FECD261F6A25D0A7E154ECDF5DC38E426811BE86AAA458577E5E0C5F0F7
+5AAFA9C41E5D1DC9D91ECD79B514F8CDF7A5F1A189470D35FDF4F9B8788879CCBD91B427822ED658
+389E981E0EE5F7FB87692A3E3E931DF8A1D1573E3B0166204240B7080089A09EF7487C9AEE2D665F
+5A82F94C877FB5B0DC531CEBF1E71C6592CEA2401E4B5122E5091DF03D203DF979B9A6EFBA12E2F6
+B422FDF15D49AC0914D372D21E871DE65CBECD105FD4A3E4714B9CCA5C6803FA39DBB015EA8A88BE
+7913502E562E5B170B87BFC8572DC9DF49AD63694311EF1334444BDF0B4CA3245271C1F7A4D7FAF1
+703E3AA0E1EA8D5C6E821B28707EE0C9B4F22F23796FE87356C58AE2CADC191F4C58E1FB58DA03B4
+5A25AC95DBAE13A293474217BDB214742B9D9D6AF35F70FED2891942EACE3E625E55FFB820543FBB
+250A062D3D395BC0F219ECFE0D76686AC148BC41476A887BC494DDBD396BE200FD3E03CFA12EC9AF
+6B934A283C42AA05589AA6B4A8D16946BB51F50419CABECEAEC5AEF9085C9989289E9B46BAFB6FB2
+782D84DE2B068F91A9744AAB237CEB1BA513E57E4C307108E993C972A3E0A898D5A8D27833155031
+FDB98863C3BE7FEF3004CBAA5CB60A1F2E3EB4D7290FF5FAFA088B1CECCB6CF51A58DAAD998F0839
+6CDFD68F5ABC9C1CCB8F6514107773C69C26873E889D1F79D10E866910E4684186FCD71C965ADF62
+39BA3418B313A27AD632300969B6F284519366ED85E7CD968D64823F8C59B5911A72D0A20EB72B60
+3A61E36F52F256FFCDF706B4560B4DFA5D918FBC530D83A4B3C01BDD3CB4572E24242D141BF9E775
+36693A0407D002E09CDA5B195BF1CCF430AE9824C07928A050D0B460F2704BE8F9E647A4884C4567
+0A81EACF7CC038643EB0FF18A376FF6F32B6FE4F197273327FBBDEC6443A299CAD4B26F7778A99F6
+5A11BDE047153E764039EDB251936AA43DEE50DDFDF8856519056AAFC4C5AE6F2051AF0579A9ACD4
+1D00775D7DBE70022CC263DCA5E0A25B9C7C4F5C418587666B2FE24816B1E0EC92F9074F1403BB83
+AFC3F1D52CA79C387BDEF864366E34C90BE52F7AA09935373A07E4E026224E76F9EC3CB9E7EDE50D
+EFDA48248D61F3CEC880A3B8843306375D9711E58645F3625BDB8E87052DA67F9794EF4AF8DB0BCF
+E00677C3A26907DC651BC838C40EC39E2B5A5DC0DBD345944A6C32226089D63C52490FA10B215AE7
+03CFB663EB8A47793B84CE7364DA1C4E7FCE32DFEF09490121222774915BA59C78C2275F829D15CF
+4D8686B095C38C731B83D48738C25F40B8ADD487C350A2EBE846C3916AE384CB1050F9F5DFE09FCB
+D9129C6270FD86D55A459618FDFA4F907E6B4746196BB717865AB378414029017551161A52E9D24B
+E4F7EED553A927933D4ABC8F25DF607779A717909CB4D810DE8F5762581900E224E4B91598149BA4
+71CF8068ABE8744356B261600BFCC57FB8BE45036CF6571D9B2A95304933BD4F17215F8EF53F8E08
+1AF61FA7F9583C34EB5655CB0ECB82246959F09091F36989EBDD646BEDCA614B9A61AB7696B3FF18
+1058A150FA6EC1BE2EBC7F64357A3FF2A2B0491D2F4E0B970DE5B7788B467CA678039B5EF55C88A3
+84578D427FD2CB16C87B0BF0A3D37CE8ED43E0F049AF2436344D5F47C948C632C94A287509282561
+6C64C5D262FE5B24916FFEE982A69A6CCF888BD01D62EA591EEC51F4B7DDFAFFBEEA93FE08D736C2
+0129E345D06B10246A5F57151C198D407730713F32299638EFBDC01367E23EB59AAD42A83AB41B43
+2DB462652E29813740F4680A5D4BD47B18328FAE6BDF4200CFA4CE3773809B45E8887C9B2E423698
+9F6C48D64F5986F563D9A7538A8716082F81936AEBD0461E6F4BD470436D8B7656F0FDF89108E6DD
+02ABDEF907731D458D690BC608EA9CED09EB1E6E64C0790C7A2378201CE997FFE0317679EE1D4EE9
+F91157449323E53B4ADA8096CD628B5861BF794543A98F2FA2AB54FF0F25A13DAD43DAF9394329B9
+5AA53CA32749FECB0B2BC035DD1EBD53FF9FB5AD8BCE06CD89E5568091C1CC314CFB1D9821D7F9AC
+7C55F55E0A16E39A87D43148201B928F3C42B110FC056189DEF183745F3B637441DE8BD4C3C7EF12
+F4258E306B2877ADAEC63441010750DB4E6269A4C78A0AC01BB3603C386651FE814031CB5D8C1F14
+9EEAFF652A53E57BBD4C8C0CE36A84A319A53BC1E5FD3F1ED1EE72F4C1A9BF264B594062FCAFB22C
+C1FDE3F2E3D3C17DD3F7FE0E15EBD812D550227C06D01127385374A11438ABD50048E17255FCD2BB
+85122A6FB9B7DA9D5E9DE8A747FAE0DA45A1FCEFE92B9E70A5B2CAC668D4D07527A5C1403267D823
+048BE671F725CFC7474B44FC5AAA348420B2D7C23C6CA066666FD6F2208E329878D90CEF1C2E77ED
+22D3BEBB9D547810B189F08920A27E7107F208591A84D463CE2576C70C3DFE6643E4EA93F4E1DAEB
+41D46F0E2F56FC10C69AD5034FC9859D31CF27A3A1EE256C93111F81C11ACF1FC0CE20B90BAC9AA3
+27A5C85A7985B951519FD4B03C40BE637162AF41B2FDA68F0D1E9B7602FE2659D3D75955C579AC51
+DF6A552EB9581AC3F712F083F19B52A6C4F560F36C59CEEB0C996AAF1728A2AA45DCAD79BD7B23AB
+388D5B0B64A2B95154B6259B730B0F4A72C8C7F7CC93C7D64D9D8810D1F63FF8ABD4DB89824E2D26
+4FDEE916C41E299211DB1A53256E1DB5CDD04862F034D9404B73183A99D3D13D642A663F129B6D16
+7095BEB4EAEFD03DF2FF2F0B6B594C1EE90FDB203DA89FACEE23F1BA3901FECC75FE1811BD701259
+343011262B6A0A9707AAA6316BC3C17F787BB80AC8DA5AAC942D90F80C5A3BB59E47EC767244AA95
+C63E50BF809998957936D3BF6ABC24B0A397258F9EB4DC8F65692CB023D9091FB180C69498CD0C08
+BBEBADC84A7E0016E8F8BEA325D924EB0DF82E75D2CC2CCBF039B11934363D4332C5FBC5EC556BE8
+5EE4E707CC2753CCC43D2ED50558E51A104221C9323CDCB0199B7B83454DE3FDC810D0F362C0299F
+5DD981B31D8E3DDA284FEF9DC8F9C8DE138D3065437A7FE8C30572AD06D62E8527AD37AE39AAB0B2
+25F76A25F6C6505241ED73BA494CF923E919F688DDEBF193E188F8C4C154F21631080763B4D091E8
+AD1D2FD6649E0CD9360E8D1A67A5B5FAFC67547CA31C95A5EA8D4EB5D68B9F6D6532DB9B54584735
+9558542A2AE58C09F3BD2918EFBE1699E9C8F2C2A11EA4D224C726D2ACD4A8D8ABAEDC6588CF2AE5
+66528B94F55B823A2A1F7BE19000F3E7579D094E047075DF18C8C868760295533B26EB3ED90635B1
+29C17ACA679C3E88B06998CE5A7A2544B700229F5A6A504BD3E45B276471959C8A3F81917A534287
+39B5EF9E3D463B3BA7318448E2A3E79520D2D245A2A72F31FF7070B6E4624E3A5E216BD103640C8D
+F387E49D732529C611F8B971073F17EBD2F6EB18F9B74A67E1997926DF178D4C9EDED435B9682F1A
+279C81BB9F60DAFE125845A2FF3B02979E5481C78A45C479BEFB9FEF3CE2BA9BC46C77B50B03E48D
+A6D17B76F06F3AD118371ADC69E178C52B5FB4B261C9311874ED07DD6D5B3226A005FDD7A6D53848
+09E7063F036CDEA41619122635E835D2D74CBB6AA9B38CAA4D819C26E95115FE0DBAB4198FC5838F
+2C91B7A87B07D734C6D4F4F83444C1E90AA9BFC908A2BAC4B3DEF9157AFCA5248F2DA31CA87BD363
+AC25E9E77F741D4B2C6E02F04987A6F49D30E9038CEFC41BA172DD675AED8B392164411144E5B738
+F3210B0E66B17A13CB9631C33D44484E792A7C082DD0A5382F34C5637653261B1EB6D2035B08B4D9
+1FA9AB770CAF40A103629511F7B43F2743D7E583433DECFB19C21FD4FD0AFCC22A4119E77C87BFE6
+FE50068B22479015BE5A9F06BEAB4D37412E062A45E0CBCD7BB39FEE747E96306F79FC4F2E8942DF
+5D9DA0E55AACCDA547DA19D30B8404FA121298B44C9CCE198C708C69A8D6BF17591C5C50D3FC5BE6
+961F7ABA8F366DAE957A1C3730DA4A5B4F035A9274675EE3BBF0CA8CE9D8349F50CABB1C3EA4948A
+BE6F9F143592F1EA95404E6909A909168E3279A957AE1924245C356331A75E7008BEE92BEAA304BA
+40B7C3F48F74D9018B3247DF50EBD7CE541DA48ECCB1B0BE51A455C3C13C279D4D8676078C3EBE43
+08748D52C9B041D3E7244C745B1F2F742D010A9E60695F3EC4FDC1050AC082B905D6A57E8F407A3B
+472F731011A5798965B7B1A307E252FE02C8F79CEEDDEB6E165F1A94D7FFF18DDBDF79477F14E9E9
+3981ABD200FE7771B29D1D2D120EE79D28B9543818527039AC74085EAFF241B56D08220C958B5D9C
+87C0C04A14D52AFD475B542D391BC54FF33DEF8D9484AFF6873BEED32DDA4B371112B523B6CE22B4
+0D1B416B64C9370F1CDF2C548F4CCBE9E12E21C36CC3EA52DA232DCFB65F66B22B5E2EC04852510D
+5E264EE939BB67AEC4764B87062AEB7F680B40BCEE04AD45C7519EB3B6199C9E0E332661463647F2
+FB7EDF303EFEF84891CEBCF0FAC5F723A9D0476C3F8C092604C87FC69C7A90F4D64AE45A478EE8BA
+2DF50FB93F55A3546123F0B0E2C1C40C98EAAE9F0F26B8F80FFE6E6B94B7E27D2884D58B8A119662
+2DF6BE608C5569D7864BB756DF2EDD184B90812B44ED4A32D001C31383A40AEEE9743651F7950846
+15C48E402DBC01C818D477EAC0347795CB2792E9C11E8FD4A02E194EED1C919D4598FEC003B6D9A8
+A0BC7D456047A1C0579453FC1D7CB2D158D466939A23D7A7B8ABED7E2777EC7487973E73F2266D9C
+250CE30729E3C5223AD93B9AE8443B35711E446A3DC660123ED45CE1942A1A2AD0610467E081CE2C
+8B92A6C82F0B17B5D2429E99F1A6268072C6B5AAAA6EB6283A872C54D3694CD825EB2926E57DBBC7
+C1663075E687A144E4D61C225781D80FCAE1497B442342B4A3F1CD6BDB50E31791CC3928C30835FE
+F845B6BE5E2D7E3F2F5F085AA3FAEB45CAD0D76BCBB1ED859A9CEBB9F7457036F0BC3F195CB1A98C
+9C8648F6583CDBB23894BC719D68C2DBD8003B10D08C8CAA40BCE784D7BFB4EEC9EA5359AC056E57
+B8B0F2EBCB1F4CE40C87FC7861180133E0CB6CE2FC4FE690756D327A2B5AE063E3021C0C0BD420D0
+56F0B941E6B36088A55BA11D0C35FD0132D5F48E5D9673572347171B4328D4807B972831C0D74CFF
+A5638C145B89C989E6EC942148207D6DB82257585958034D9F9D4221C7C9F7013790DBD130F277E0
+BC88BB179DD09E27062379ED06F25EEA8B7FB33C35861A0034776E3813D2E9E5C10E227CC569AB36
+CB2D9DF2E7B7B44758F9DC4FFAD7A24AC7E9F47AA850C221048C3CB35A37CE8EA75632AE65FE3212
+175146FECD6334AE3D3C5F492F067F795E1E8FF386BA198CB74F0BB4DC0000DA383BC4CC3F070DE1
+7721431988D69C8B1A5AFDCCC83C22E16A87E01C6D3E79DC7AFA3DB0371B0866EFB8B6F88900472A
+FEF1C4A878243C52D4E02E82658979731C841C489A6B97E271C4C93800EC7D91F93EB9B9C659A554
+E1FCE42A5EC65AC39190EF4B66DEAF6FC0569A000A9E1495F42F706FBEA4D32EB7EF11A648910259
+6A65CF899C2F322F5679C6D123469192A9BF1A7F1F2C81C554ADB97BD19ADB746A4F81A4D5559E60
+AB94C483DBABF6CE2F28CDB412D50FF3FCFA3B3DAAACC6A83CFED910CCB3B8D2C19590AFF4D75303
+4A6CE7F4156896A13808E0DFEAC547E69D3C886691728E4A35ACD575B40D721E8FCC5385A2EB28D7
+08101DC50811529528F5CB0C009BA7E3C88468E37768FB0D83895AB54DB2DD5426562AF9D8AF304B
+F6EDA54E9C92643DF926F5C3578269750120302A37CB140A18BA56BA01108D4ACACE8FEAE640A6C6
+958EF156B588ADB0EA5F3B0F37BBA12B7BCB221C811415387B024B7076FA4403A3AD6EBB5D9C26EF
+EBDB7ADE7C60B444AB9F90EA493B658B7767AE2BE649BDBB3FE85F460F1ED137C61BD95F7CD3D8B0
+15CE45138538930AB62AA0E54B4CE1A5EC5FEC0A2B28B345B67089A4E4AE14D2E1F5A9C8848DA688
+CA298F93860649EC3AAFEF3E820D86988C8E3E5A4D4BB937791827994AA3E81D0BB3EE115EC36D5F
+B9A392D09E79AF514D11C7B3A03C9F9C13355CE79E119A19177FFDCA34704D38118A8976D1EE5AA0
+2D14FEB1414419F5E85244ADC5C0A765A522EEF36170064BB19FEE3B5F7B441E4DB967DAE0BAC2C4
+8FC6A836E0EF5A69F073BEE1699F55E9C757EBD6FD8B514E2B49D6333815B7DBD1E0694695FCA3D2
+1320A0C4B852D9706DADD8369A95FDD917328BE93DD33818954DBD2C212D2CA81560ED5BC284EB04
+7A5F389E24E43F4FA8C97FECF46589FA7341076555CF55B1C21B28E0C1CBB00AB8B6F67472F27BC0
+D11148F407824B0159B5188D4BB7386FBDBF1C0FAF34721B7BCB5C0FCB7C4010DCB6A1284E9D7883
+9E3C2111A05D29AB7997073B590A81C6168020F1D48951BC7D8476D5BA593F4F23CAC1F9BB0E091E
+84B4E99E5C584D1370DD12DEE8DF16AF8BC6B7B23E2FEABDB7F32779AF8E2B5094A6E9B7A7225F24
+C43A8E5D2B977E1E19E633C26771E23017ED233DBB02C64F8CF03992C6484528D0C8464B46F24F9E
+8380F385D5D01B8893C67FC103498983CF939432AA380CA576D09030CD52FD99BDC3BE16C7204CDC
+3365BF76294A83A1FC14A236F5FE5321904E779B13232A76F8FE521F425562678436359C2461BEA5
+AB27209541F557AE2AA60009C9CA0A9FC7898C14306CE35A50017BADEFDECBBF94EE2905220706DC
+806409EF87DB1D73EAB0698AD2DB72CDCDB293E7FB13C94D9FC87E74502E6927A212F0D7D2F2D194
+64F7A66AC07872E18CB1DDE8F11835DCBC5C4EF039333FFFC0FC1456DAADE7DAE3EC2EE0D3415B0C
+ABB69FC5006F4D14A4EE1A5CA99AD4D5E629C0DD1E0F097B5B93DE2DD001A8C418234C9C45E8C13D
+1AE04E9466DAB8CF1ECB88A4E059C111A6468D2DABB90DA79C7C79E94DB28F6968B1A632F8C57D9E
+565FF91C6916026FFAC0661856B9FB8DE9C81661816221B1FC159CFEF1751E7E403F5F2CE32529DD
+540792FC17A12A3DCD7C50D38EEAADBD10ADBF5D8A82442AA900CE6150EB7A4639DD9FB6E385B2FD
+093493DCCD9014B23EB172E21AA89643A6CAD1093343D85D81261972DE0ACB16A4C6B5F0BE4C978B
+FA12D3CAF0134F9EA49F6E9687C8F99A456745EA252F0BA9968C7F9586E3DD841AA92DC7705BDD68
+2DAE41518A09DF0E209F321D7FA3417202F4BA76A984DA3ADDBC58136885362F02F0A24EBC439B3D
+BBDACFFD8498EBD29F88F016B1FEABC10785438EAC860B554525F3266097A675299AA0967BD3B7A0
+EEEE3FC578D1BE99D3533BD91571AED904BFC9DA1A1451FDC5406E1CD614E0C7FBC733563CD6CE6C
+C31E9237CA153F1F0411114361D731636BCF98555ABF12848AD109371A42B63675A4130B81E97C2A
+2EE2BB5D8FAE2640156001AF0F55D9D5DF8FF23C8AEFE14F120000F14149A36E5C94CD9081DEC277
+C2C34870D05011F99D48B0875A5FF542F067F7E9880109F586BCF2B50522A1F23ECE44349E539E70
+F84E207DC9BEC7CDF856A046F1A03226AA41F541719AD1AF88FF211E57DD0C1275DD0B7B47440DA0
+89B98C6EE92A7D94700B83CEBE19EAEDD8A615F6587587BA8BBA3CE3AA5E8EAFB1FB0F486BE3609B
+169EFB178A4292F4C0378AFE5D24EED1CAAB514DDC66C696D8E37F294A6579131DDF5488E9436609
+ACD750C3DB0A940C84FE022B22ADC2676F62E91E8F891225F891FBA537679B24547BBBF35F04915D
+20B11739F620D18B5B216921D222F15044368569AA302980B9225BB839F494588481B94B0C724352
+B2DF600A22B062561D86CB8F81514FBDAA4F8A043A0265F992FAB71FC9124A45B8475E1EF3DF6B6D
+E35CF329777D45F08325E8505EC0D979F542807AE77E57E453525F23BC59A50740371EFA98678AEE
+6C425374AEB745B99DDB5D8D908FDB551FBC0DB15832107BBECC4E11A1A8DEC69358A574A2ED46CC
+31D564549EFF23102D92BFDCBB2BB985F78F36033E34F59C0EBAFA3BDD71338736464CEFDBA91398
+33995EDA4207BFD4A9867D32E867FBEB7DE60D132803EF9347CB17BD91315484EF6570892297DD8B
+7D966103339535E28A00CB1EECA4A9775F60A9F5FC9BD8B06D78FE8E6318C31DA2E847E3F9CA587C
+B01AE2BA0A2EBDE308314413F4F230A758184ED60D4F71F6CEC22A93A01B6C54E0449A3860FCA895
+4A347B7588329A80974ECBECDA1070FBC055666375229F13DD995E99265DF870BC8B8CC6347FADBC
+1A6AF64599271A475B9123493D46BEC41289BEEB67EB97A8DED7A9C9730D37C65164CFBDC22E5CA5
+89D2E7954C7136EF4E084C43A6C7F361A3E96989239BDDB9A593CC2A80BA16DE9EE90E95CD39393C
+212AB22EECB677FD36D34DEB46C4AD0D21BF7E6D7CBD0C8083842FCD87B18FEA7CECF939987E99BA
+34C214E44DD84C176C9CC5A4CEA76D380CB316BB4EF9DE73D73B4AFD4ADB54451591DEF86621D138
+D5A0A29441502BF6C2ADE671CEC3CB5CAB903A657EB2D70C943F976C110E46C5D9D29BC00A875F27
+38E5D22496A43E096E009C5D3CB724B4CABB32838DBE527F83B18CB457E57B092C302EE557FD4F00
+DB9C56E66C9FDF4EC9FFAAB85F60D02BA79694FABA476A199A0331C30A78A92E10417BA236E23364
+8174C826331DC1BAB87C5F95027846130C6A2B4027930EBF9A97BA1B039D386FC51C302648E25980
+212F6A582CDE2778C677A01FBFB3C5D1B8A374ADAF6ADBF7DC94075F25ED66D440B3922C5F255FB2
+3FD8F6E21EA65B1D93BB225684B50F11310E242B087575973345B229BA62C1E2C35BDAEC04D10148
+F5B2F3BCF7399BDFDF1F3F79119714AEA697245BC647316EA157484ECB951BE367234FD02E8B1F09
+1AAC3D29BF282DFF4011BC0CBA8E55234D943DB3017CC7A766720BBC29B2D097A956C0F1067177F0
+12D42ADCB473CDE8D1BA35B4030757FA1D8211989DF3BD22CE5D501C21EF8708FB3449DF47D88650
+9FF7B59B76C0DBAE443F336FEE2D615D7EED1C284F14335BC8A26BF4621E10DE9611FB2F1DBD52E4
+B7565D8C65B54EA36D508BCF0C578A49A2665227CDE1F9768EFE847F9D94F1BBB7DB83701C232198
+5C7283D47B2E40B27A268428AAEFE75F6B2F8764A8494E5827573758CB9CA46FA93208836BCCC8B5
+564A69F5AD882052AF1C1417C3FA7F580569528682C77080F3688B65E7FC24D2A3AEB61574B4A321
+5927281544DDD7A6EE0A3E9388F8F631CE7251724DF70726E5912DDCCC8C652DD6C9608F8462303D
+867F589DE0F2F71711B35142EE6EF93B64D6326C4DD7DC83278E057100EE772082E6BA368ED91A55
+53ECFE2293A481E42F83BC8F9148C70EACE91F7B7D9CB8A72415BDB3AF66F68EA733A17ABE9DB005
+3BF148629132969589F38D30EABFA96A01FAC72650B5A6FF3935670198A1EA33810A9B11E330EB8B
+451F24F93544263436F669AB5A90A53B16CCEEAC36B1445574EFA7E802DE73522BE725E68704822C
+B7D3912717333367895BBFBE06966A5CC653AAB5E9B3596702086BF0010085B900711932A95ACF15
+CA4DC45A754EA334E9EB84D6FC8E3FC4F897456BED64BB93B593549FF0D5352275D8E417172A6664
+C5E0ECED1019494A7ED49AB0B965BEC1A82E5873766BB38D7D856049CCE2FCA65AAF61E961B60634
+E2A69EF059754C9D8163D87F928C222772D070D83FEC6FA5AC734AF65E40BFDE521F7D9CB1650FDF
+64754BFF21EA3FF0AF7611A93D525EC9B28C51AFECB04E7FC8323DD6C9B0D8539A34FC3CD8CEB795
+8E8EBBFED4313C77ED469C199552A9FF70BA5423B03B6148D4EAAE17B71C5B39DC436AC53D6BA8A7
+AD81AA8B02335A8B2B11E9F4FA913159A725B8AB60F52F1A2EA50EAF4D56656E615BF382CC68A690
+BF83DFF24FE986570ADC0290ED1A37C1C2AD469CE789E0EA0BB5CE01020100E729721AF3B5BADD33
+A2DAA6C33EB8F9064F5292F715F820B4BBFDD56F76D42E7A1A068C1CBDCE4640082F6E7D582D1939
+990CE6EE8D270015A2C461798B37DCB5798EE9F7512168B76D26C28BE4A49A1BF96C89D235F21A1D
+B6A96E5DA474D0B19B808D13D7A11BF39EA8647499C410ED9894A1ADF33D41B6FC2E614D8087F4C8
+4E437B136F3CB32DB8393C49177A0675A0C9E7EECEF448A97AFDBE840FA01FC7E5F2E8FECEDC1884
+84C312E8635CD79195475DDBFDD4D38D5A0246DE2C7F21608F8D2C0DA1371D302E941572E5792A3C
+F4E51A33228B93A814D03FD4FC223C314CF3714BB3A34BD4F7ED6348577FEED9DEB082C4049E57B5
+D3CDB7F26629E9F3BA36893E09E3C7463D02A22D7056BE76B87763260E46E48BB832B7EE13F8DC05
+37EC8E81E9BDFEAD8C27EBDF1AD706933EFD11131E12814F236EBB01BE85B7F1B2D627413B324918
+D247604F56EC128909873FEC3857028BEF76A3494364C2A7002D104D486236C30B48E2B75D851C34
+EA50BA7FFEB4E19190898AE21768C157C0CAC628A2181A32796FBC1A7271D2473CD88E5395DDBDB1
+FC3AA8DF0F3D588637F19A8B833AFDEB5F655A8838EECD684E2315B72C75CEEFBCEF94344ACE8D6A
+DBE355008EC72FE7CEEAB01363A895F4E73F867639BE0A0BE67333848816B05B419221BE8F9066C3
+62C23FE85B7F392930BFE4C12B9526FF2FDEC38F23A159ED61A0718E7115C24597D849FA76369153
+54A40C965D4D72EC94DA61A03766AB39AAB684E134FD1407A5B1B19BFEBA52AA0DA5D99CBE5C82DB
+AA663711E6DEBA180E1D4A39C320516A4350D296BC19BF1BE054859A0889C7E9727A021F3176FE62
+0FB0C837E4141FECE531A950C03D319E3255703220B7185BD20FE5DBA673F8129AB211EFCF36EE39
+4C7E00EB0876624BC840FA86E58B2F584754CB6BFDFD76810E300741EBE4544E5AC17413ADEB21C6
+2F66CA4F075C32381796BA709782DE34A675B717A2C7F6D88104CB924FDE5DF775B4F0B68E0E2E5C
+2F788BBDEAF06D8E1FC2105CCBBD5827C0B03FD6CD64F0D073F3192D5F94839644E5EC6C5185BADC
+F04112A65F49A8C83174A9AE958E76A2F5AF469E8B76C833782C5FFB8BD7B1BBBB3EA0CB7C9786C3
+BE2ADE5E7AFA8C8F20892659A59BC421E28845A108E34EE17864042EF587A6D67DECDFB3F510EB40
+D2229585347A0035670FCC76C2837A4E4D68304FE113C539B35C1F0234B5079B8E32934546982978
+C5E4DF955A454EA263C3CA5D7101F31A318D82A3F9FCB5A8AFD7A65209663B0FC9DA400B26F285EF
+46D0E1EAF8ACB1F1CB805E3986D04BC585073FC64895E4DAE1CCB749BB439CB32EA91176D5C39C36
+50D10AFB9C9884D5FB90183424CEE67EF2175D01D2478D67511EC9F54F88763C152697B06D948BED
+49240096EEE3D06AB4575E8E8B2CB8263B5BCF4FA1608720F52B675309833071879DF52C3EC2871D
+20F398B5CAC8F8A4D41D0F1D47584DD90DCDAEA4A1CF160C4B3BF1AAB890B5CEB6CB3488672AA68F
+BD938281DBC1D8BCFE92FBF514DA5358443CB6E0147254E91B38CE6787B2BB0DEDD2D38F5938737A
+977B5EA42892520C58F8FBB53C994B57382379E9490F0D6970B980E1BDF8CF9F4C3C5E0A18F66E86
+EE93FFE7FE546DE50F41364BCB3721B637072571FA1779F1D672FAD260C16D7F13CBDF3E4376E7FF
+56D2A710AC5AC35FCBDBCE2C9C17E523BBE6218617B13C1FA6679B308979AE7C61DA6E68369324C6
+CBC7DDEC364E5A86707266C0B459EE7B2C03FE584E529BFFDCE98C90A2F3D9305AA74D3ED8430DBF
+3A49FE2ECFD9C4BC9FEFD22618FE9C8A973AD072AB6F713E4DF02DCDA7AC5359B2D652013E131B76
+B3ED6C75FD53BA58D862846264627F6B9E70D8800F6D9B32242B747A67BB2B45675840D34F852AA8
+062FA6B01E31ED24DAE02F6CF788A17F7B9368175195DB0072259CCE0FFB2C1035C1D26E1777CCA3
+D56A827C3242069E76D6DD69B653768614B9ACFF16567FEA61508D51454BC02F6C60F755AEF6AFAE
+3536BBFA1823F8E1A53C41124DE983E51CEC92AEF4F99785D554488A51C20885346D1F761DA79017
+940A0C557D93F1DB6B3D00FFD61D08E96FF3AFCE5FEDF545CC9F47A2B1BB26713431D6D1E47FD6BD
+6E3C668B0368241F0EBB5FA9C991DF79890E52E83A3675EE699B61BAF869DE91F67278F510061C6F
+E41DE2D883F48CD0E068E2A652B244128D82E5CD52F35F210DDAE3054691ED55A7D99088AAE8FB04
+F525C2084AC09F5EDF80A4EFAFE981F74C0DE9D194320709B3464F3FF2C0F6AAEA6D973D9C323F53
+DE3D741F698FBF01036716BBD62957CB32CD81D3A2674560FFBC5BDC5C6E4F547E589AD0B1CFE14F
+5E17FED1C4A8ABE4E67CCF8A49F32C4C6044F1431E1CC382E7758722A6D0DF9ED23E51F8AD14D11D
+7B6428E27443715EBA4E9C05D6F238378F9498AEF0E7EE4FE6856622CC8E6ED141EE5F109E343CB6
+695C4BE1E0F66601C27975983BF557C04ACFC19227A1AD7E6C44C00529FC7EDD7F886D24B7E029B9
+C395260088BBFB96972199A7B32796D27257DE83A7402291C14FECDF7998C5C96B1EDADE0280F856
+8A8F5007852EED303969180B3329917973C2D32C080C9765B6BAB0673BC7ECFDBBFBEA980C263843
+39B7F1052591D91667D4FEE413AFC23DE2D4B9DA742F4269C6C939F5FC32A38040730A018155AD73
+3F231E4D5B9D01C03A58EAE7B5F590CCFAF25EDC8552CFC8D95C60EBAE1837D7A97CA137E9D4A4BD
+2CD34AEFD68D64B3F4F62326AC429921D7FB3C235184FE0899690A0B775F1A566EC29D5830D32372
+6526F7E7F5AFDD71B77E07613DDC4FC63EDF49051AEB59E6337AC0A4B6DD872E776C9CD0CCB86130
+5322D816732124F5978A86C186BF0A0F88E733CE38E4D7C1BA5378C5629B1EFC97806059990ED42C
+5CD183BAD7E94070E4058569DA2E51831FFE0D080301AEAB4350BA290318AEC582C78D05DD92E5AF
+B4424EA808629BC972E68F4FF2489C245593F07555CA6A2B25964794CF31CBD3AE5C229AB9B8C298
+06C01D116EBD0FF0F159ED2D3D7DFC73EAB4910BFF5B0B0B587CD9EA6E6FC45D63C09766224D8346
+1F0588140B258B1729F70BAE7962189B1554483392988CF230AF4077193E53330519394DD99BA135
+6D4730AB221DC6A66019BFAE564893DDAD7B177DADD16ADD21D396CFA6C3DC818052E2F71149FD59
+4A16DE0C2FFDD366C99B486C55A6E991E4D22CCB15843F0C3363676AF2F5B2D1B7EF66CCF2F12DC5
+0D63776BFFB058D70A9C76DCE96C754872D72C82A0C33F90D49C935402CDD26B6D743B1F43BED5D8
+B539424849C1495DAE73044E885A7D0F307F1816DF6244A6F2D97BFD4E200E93F69B08AF39EA21E6
+E347A47CEEBF803F73B978ADBFCF056789BB8E6E2563DE87DD9A8C877157B934102DCEDAC54D487A
+1BB2694F0034093C48F10A17D32E2BDD0C723CAF59ADDD1BE373AF8C9BEB4415AA5AF36310C31F24
+354A53C0B962573148BEF91D994FE3F3D8450DD4D686725799F53C373A0A3E3C060C2E1A3E800504
+9F26D716E1F381B9F83125E4683264A07E2D8938F605978E2513DD2050B3D8A1012797CBA8961632
+BED260916338A812AE751C7B657E086A0C7DDCD3BFDDFF3E48B84751925736D1310C4910FC114387
+F3ED7FE163F91895EBF55FCB425CEF5729D99BD8F2C072E36C310523E75CD8E5DE49C031C4263410
+9D56E91A46C8C8E89FD92012A00C33D0DEC52597B5C6933291A7BDC5CEDA95DCDA5600F9AE1C8250
+54E7EE1067458CCB66610704C58E4A4FC0CB5FC933D0322A716B2CD430A3AD48DAB3D4CBE9D23F2D
+092368CFC4E1F5495C133A92942EC62118D45C17723646E69407B4A89DCDFD2AB3FFC099A21D9D29
+741D68270629AA3A414FE58658DC9170C247B6E23F35C4BC5FF83009F462F2EEF4DBAC5FD158A658
+57F9B6DC1F5192DFB169DCB65621CAB2F1B07BD22F4155A8E9E2B6388D430FDE5EC1C834D22EA035
+C52E1E34482EADC36B4CAE902AAE89A7284E62B3C84B608D6BD05F75BC31310B2DD3B2C08A00E073
+7F104F03A41989D5F6B9A2C38B22F1D1803EE5D7A4D8DE44E4ABD496A1DE0C0E12C4BC96D0122846
+3F0EA9CE9509FEE987139F3DD3F9D0DF4313F555BE85433718F6D05F197C41A9D9C7A8B0D2740196
+82D49F58DD5F66B12A6520D9F226D1DF1F1B65CDFA261F980CA25A92645B86B64606293F8BFDE364
+C47D2AF2C709BBE77A70A5712F2CC26F3D66F5BE2C307A48E6F887F681D30121E32BBD87271B5DC4
+615D28C309F15AD263FB37424E56DDA6E17B998B45BE6C7FC6C28E3394A8764C9EB2DF5C06626593
+B5C665D550D4600172791CD208AE9F37BC082B0B242B0A504B751B18F4D7495172B697EE217834A8
+A4FB7CC16D6F9E8BB400BE8AEB0850960283DCE725249FCC4DE97D9886745AB6066C3E2F64DD8AB7
+9AA11667F11188D7965DC11EB760B772E282DBF13249F31986AC6898FEBFE23E3E8B8D2C33E00EA6
+FC493850ECB2E6D831D1EFCA3C2EC8EE2E394599091ED58BEDE97D7A43B6F739EB0F845EAC1DF6B1
+EBFE876009CC5D804B15ED4B56761B3CE1AF59C07B49DC798A44532297AD73D5101ED47F36A3678F
+818297CC27F6AAA2AACCC9AA9B6F5459911D8C56CF499E390AE607F3790450B2B9C9BE0F006EDA0C
+715B5CA0481734CFB0597478E7602B0D2C1E4F78F03C68C17C70E4B42D7D2D3C95CF40F73488B371
+8E2CB05A549944D86944D78724E266C3319AF89AE430E777E95F0D792B1C654306E421F3D63A26B2
+1E74B6E8B21B2E2B9DC596D013CDA16D08E65E8F24A84B12B2BADC653E6E1110DE2E709C1C1BED13
+707B70A421B384F20CA7A9A9D20324DD383F28B2D3C7A9C53F5D4C6B7C378D26DF11CF55238BE1B2
+4FA70DCC178DAD3D35670FE4919085EB1CD905971D76A368FDFCF9D2F0A23739851A3A6D2E02D65D
+54DEE69ED5D81315D3EA5E356F94EF256DD267FD1E1A9EDC9CD63E743F299BCC4A4506233B8DD765
+2CA067F741603F93250C087D368F9E9CC4CC1A6DED567487C05BAA992B0056A77F630A72008E3946
+15A9DB24FE56A956650EC9DE90A6C2259189440247970541CA198748928215C0E132A81AA13208D8
+63C1FE817F70CA573B54577D10B73100AF8EA088208A44FB92ACA314AE5879706180788C17BB1D0B
+81B6B95A1C4E0F9EA66F9B39BFE12444A6446691A7BDB03E0F03D9F07A10A7598F2166F108529F34
+CD90E601FFED3479ABCFCBDE8F051C348E48C61D95B00C59EA1287423F05666C3D36288844067E83
+E14F6B5210842C742B89F13ACD126B9FC50ABE2CA7D7ED513D43B6AC7F41EEDA416BFFFCC5C844AB
+2D23D4DC09B2D510504CE98D02E72020D9E669DDAA344C63A1B75632F912A1C0DA3885DA4AF7E243
+E4A4C6493D6595BB6D56B0359106957259E59E336BAAF35BD1CEC5CDE735272EBCCAE8D4904AEBD2
+B32610C6FEA2B69941D6542ECB44D71092A3CF067708A3D087AE99FF29671AB7DD8758759B971A08
+AE1BAD78270D2FBEE37AA2DCB119D72F6C7B0C8509018A70D0B0BE2C6830EF8E0B24B1CE1141EF87
+3A4D7DCC501F808BFD94E4DC0F2915AA023076BCC8006490A43685EA25AAFC187302EBDE7FE1965A
+04A5A398985D29F08E085127B56B057334D88EB638A4DDE64AFD204974C3939536B1B66A54B4DB81
+151853915718F70813F096CC1B0EA25E363B49264C2AD17158A4489F91453FBEDBDE15D7B74D7F98
+E81DF23251785D58295BA297F295AA6248A912CDD4F1111E6B628EECBB5139709E76EA4AB743CEC8
+26621D08E6BC64691CC90B3C3C1778931A28D3D5B1E20E96C643316613FC487C9B604C43463FA453
+3BCA1236286E6F5A6EEB2F1D9C34BDDE4595495A365F88055D9268541CF1654ACF478D384A5496A8
+772EA1402751A093582A6625A0A44816B5FDBE166835D598644296249B92CC90AA3FD6445C9A19BF
+27F59CB0616C7306070F33C7DF4E1DE64AC8C5BB2FFAC1EF2B1B30E5A0275E6004CF64BBE2C6710E
+DCFC3AA4ADD60106334708862FFA6652825BC84842736E47AE6917180365C75B27505EED3C6108E9
+898A780E20C3F606A860229AC46D0471ACA0187D6D539A1B8820F620F72B41AD1D3BF3834BF48CA2
+AFEA8BF535AF74C4562DEADCB63D2F5C7585722B77C989342D190FF926C8A5263B4F25286F99CF6F
+C62EE6E2AD61C82B29D82468AC10FD27764278E5558CE8B41BA111CB2F040914451A480C93084237
+CAC8F66BB7C6689F340B8ABF0150E06D5B1177278A4C08742FE22F42C28680F190900344ADFA486D
+59718C25D37275BCE4DF981AAC35D2C7E85C72A0188B8953CFA516FD545AEE0BF4B8BA301CFDE214
+4241FBDF3D204E3D2823301572E23F204C97305A82401660E12926EE7BA6EA1A81FF5C007933AFC7
+3266FAC4C134ED818A48E7DA01C71A46335C845F9DA5E960B25339D551582B375814148D94CFB781
+FC56093827B78578A73D4FF67B6B87F40CFA5E3F4325D9108CDB64BD06427B88C84105187316FA29
+90B4E3E8EDB6C78ABF164F4A9717D523794B2FE772A04DABBE688CCA977090979B5F47CEB90A1DBC
+167D305EAB231C9F4260C4AD10889CB785169902FC0BED78DA15B8417453BB65856EA0BEA5245BA0
+573F623D215F6C0CF801851C305B355D26B52B0B343645FE25C78A3526841EDA480919A1BBE5F56F
+C10ABEAA3E1FCCA7C43EE560F067F1AA2AFD642F769D1ACE8E2AAAF38850F0D757CD808C921D716E
+96FBC07DA7860DFA70CEAE2888C0ED3CBF9586443532B68DAED9A926655C157A416C383A53D8F283
+2A4E67468112A09ADC837ED8EC95F70852921F50D4417239FC42EE3624CA97F682745CC5E76CC7C6
+7BD99F2180F8C0B7FB49539C8CC474C25C0DDE491671FF329E51BCFA779346D4686835A3AD6633FC
+B5E0F67E0CA9CED8F215BEF4D240453EB2EDD6ADB22278AA5B985FA140C9834D38753DF2014F8C0E
+E6DAD19E8FC54C03C1F6CB0F858986691D99592562CAD95FA0A5B2ABE4A8B54B457D42E8C33A2D19
+51C0419A72FB94FDA78ECD92BD2A1416459E9DECA9469F35E4C47DB531726DEE8F203D7042EDB32F
+025DF3D582547BB1D45F7A5B70D317DF4EBB16E36B0D798E0932FD2A85B04FD67143E4B287A50416
+2C1F5A037CCD780088C5476385AF8168E12D97D44B0630621759173C8F1E3006B5B1C6D7138B7EEF
+C3CC5F54E24B2C3CA7B41AACFD25E554880AAF406EA4C3C6E21D3B550B040FB1952598A7E8E6488F
+E38288B2AEB6C4718338598A2BFE4D2B9D14C65732DA304C16FF3E1F8F03046EF095B65FD609DA87
+EC24A69278BFE65C905CD0329F6A486B8525B7EEA4F7AE56C2633CD83543269E8ACD6D71F500D82F
+DFBDE7F7F7B1AEE67328549232E26CA55085B6E84D9E2E7F74068F93A90C4654F2F396E57C5F76F7
+E61CBBE523DBFBA6E76638BBA3064DA025A79E3A294FE7F1CC28A3B4C57DD6FDC48E541A85534B25
+E1BC11B4F78019457239EAEFD4BE9007D205F1D985F389DB22400B279C10948551A6B4A17FBDA0FF
+C9428B18B43DC76EFB15FC2182216F1B60B4E344A03AD6C00F141EF99F89F24C819C3E32877A927D
+84C2D006940F39CA8B71E5951673EA9BFD1749923219DE38929ECAA9CE43B06CFA7DA1BBEDFDA56C
+61FF6C24F40E59B13870D5FDEB82D981154FAE5D6D5152DE69339359461A41A9713B6BBE47E868C9
+33CD74C75DB71D13BAE4DEC85E02FAA14EAD6C0A253B16C79514657B15E68CCFF9EE6AA385CFF9E2
+C53D9AE40F85C793E4E8FF50B2B7420F4FE69807BC5F37C3E300E6B3C3549D1D3246A2E70F091054
+1135BDF805E0A698E236B6496702D061241687B7B8D1A0E517DF0476DA09D89667A7AB375FD2672D
+CBAB8124E511502DDBD08BA04D941DF1CEBDCCF7ED48405CBCC33774A68C5212FC6F132641FF413C
+984F8B43BDFD7B1A2A3435F15AF07EF4970D3E4A0BB947C181E9CA27CC14A35BD1BD096875B45873
+8CA244F88C28728B74E25CB8C4FC1095A56CA75E4569AD3082EF194ADD11350DB3B74B96761D4538
+596FF7243B1E1B724716A144106E080D42036444FD472998460CE9ABBD05B42AF9389AC452BDBBA3
+A13A96890025789F16B9D92251FD3B3BEB2C61EDDB370A20456E3BFE5F4039E2557C451C524F8087
+015BAF3FF05F51869FB97512968BDB2B49589C1C7AF1E085250A47657465F480B7023E24C76731AC
+0EAB6704123D77977D3A2C4C56B691346EBE589C619C04515D34F81FC6A17527D5D8319013C5D4FF
+27CC3925E24C99231AC7FB9EAF0BBA482D3B75807AC85D03CD09DE5D9AE0B07B7A813F0449786500
+0AE8A7E00080300F0AB8C399057EDDBA273DD2E1B2A0DCEFAD3B332E6D4AC1FFAD846167DFD70E03
+46DAF84AF292D4F424256ED5AC4E104F80697050D50844A708EAC9E7F7784FD01646F3BD0C595CA5
+1EE6BD607D254E78ADDC5E15C3B6AC4940EC865A5C23105B6BE09EA09F2C05D6D76960A843B81EE4
+33977FAAC3CBDA85CDD2F4DB7C28293A77825635992AF8F3B38B4480D9A139B1662345A8ABE1634A
+77496C3F57597D2985E9E54717AB2E99CA35789441BCDDEDE9A9E2106B401D9684ADBEFE40D607F0
+75C179E9CC03E59E65430DB70B441D43DF03F2AA6FF06F224B6E455B01C64FB89EEC9103E48453A9
+749B4D602808C7E408A8903091D85E06AAF635D0D529C3CDD1B8479AC0F4208C284BB678A547F2BD
+77BB17C86D4560434F7AD1937760A6AA55B614CFA9FF8C9C96561AE6C8F2121C4E20237428BC51DF
+2099B6C49E3EFA18E6D439E6E6981E746EBB1DC461259D8EA0F8099C47CCA27B2D982B72C9A07CF2
+1B3C05D6E26E6E286E348B8944078E24809F9C5F3D014B4CBA02533F5621BFBA1F0EDB776C634746
+703C9F73BA89B1960A496420C68F54E5B901A6D733D7ACC79F275FFFB253F389AA480084468BB34D
+A1E797E43B7F6E8CAF5E8C93069A3A2730E57EC39B677BB73E3F07C2055599F7062E53B37A5F0099
+907D2ED87FF7A82C95FBAEB888033BDFD67BA3A6031A4CDC56CB1E4CF5B06B46E16D988BECCEFACB
+9E1C037023D7BF5CCF5D65AA66A17AB361BE7981F132A578F3ABFB97960A6034F052D9D5AFDC0679
+782EC90F240F943A5F9A3D969ED7399254FF67D89DF668F7C56FCEA1FFDCF20481474AC8495D3AF4
+B6D7EE093E369C057F0B70858220693B398ACF8E8143558132E4391405E30A73937C53402E459F4A
+A3539CF7A99A3F51C0307D045DF8B77757E92EA2F51BF0BB4F77D3904DD355665870C2B59F1ED7F8
+4FC71FDD7F0B6C5D3182DB77827CA6A2060D2B8C83C4EA4A432EF43A4D0A952CC6CBBE52A9F0CD66
+1A538973DE41FFE9C5CF55F2506B9EFEE51FBAE5E63BDCF5528499A47C031163C88D3022606784DE
+2F46A9C9235AEE3D4F71D4959B0CFDC5B7E78C8C0A8F9DC99440C2263DBACB343C5C648577F5610B
+50EAB1CF7FD02419EF3941C7CA0B0E64EBAD4B2CB05A0793DBC38F1946D44767BD287F5E9779C611
+CA0DAAA1E7393DBE0683C8D3455CDFEBC0E64B54B737E298DDA605227C0C4BBA87AA3EC7FA6EBAEC
+39E6EF2537D5974391D31739D9FC42983D81AEE44711C823F35F8E2321AC74943871739D2DBE9748
+FE68592263E7713F27E0D49B9B5CB7A4E55DE54E6B800D15856450FFD3AE5F287B12AE4F438B20AE
+9E27E6CAA00F3EAEADBE08432684FDF9931E925544A680182602A3C1997DE5D0630BD5A010535E66
+E1C123013D23966B3545C7431C39B97295BFA4099D14461004C42C85095EEACB9B47C593BC6DB863
+533A8619BAE09095DE8ECA432D4DDD49AA600D277E75DC3F5C6631E2A05382CB007825FADB77438D
+CFA78E252D79B6A196D5164C2FEB85D75ECA25FF80B1D97FE10E87960CA0FC47C41D3A213BF141B4
+8BC3AAA93FA86245064668394665BFD52D12C3BE4CE39EFD8111754398A944C3FD1AFA98EC337BAA
+AF899D35E804CF416AD7FE45FFF13FC6354007501043F98FE8428DE8013901BA6A28711A2CA85A27
+0BB135B72F1D5026E8217581860729E94F2F1878A0E96C59E9F62714FB5F8F25003DFC7347E99007
+8A9A331CB3A6A535BC61866F02513DEB982C4A13ADBFBAC3FF70A7335F40D5489E48E5EDEDEF1619
+1973D932479C62183B0E25EE8C4F76D4F1AE45DAEA4A12AEDD9EF81D248E8D19F8C8A5BECDD1EA1E
+98783EB7A38149170851B1942C96C53DE06DEF80913BFC04E539EC67C110498D15B78268853E5C72
+F485F8A27B768569E54241F6115875E2973292CF48FF91D45EBED627AE9F0766D22201B20AFDD40E
+5B17CF337F2999E0BD15B86E46EB3C18FC12B7DCADCF9DD50C6C7E3F37E615A892DB3F57E250A072
+A49F7277DD6A2C8042698233D35A699B17ECA5DBDA6D250ED4A16FCC893BF0DC2E33FB1EBD7DEDEA
+3C1C39603C8B7E1A5A833A8FCDD5570BD088749BB232615366687962C7E56ED089CD7B092505CAFA
+5A80F503C4CF337F07ADF0D106937E25670839D491F7BFF7A523DB609D126328C16113ECBCBF9C40
+04904427A108618AE5D4ED809F8CCAF72251104C94EC5BEE21F91B179D31DBA79CEEE5EC7FF698EB
+84AB1D2D1A624F58B3622A78844CE51498B2CEF38EAFE259D22C7BA61104651A862008BC1DDDA58C
+C45F663EB26428DAA85E7785363A69D2790996EF5D9621D53042F42F794962FEA46E46F37B8AD1FB
+76FC8D5CF2146843F8CC625139C75FB42DDA71A752BAC48F294E4C0C8289FC46DA5EFD9C91BDA6D0
+27518B7E81E8B21F755A9615627D5812ACA674D1527A1185EED4E3C628196E7D0759B1CAE6B9B7E9
+01E9599A65230F1EE469CD33B9BD9C104C44E3C1AB966C9678BD0AD78111A4E0F2D07A01A038CEDE
+7036D0534D684A1562A17AD64A00F279200C0371B1CBA61747671D2A21D3F9646CA290F6B82418A9
+6FA177C6278277504B7FBA936325F5FA124AB018A15DC18D2C5E8F93CDEEA52BEEDB78A57828D81A
+3E6C38B9FAF3DC4EB7273ECE3EA4482A1C6242A335862C2C3717F9C9ED95F77B140C4E1569B2192F
+C7DCF702D0BC9A50428EC406F8BD0CAF886B4D979320D3E429816D88F7C7146D960AC12E70F2CB7A
+9F4E3E366665AB3F1B4B6440F55EEA26DC9EE0096BB7763731740A537766490C8C174723BF0EB40C
+53701AAD12B21D436ADCE22203C1053A9DC4E9F17AE617888C4B4E6F3A720E4E6366BA628221A387
+D8AB15E04AD69387C310D3528BD2FAA5B22BFF3FA494F5FBFAC4F771C9C7402B95580C5AC4BB3AF6
+92A70CB2C851FA5CF1173EEC3EC29B5A05A0B728BBBB51D3B7AD8B0AF17A1563E82FAFD93F8B7118
+1FB7AFE352874F4EC6D334AB6747519AB8E847B7BCED33EB5458A828E074E74BA621BDCD03FEA604
+7F7B6ABDA01FC7514BA1AFF0D4D0C0CB8F4E42D5A87E395D9ACDD02CCC220C157153422018725846
+009A3ACD8C8CDDB66BC6836B4026FD9F526AA275D06C813179E5924F26A25094E7BDA8BD26AFC4CE
+B41D8964D4FC4AF1DFB0595BC5D6714C32F15DC7194E9A3A73013C45D8FA55CC0550A12D9AAE8E9F
+F199FA28EFC2426D8D1DEFB93A65717AF3EA8E2D5B4AA8EF0EF38E9600F7D4E7D9F1D67A2E63ECE4
+789FA74B159BFE2F91C19B0378BA52E93DF12830D99553B6618645E26126842AB70262D96E35E5E7
+50ECA0CE3458B3E51BEE2F21191136DFDBCA39BDC07939E521E4F492F392DEBD029C1EA237BD89AF
+76BC89F618D530160AB16269FA6B693CF14BDC4EC7C630025703C5337F61458FA09104EB15C7CB20
+AA4C9BDB7CEF3A09F25BC7F3149951A7CD75372993B80CD2112F7674CEFD6AFA764AA3486730D2C1
+897A264D82A91709FEC4A21E30D812F558451804EE6F3DEE2C4C437846BCBDA07C5B6CBA1D94AF02
+9163B7383CAC6E088AB1DC14ED3743EE77E26EA7AD3119A76C0B5F925C4DE305CD7BB3A09A453947
+5B9BD79BE28FC462D8718CE05F9D94CAF3387BA55E6E447BF81A9EDDD3A34E17BE66BC52B0C0BB6F
+86F6F008829173816D205182ED2ECED319864A796AB65D4E3950288BADA94FA32B6F453AFDFC6C39
+A4FCFE60353A64627E2057D4B379D3240012B3BB0ED0C7876CB83C1BA5EFB6E2A03F340C2B576731
+F848F762A7E1CCAF267EE06D621BC33FC245D0E1547ADC12CC0EB58B26BABDB8EAE9CBFBAB93836F
+FF22BDA1831DD01B7346AD377AA298D84628BF1C07433284B0A90FC89F5AEB2651BA2CEA405D4F52
+DDC0E74B871D43F71EB4ACE0D2B401F9348EAC3A2EF0AD295036BF6CF6F870D58E00B619D50EA7DD
+77BC28DEF91D805CD527DCBCFDC16C042BF9B874E3B1567EBA4C1E70744B9E7E5BD1FDA6A5FF6E10
+1613FBE58DC46CFAC1A65ADAF65E49757E9304E2AC9A91E0588600C709A61D4231730073A36D473F
+518A145E141D0A5A494441B9EA99AC23F60F54F8127B477E1CE698BB4129B4B1DFEEDF10D9E665C2
+47A62F112F5CA30B0AE5DBF3E495FF06EB28EB438CE8AAAD84D5F50FB56A3AF002C23BCF66ABC270
+7AC233FC0F2723DB99D2CFE7D3B3667732A531F5DC315CE74EDB9050BF75D29E6430F57CB6778B2A
+CBD57DFCEF896E6766C8FC5C9F9FBD701CD62CACF33EE0FC95E78DADD205B5F42CC63024624BAA0A
+B4DD447832B4E1DBA77BDFADD223989F8E958C8D759AAA37930664C6EFEC708116248A2A7AF3D656
+DDEAFD009B7F5333854608E67E5E588A857167ADF9225CF6C641F5E19C3E08678A281199EDDAC831
+B57223B1BEEADFDCBC8F6F25D32FCA2336C808162E8F381656E847FB6CB13969572425AA05AC830C
+33DE6E030F86A3A85D2A66A77F103C7042C97205526DC882EA9A00EB8BD5519847EB424C15F808A9
+1652A6CC89B66A5731126DEBADE123C63D88A2E550FACDEB3886FF98646000C64B3A91078012CA30
+904B71737CEF6BECABD43DD702880538F5A70085E6CC6015D2163681067C3D513A8C66032C34A0FE
+17A58AD4BC97CA69BF41F11D5E910FDFE9729652D3EA21F8DD8CC19160A8FC77573B1E9CEF4E790A
+79D8AD6723B6804E9616466C935303E063DEE29CAA6C3BAEBF278B818C2EC2F13ED645AB452397BF
+00DB8B26E115026E256746CD0C78A959364FDE6DEDDCD0F441A61A1EBA32C7BC172BB09512148D1E
+BAC9E791B7D51B71CAD2DC9B83B2F99B3726607D9CBE58B499A13753CE87FCDCE21C0AD0528ED0EF
+B9B2C927F57C78C626248AA2B835A0791244C5896686A66173EC9F802C4C633A42B086334D2A4878
+0E53D00809247BE64E529F96AD2F8B3922A6097D414DDE1EC76F9552F9B8D58B8E34F359AD792B2B
+E50C26DB05035E7497162E7C49C38D3CD9B98D620AA67492BE5AFCA3A81A7080185C7F0B5105223F
+1FA77805502A2E8C5FEEA27699858D84A95842C5F2FB68686D59FE24091FCDDE139B6463BC6C7B1E
+0E90D20A83651AF00C85797BB9F53ECEC1675C7EE636D0D9E77DBD8F89670F855EE4D4800FF3F695
+0EFF09BBF8A0DAF6B8242840CFA5BA73BEB95115F4A78BCC02D85ECCE0C0F2EF6F328AD1DD6CC049
+5A3315B414A4D61DA50DA46D7ACCEFF6EE56451805D26B0359AF193531F95F6589CEAD6FA041AF15
+3067F88A0A2FECD135C56682DB2B45A71D1FA737C064EE9A4F404BB72A70B3AF0330359393247EC7
+81512482579865240A23CD8479F21C2C44A119EBC4E81B308DD8AA86E60C3DD8ADA50E0DFE8308EB
+1A7F201EDE8DCFDA405AEFB47E0E6CA7DDB376DCB21D37F7ACC4D3E9F26B03A8DE0E8940CA3A9E75
+963A389DF8038D2C486072F61C0CEAF500753C7A6352B1CD0338D9212B42A4D3DA23D5BDF44C27C9
+4B88A415A3242FFE2E1B332477A21D2B9CE075EE479C6E657A4D8874A8C53964229310E01ED4F3C6
+86FEF5258EDF3B464DD6FFD7F1CAF473BBE722D60FB14AB4918E93878A8AE4773930B8CEE110F476
+7F42A52D9304C55BE12846C911A10AB9B2E036BF9DFD597F5348D42233315FA80D0F563C388BC253
+2103F05E90DBF1923F229F980A2F4585C7A373511372D07DCBACA583099EA972C03E5AA67E663882
+6DB134564DB993CEEB6E7A6659C7C5C05C310267D5F8A24EEC2D5CC3E3F3C808E6D6068D1A57646B
+37FABD98ECB7BAF99E7D9AC4414A491A73CA34C52F394352F6B5A15F0FC4D88622DAC694699C2464
+84ADAC3B1D366AFEDE2A2CD2042C90516A666A19A91C80248B11224BEDDF1A320E230739E755D098
+B6A67315535F4C187CFA67ED817A035056353FC859BF286317996FFFB478A2248B908FF12ABDE705
+402224A3EE5F463DD3D243875C84E02DB968ECA1CC52C75171EA50D6A88CA91327A7AA5795019F36
+C0A19C093A1C9D3723C7568F9D41F2E4FFB712FD47F897703D7A620B586B81936C84AAED61D84332
+B3BEBC4F95B796B93EF7A1F565C494F8A65EDB21E2EE18DC025522EF8E599887CA2836069CDDD889
+88E5862977B7472584303198CCE97EF9F9E1446D1F1F5ED1CFC666A8A0C3A03E1792EFB60A9B4065
+49E0DEDF6ACCDBD98742568B4735A747D8E5DE21E630125AE0C691D054E42199C15B1F80CAFA6E7B
+B2005F374A9A5F9900ABB7409CCD50C3AFCCAB1214E6A856F7C7EBA89BC3291801E1343DA9DAD2C6
+ED075C8ECA1423B43E587AEC67E6145272814B3F191B3C285639F9E2D6E148A02DC2CBC0E054D629
+5CD05DBAC1950400A9189316F0265B86A732D302C5BEE8ED233768F237C62600CBAAFF3A110D5EFB
+6CC7CA3B92D965CA7C5E8D3E64ECF239FE2507FC797FDBE54C1112B28D4DA44C60AB09D994C5BA78
+D663A2591934CC052BC70CD1DCA3325C66C9CB982E2039F5DB70C848D3DCEF655B1C2CD0CEC8865F
+E8E1C0A267BE4F707ECE6F5A3DFCA3CC1EDF92C760439F51AA69A4C1801E96CA4D6EA4AD980258F3
+D15C893913ABCE09101984C61B91D603053E49A97CB82FBA707DAE8AF1D579FD69C8481CB7B712CB
+CDDB4D287BE995E32C02B399602A08B9DD849039B5673F1930BEC7BF366EB082D2CA5DB2385C8CC4
+5BE3FC0E31820191A814EBA7C4F23B1938E6C4D800732787CD2CB97F762DFC85D4B798809B5F2254
+D826CA42B32695428D120298B44CF38494E56240B75DF1E41E46E53C44DC505452256DFEC819408D
+605FF14D6C1F3F152F2FEA96EA0AB3B472D8704E06BE9F8C3E8395CAADD06D6DA033E81ADE5DC3B8
+3DAFF743C6E9E48716003D358DF63CD7FD3E2F727D1F2D0C29962F76D5C95ED44B6F08D052025A66
+5785F264A3D5F5593677B630E628B5EA81FB37CFFD7A30B7FAD226B6FDC82B0878AF4C0EC4F4243A
+807B9839EA62BCBDF7C2E9B30A623876E632E084EBF4A21EDA04FC88A1C07021D0C72EC3E969D449
+FEB08E5826EC20E55B21EA71EA59F6E3B0710B0DDAB3261B4A2029ECAB68C19ADD5174E55D5E984A
+4E5F38F592A302FEE6ECE732DDE841A28672C620CC5D687455A5C06FA9FE688394A04F96312ED025
+B7AA6FBCE2925F3AE559CC1886BEECDB70822E2E5CA3F732A87404B1536AAC469989E9610CFA440A
+CE43875A70CA51F36CB6F629D9424C1E35A88F92D5DA3CD8CBAE6E8425A36968E21F4F30349749E0
+205BFF8D552837D6FC39532525370BBAC833F75F1854C93FC533A4AA53ADF7008173A70D94A4EBF5
+38EA9E62BCDA7C20E0A073BEE2EFAC34D2EF1D03BABD5147659E50B557045B2EB89DB303749B04D3
+F54B43FED612FCC68206E001A7AFE90230D9C12F74A32C7EDB5D0241DC3A5D51481FD7C8FAE08FEE
+263FBCED7C7D911B3A303C835AF5FADFD218F61A9D6DE80485ABCA88200047B094441F7767B97A24
+E8C612590FA2407BAB1E8B56C71914EEF2355DD97CFAFCC192BC06FCE063D3D9D1A629AADC75E3BF
+207234C208E7E30663EDD691043065C9CBC473D97C6D4DD3DFF59D6A9ABCDD4412C3128F603160AA
+D8F81C6E7A4DCAF35F3A99B4EA10A34375B477C2BF846521A7EABD4D28078E9340452A198F3F5ACC
+3DB7E3908939FF6E3709C6A3FD9889439A4AE3E10B618CC92E14B68429A3AD2C80940A1079452EC2
+66F254657BE7D79A2A24084AF73F6DF71FBCD32BF6913A3FAB25F977787F7BB0C3A3E8BAB38D7A2D
+B0B4826950643DD1E03BD7DD1FB149A33862A89226B7CB454DAF613128C2075470E42E70A9444A8E
+6ECA526345AB48E6F5160BA23B5BDDFDA6049EC44ED1461C7E0DD514B16E2FB285F72039DE3C7982
+EFD40D7F6C8E8F4CF35AC71B467BFC578002E8D2239A2FD2C4BCCDD8AF3D7DB1F4AE7F2D2E0811DF
+9D0155BA6EDE50B5F052F14F6AB884FFF244D8806C07EBCB49ED22D85DF696995991A954AA97A1EC
+D86ACD76E061B7541E87997FEF0657A826BD88EF3A4A5920462C6595E7A156F453291CA044CED810
+860C3B0149BCE73BECA713040664AD0591304106129600AF71317B0D2907839CEAC99515D357E980
+B1937B6E1200AACADA205421001F1B2F91753E80D2263C56AA164A74701A8D5FD28E46480B0DD963
+A683A1F355D7FB4463C7347C94EA5E2CA40B60B56297CB22D972C5BB10E56715A955605256C1541D
+9F3BC5768A6F355CD3B863F0FA1A781EDB49368F51B29481CBB41D4AEB07AF9DBE8F52C5D0FF75F7
+FB6431D37D6AED84D78C778871CB0F715B4F07580F23B586C969C81B471FF6A6C7276F7E141E02A8
+584D4B9AB00E7BD643D2C3FAAA299B1F1E25048461952EA42D4882768A70DE46B213A287F8D31AC4
+6D5436F22A796C05D1FE50A9BC2A928066627A0D87DD57A3AD91DB446404B41557D1457873482005
+EA20916BBE46C613F456C849D46BA79D20627B446B2F49E3FA309AE14F8C420CFD94922CBC0FB9D3
+5A0F7DBEF577F1849A1A80E0011DA8AC082A8C6F61658E65AD177ABDF23EE17C8CF0D26B9FA3A6E9
+4837EB9E930336889767A8D7EA3CE980A8EA95528B004957BE6067CD9BD8E02A0F23CC1762CCA656
+D33412FF45E917FD4A03EB6E8C1F43FDB0A8965A33B4FD26BC24A20B304CA817E88495BA9B361A3E
+933717FFB0271F7F70C5D3CBA1E86D0F51BF3ABA194DAF32C35C796627D00C7B2271ACE2463E37E9
+7B3C826CF3DB60028F240F9452CBE08F7EBCC5FDB1BCBB3C327A9F450B9E5671916101D6E3E5E458
+CA31F04D12F592F83BADA2C3683D3886AA3B403963AB5DBE220FEC00037A745839F67A3635DFD3BF
+F08F367482962DED88ECF6322852D643A54D5D303EB04BFDDEE9BBA1EBCCBA7C653B3A613A8E719A
+DEBE3CE1BD7E754E5F4977E863E3C2D388A65227B451D4F3A4F94E06513CBA4AC1F2F511613FF035
+611684CCC461599000E546E4D972CA6960E095A526E4735A23421A4C9B597ECE08AFA2753592BD16
+DED93255A1E33DEECE3C5EB77B94670E8137F2A4A4B98AC193258E7DEA5DB8408A806188F2D1DDC4
+40CCF0E9A6E2F0C78FDBD7B68DD4939D2458C1965BF8BED4564B32462FFF3EC892C03B11D3EA813F
+AB4CFBE8D3016329C5B7E3DFED0F08284D44AA0B7A2F6BC96EA4503E8EF52A64C22BED6B452581AE
+8FF8917D53976471941A9116A2D878FB2541B561767ABD4E31CCD8A590CA03494C62AFFD64EA0A1B
+C779173DAD84999C7A8D844EB1259DE7BB5B25CD023537A474A524EBE4660B22568949E624D8FEA0
+AD37F4CE1EC75955EEFA49C6BF1803BE87E9C9865FF3F6B8525B8C15FE8835CA153D27E6C0FF0CA5
+1029A7A9185D25F0F14D86FC797DCC1F99EE97E2054B9C2A2E06FDBEB8DEF6CDD368BF23A858D9F8
+C1DEFDCEAF1B4A8DE5EAFC604CECCF0D285BE00AA912EAB66EFF4D37AD2EFE34853BBFD87CE09B18
+749B489943EECAE7887B006FB827D10191DAD18466CD1F86505879310A8B171F902EA0C26A388E13
+B53C700272CEE2BFB47ACB58247C13449C6BB9D01232C32517358F1A3DE064D43C18F8827D53789C
+CF3CE2EBE78949A6ABFA1A6B8414CE360A5E22AFB7D1DCE6F5A06182C3B984B4F9BB1A905A9D5A14
+83750A1DE0A857CD5C06945EB7D4A2A6BF1237F32A154FDC06D51A703D44FE052FD3C53E9E8F417B
+35D1C851F9203A8997521529F21AD8498F96930AA77EBAF82EE02A57BC77C792D9F220294B45F48E
+A8FD94E01CD25645D36D168923562F3FDC93CB79DD4760DA0C103C2675722D7A1B79FCB4245ED12F
+A0DB52492C9CCE58B333CFEE822812F7DCA68E802C451B5CFAEBAC608B950386B6C58239D1C62D62
+4DD5D15782FC552222CCA06DDF387B373E32C3C2864C63C768350C37283760F3515A5B0AFD66C48A
+B522EB3E808C061F5CD6BD96CD18C9839D30508E7D4EDB88E8F11E31E10919B16B7971F06D7877A0
+58D8A4944C84FC6CAEDF3341B48B6E0D3C7B85D710E0C35F5B5053CF4B4798B3778CC28B2DC7AE0D
+F3A49F9F3BCD8E95D746C35C3F47D68B8AA35D97AA08E711B5FBE70D1A623C82541EBDC51A827D0A
+69E6C049087AD26F256EB7577F58CCFFBCCBA5A95D093DC29464C9A38DE95BC6B1853963B2DEB0B5
+7AD1248D6F1625E115EEB9510B5772AAE4E3C866657DB0B3BF0E0AC345E116F8D4976B770876FFE3
+748C36165522991F46A36F193DD1A1C94713673C7E4C81582391B636C72DE94CE6254374F99B623E
+5686C13D8A8322E83E11BB0B0A896C6A8C2C4F756C5385CD7017F26D23F7C3EE97372C868C8C9155
+81723BB6B76B4C3CE8998E4FA6CA40B633DFDAA59BA902A4952DA90EC4FC3CF0F2676ACFA7F76F78
+236FA2DE10FD3545357215246BB7E527F277C28B353CC6D79DCEF21BCC8F77603CDD58A2CCDDBE3A
+9802F941CED8E035313875319548C41992A2BE939A17CC109426E33825AE59BCD17CB19F50D972FF
+CBE7D9B4B0BB095303D9DC9D406696C2508D6CE99E11CF00F6461147E97449ED5F486D480A86D3A7
+ACECB7E9A945984724EFC21C5079B1FD03ED803C2DEAFCE3327D2D7827715FD65D9506216C88B0FA
+26935E95C64114A51919D419038B1A7E9C1E829FBFB53275093752DF19891A97F3CBF7719C1FD6CB
+17019A6D2D25360ECA804C4B35172662CC4769D2B785C6C87E5A4ECCE31704E59F71263B7C3CAEC8
+ACB4C7426EC25F11A0042323EE6C3EEB04284DBAE2C770BC419DCE79BD4560AEA41571C3B595F525
+60191DC7A8FBF63D413A77A0905E517441B16C2B501EA2F9E99CC38D052679F288FDF1894542E3A6
+6989A0090185EB2E75134BFA3D9147C3DB8A621D9D35E37786853779E157B47F71626D6B3E633005
+9159C17596C1B87FE2B4FF47ED9D78FA4C2160077276C8B58CEF5DC030B4A5D83CF257096C047FE6
+4DE307C598B815058E72D5F57DF5C369E664E137DE29349E2F9DCD8C9F4EBA6E765B6327D7A20DFC
+B20711273FD8091CBA605C4C494248076F7E03DF65A6A50164980BBBB708741E5BF6056E6F996DC0
+7FFF408C5B8EAB8DCEC315E92873228C805D4440A6470E3EE3983758DD211C9CECDBFAA4C9300CBA
+00608A4B2404A3C7AF017A3B7E67F39F0B51ACF950D3E75CC7BC2B8D3480202FA958E8EE0B240501
+5232EE0D264C7CA02C18CA45CB3C2DE322D3EB7F00F9455DB6C5B1F4E59C3E95520EC36D7D903CBB
+625D70B54BF6F8255E412604BBB29FEE026CC660577F91DB1DB4A613EEEFB20CF7AE3CD89D565AC8
+38416B01B5DE4FFA5550D17FB51FBBEBE21CF1D56038863EE931B90DEC2E211ED42BA92EC244D4CE
+2C4EC5CA87A026992772DC2AF754FC982B94F36EA7B7BF75E0ECE90CBB2A6AA1A012E8898BD679C2
+3CB3827C35D5D02F0569C7AA82615D4AA67518ECF668D3B57D6EF1A8013424AC2268BA0D9A74D588
+79EDCF6382A89D397864940303EAEC45A38304BA8B1CB198967AE23EB81054BE74B16909A405E8A7
+799CEE3C270FE2A6DC50BD7370B6B2C8FDB9A87D88D5D40348D3984E39C693B6F4486D994778607A
+80A3122872DD65E40492107C71C3CF708A9717E9EEFAFBDDC239C53AA9645B711038E59C8B861B37
+411AB2039BEDF9CFD00F08D9C5D76154427FF5DD39878CECC5D7BFB3F1F035087185C0981F3C2139
+BE84872FFAD3408531C4EA9387B89F5E3EC779E8850D50992DFDCF9132BC551E985943B07618AC10
+D1150451F0844C0DC41D6E17EB508DC8689EC726400D5A7F6FEB3CC7BCE05F09228B7CB2C5393664
+D8DD9A4B96B1020EF25D70AA2D91CAE93AFB5F2BF0AA18CA5C599FA1A708EF35BF8F7FFEC9AFC1F2
+42870D028B2B1459063B493943EF1283829783E1010242E5CF4DA39D93D506F3892936E7D6CF1124
+70A521D397438733D053944CFF12D6FFAE8246F20618684F263715AA98E15D72A526383E05C23214
+B78338E5B476F0981D90056E6E5D0DB66B1DF2298E597B2ABE1D817E18BEB056E65EDB4234342D96
+00470B1420C9210419D834E431B82F58608C87AC361A02D0F1FE4B470A3D71E0D21BB87E1023D428
+E23D596CB9E1A2184403A16E36E644BCCF9BBDE27290485057E62827283E7380AF786BF395B3961B
+A5EA469C315763FA59E0F176EF81985F38B882DE56A74D128E256D1B89939728E55A92ABA21A6B78
+44FAC1BA7BBDD8B34A18194A2984B000380FE9F672E83EFDBF276FE797A325815B0F25CC95C97A9D
+ACF56D583486305D7C9E51A7E337D14E3B900333EB38FD93A99587DA2341B10C059C71CE080FE753
+3C0F059FA40E560AF9C4A41A4BE6FB45846FF8F78165E10B4AD40F264BCF5596A1E8EF8CB6EA4B1A
+3A5C69059AB1563843679ECB2511A90E8898F54295649CB73D277760D8D04ABACC7BCC6E777A0530
+E2067CCBC08673F9C8C178F9D672AC8A15E5367F0C5651B53E75E0CFA57C931746AE1A679C246D7C
+9417F1CD89DDDBD1173C2F880B7B3847CBCCEBF99F7122E832D7C9BAFE2B54CBAA1ED48158DE3F36
+238B76B0E67644A28AEA996DDC006F6AC0242E4B667639E7523CBC90A0561193C1AF34481C2EF402
+EE43A82E1EBF4E3D601BB36B2D95CD93550D61CEE7A94E72F6D30C32C8F91A61E964B1F66ACFC398
+7F95D4028F116E9A9A8474AA29C1C1A984BE0E393BDC41DCEF6A6F1018DB60D52024899D8EB5D55D
+324D73F39BFA47377B9E15B3B06A7585589FCF52A54684173E5183367E7B0952DC4BC2767C4C6247
+B1D6103E52BC7B7EA6298F454C5D97AC575F19C10ACDFF4E10C7D3755CFAB4200CAC545269FF1D8D
+B0D607C7AD47F40DDF257AB4E7D0750577003C13E4941960C3DD7B0774DDAC18E8ABAF8F53E03CBE
+F6D57B44F24CF821014C064278FD51B3427593D17694B4ABCE81F49CBB984C5878CDF0C38D1ED7FD
+99B0B9A3BD8D8FF6219588B3B8FA59D0CDD1D9B2F65122AB45E48F1757467B9204926140E3C350C5
+A927A2E700173053EC35D3F1DA2D7258714C97FAA857F0898917BD94625C6D1E2D77138EFCAAAF51
+7B17FE187A2212C24A881A2C6A647DEF6376ED80AE4175C5EE80921F001995B44E49F0D33DD9075A
+CF33BB03671C0BCC34AD5784AD1CDFED3A6D9BA103B3DDC1CC2DE74DBB576A0277715275218CD19C
+A8899209125266D8BF1286F881DCC2C383749D1E768D670F4099F7DE959EDFE852583183C9111601
+2881A56A24AAF020EA45CD5F39660DEBCE30AC1C7B8CFC60387B1B0C3E361BE612FDFA9F01B7E4B4
+A18839A2C7E0E393EBC5AD9A8A4EBC316A740C1C295D9EF5F4DFFA0667F9582C0BB837B142C4CFC6
+B1798E9476D0631111033B8BA75A10FDC800E2AB1E0E829632F869CFE4737BE9E2800759EE0831DC
+7D1195EAF80555771981DD6DC6606812D92CB8EF86447F5F6C6F626D0E265C67E52A6319189EE349
+D48E49DFE6A9E98F76C414A1E3217AE0A215A17E54AA498F4ECDC50242ACC7E2322F63BB2FF2189D
+057E7354E32A3ED1803116176B9B9D0129930F919E2FEC280B2C8924E49E7BB75768A2EE1DA8ADBE
+D4E3589906DF1B923AEF84C1BD327438B731012E69BB0D43A1842CB88BB54EA4516477F704CFEB28
+6E3EA483445AD4D74586FCF32E96D366901084365F693A53C5FB532FBFE7BC0CADC404C4985042D6
+8DBB90A6DCDA3531EE324D558A214F935CD9FCC9A0CEBE9B5FB0323F4B3820529599EF48EE068B5A
+CE85004FEA2984F0A86F5AC9D56163BBFE1142B774148F1EB0A4DC89C3349052533A7DE66729DB24
+41B82F8F7360111DACF69293C9B281A0534F3E9E9224A75C49A832F28B2E497262475507B6DDFA9F
+01CA0A6696E3F5AC7EA68595EBA0C2EB8A47813FF936D84AC1B23ECA7AA2862B793CCBB0DF9FDD49
+31BEF354CEC12FBF478559FEC29F81ADF4452E83963E56541D31F3691C93A50F0BBA5E9552C4F2A2
+3A6E53060729854A3DD71CC4308B91957DB19E66AAA18FA67055A950F1C2CFF78A03BC1A588CF624
+696068068719AFB1001C4581EE072113882D9052B21E355D401ED8CD24D067B99E616BDA5A0A5A93
+36FC499632B79FF2FD0DEFB096EF46B75E2D4E0F48DAEA239719FEC4D9A29818F5875FC5041A9EDB
+D26CAF0ACE14CC80BA49BBA59E918EB3D8F1E541AA16026585A2F72DF7D83541816DE46981FB3EFD
+0C30E458CFAD04C79421AB7C4925E23AEA07F9F018431C790002596D26BD9663B51B699DF53E4882
+CBC34EDE88EB55045B889B6062E35FD1E018BCE785157B85EC3B9CA6C85D4B16238275385B8285DB
+012D8FB7C9F5B946A41D7A0FB878FF72C39683144D8A007CFF631B43748F2D5FC690300F9BC0C837
+006B92ECEBE0605E8C3A4A400E18AE8997D1B45FEE10068E247C647CF82C6DFBE5E881D511FFA687
+B7AEB78546BFD07D5F7EC242DCEF4930D8AAAD8C6152B6642AAC325963FD147F236BB850A9966573
+9D06CDBD7CA79A527DCF461E33F22BC9C5DB00DA2BD3DDDD8C99D99793BC98282AA8872FF96C3942
+85D82D9419EB78B6AE37A5F519397700F75D624A09BD255B576E955A323E784E8FC31131F003B0E3
+024A4F58FEF2A6C043796201FC425482E1155E229D1B2D43EF7B0D22322B22EF5C9A1BE026A1C3D3
+75EDAFF99597E1E5477952A4E8D2ACF5D014BC00DC2A272FA62B6983E27D228881E2EF2B8B95A681
+CBE90C5FDE16331C85222FE2A16F0A3C3000A63E2E21666C0C119F8AF89A543D37977069A5ACF155
+6324F05204CE8CAD50FF4FB630D9CBBFC324DEDA584AA56A99D3A76FF55BDC2C2EA3A021361CCD4A
+83C7A5E2768D210FA6DE889FD48A39D679C94EC3C99A8D33FF11377DA7F6F1B71A2A05B302ECDE95
+4F26773F39AC881542F0D0969C3995C3519A8EF70B4220D86BF01BEECC6462855E7B686E1AFF1CA9
+1FB8FD8B4A69E10EE0C2AD94ADD44449506F9B6EF43641F2026EFF6E605C670560C2B74706FB949A
+A7E8CC6A2D0D6207E457E7FD87EC1B9092DC68B9143947CC8ED14AFDDCBF8FDDA228A76847F96802
+E561F67CEEFDE45AE587673983FC04C96744DBAA83F2DC838D633943C75DCB9E6410474EB27B348F
+26E505F0AB90878940E846C5E9F3C5FE8C3558C3236B1B88C405716949B8506841CABE1717474BB7
+C30DB91CDEE33B0F844811762FAEC535BDCF84C1C747CEF9B1FA61D2AFB5A81335BC42C06A94D7D5
+9B7EDE55BCF6F9867AEE107555CDD084B7684C2C87087475A39A9DA6347BE281CE5635A4D07865BA
+98CE26C1465B1AB0343F49FF37B4D0CA9F3BB693D78DC3B21925CB996A038DCC172527FE57C07460
+EF39C07D4396E7FA970D9F22ABD21A9C794B64AD96762C7428F59A8757C36D6C4FFB23216195A04C
+2A2C2E7B10EF7193931544D782FEE4B91E01119C5553BBC6252270A8D8C56DD62D448F5AD8DC69CC
+B45E1F17F0AA1E445129DD00F000005B23D38DE93A3BE55A4C041947F36B4E4536E307D0180553F9
+2E46B743881CB5D5386C48C7D5F84C2BCD06B9C501F78C7EE61FA23516791FCF4DB278AF688A2E60
+10A56692AD92008497487EDFE4BD5FA083FA544138B20D6940020887E35D46E093B71F7A04A67460
+DC8116B4D4839625D7CA6959D6831CD93F81AC4EA2709036DD738364FDE71113BF22EBF13DFE1642
+E564701E6F0FFE7511EDF03FE448C2B28C64FB7D54B94CA576E481FA56B2B18AF10C71F699B6BFD4
+7459CDE1869D0FD306BF489A6F42E5B2F05CCF55BB6B9526973D19CB134CA7F13F1DB3716F8CC217
+73A832568C16250B5CDB16DF24BF81D49F5B37018BD310262EA7078107868AB0216CEC83CEFCAB1E
+9F2C665A31585CA04DC01879CAA79AAA5AB201B516F7052B01B16BEE5606098393B0E5D9F9E5E3F4
+EB20F63C958E796DF41CF28839F5C62A0431648745D7837B519F3AA36BC6C08EF040CCF53D9B6D8C
+0C7D1A84D707EC57A3C6AC9A62AB37251A01A5ED40FDEC6F5BE6E34C6A91D058319439778A2EE5D0
+363E2E1F33463C33327D05FFC0CBF08D5BC457C7230448972FB9B4D0D782BA7DBF10D3FFEF8BF523
+6EC16D4DD6D0D870D9D5EB5C64C9A46A4F583D4F831FEE74B0E5B33A09ABFD4444929BD8F638CD72
+EAB99CF2E9551DF427683964A592E49D186F285258C5D5F62196A98532421D73E3495F82695FEEC6
+E1952C562D546B28618FFAEEBEFF03A57F4D855021F85B0C7BC37FCC6DA9AECA099B646B99D41896
+09D3FF2D56422F8C37E97640293EC7C90E3380887836F4938FBF495CAC14FBA5648D89282D8D49D9
+1AF73ED36581139D8BD42551E263E830EA3C6EB381D85C42D74C50DB0CCAEC03F535ADE92128A016
+0E811C34748309AF7604919B66CD43EB5CA975302DCB6076FEB6BDD6FF55976FE990FB0CE9ABB11B
+195403FB26E3D6C6A0DE1C5BE79E171A61E21F79EE8DBE7A832519813EF6B33EA098C2C32ADEA219
+AB2AAC8B093F40000995539D1276D5F2EF84CCD099B71FE4269BDBDB6A8D59C86F7D2E3FBCCF8773
+D0FAE97640BC1AD43CB4B992BFADFB09DBD0CAAEB8CD9DA264187C4F97300E9A6C9DEED5525479E6
+05C65AE336CBBDF4E5D7F79AD098F977285E065579B748FEAA97F2A753E1F962FCAB68D72BAA8EE4
+FF6691C23E31BC0F3E981A96FB440404856AE1AB32A7205B17D411D8F21C8C93B704D07EC594422A
+BC368CDA2B1610CE6A973F4474E12B78B532666797F5755D269772C9F5400B3BFC6C58395D38527E
+2CCCF29B56123F7DCEF3BDE5DC1DFC5B0293BB125085B1D2D929BC3EE84F4FAD571A4991C3DEE03F
+2DB3A3097E52B1A7D5C73CCB6148EAC62E8E36DE9A71C57638C6E4D5D9DED18174E8C390E50B4A5B
+913C074EEAEBE390B214B3A68F02862B9A296DB4B409769649E51D738CBBDFB7702E15C73C2AFC6B
+C37CE15171F4E822CF20EFE55D9F061AA43E648989628FF79E65932390CBB15D8E621333B18B11C3
+BDF96F841D7434E01AD501FEA964A75B248A35CD9DF9A37E48A1E5A09C624B93CE44F0042FA00D7F
+9EE89B9F7AB785E9C718CF6E7228F743271C2C9BBA17E5208B920E44E765D99D86650EB454B0FAAA
+112753AA1BD3A24239E9C5FC47EEB1547AC9D23731B8DC48B9707830DAEC60C8D3790BBA1120F776
+4EFAC542CFFBCD5C05F9510B27B2534B704ECD36C8B041FD49A96881302FFF5B0163A2DD09C751D6
+D6AFEA9170A4F4C4AB8D46E62F763FE1BDA51DD1CE4A27E772F3A2869155F762FF26B7AA6FCFA4F1
+292E56F03AAB6322BF867E7710C34D43B5D85B45AA68014AD7879EED051B1933E491496E3E26D9AA
+8B80A07BF2B94F1077E84A9726F08199887D66DE7A307BF33C30DD9CF3DA188088C03B2BAD09A217
+6B110DB2C868B53DA9A66C85737BA66C93C58A259860E294AD0191E3A72C73F40B0BD98699AA08DA
+F03587B78F391F3A4313C58D9F29B53C70785637BD0C58310109C54091AB0A34CBB0C478613A7AC0
+FB8F0A8B4645AC966395D8BA775262CD291136AFFDDF01C1D83DD4EB3B59CCAD18057FE7D92A8CD4
+A58F22508D9FD7CF356571F701BBB23E749BDDCBF8A317FDA0AEFD952BB18545610FFAD3AC143D35
+1B8DB3F66293375E0E50235F0D0466932181D377EDD32A5F0FFA4E22B5A0CB4F343D9A7E4A342E9D
+09DFF6C697630CD3971802C277A5590B8CA94BDE6B38446C794D072BBCCB724D5BC208EEF1B018D7
+39373BB910D668882CAA779C2D686081DE6A2606417B54D7C20E0E7F722648D893E4EDBAE8F00D6A
+6DA3712F91AE860C756D1127D133AB828E9D80023B50B162C5A1C5CDF70CCB3FDD7EA060ED20838B
+E1E50C4094C9E79E1A0187CDF780CAF45A725964F004253E034C5BE46BBF89D94631F1A33BAA35B8
+4FA2A9D08481C6674126CD96ED05DCE48BDA069D902D6836D5DFBA701DC0F98A863E64F0E312145D
+8DC0B77F25B43AEC729A1243B45B08CA228DD6101CAA2AC5ADCC8EFF84A4CA3F254176C2CC711EE6
+C273835D0FD3528ECA2A976B88E51FE347FDB60F32370B66D338931D6581630ED586F349C638960C
+31AE4204E89521A96E1219E696B913DEB2AAB7A3B022D06F34FDFCB810A04E60A4FEBE284C2F063E
+0AE9EDF87704921CCFA193BDC912B747E13570066223A49F1F6E2AF0D4D65DA04CA876FF7A462FFC
+9C0BA2CC545C3BD36DBE762F32B2D6BE5867C59F479195C92440DC165098B74EA5C3AD93CDF2D410
+B04C16BC7801E7956F4E5107450787AA592493171C3628E6B8F49D4F8429EB98DC52EF025F001387
+BC1A7093F7A99F10B5D2D7DD8BBB393BF6E56F08F4F7FA1A343F220D5A1EAE7168C74D41BE1DC1A8
+3BD65B72B982F4F7B34F24F97F9EC9A91011064031FACFF2A14921A32024385F4E061CD07D152E74
+1BF97156D951A342488FA7F5EF934CCAD13E2753A0AB7A1F565C2F7F6B349DF03BBC25BBD972A9AD
+F809BB5C5048A8CCEF9297B2ED3324D18867F293CC66E88B3A39D107B610DFE79A3B4E83A96D3D52
+A17FE8A62C9FDD271130148366942C9CE57558D023DA5F7501319EBFA33DE9E6D1E76D7C20DB8A09
+B657839DA99F3D8143F1EE6253A3295C9651FA4366547893C2DC7ABCBF4BB7609DE5D001E0A36D9F
+FBE01F7D0903B3208AE8547E2E5F14EC1AF4C2535CA8F4EA37E3F3CE172C7A1E8308995B1CC23E6E
+81190246BCAB6E755BF868D449BB02A2AA87C44C9CC0F571ADC72547CEECBE104BB274B8AC16DCB7
+5D5F458D356466B921ACDEEAE384E2EB1DF6EF393B41B9747F0A4FAEB4AF1928D9AD6FB7E06FDC62
+1E4C6FC98CFB43F88584BD55D9B97CC9549093EDE586912161931162B1B1D52D0443260DABA02AF2
+B4432100D5506546013DA703573FA8013685CC798CE501960093DED713FFCCF89CA2B9106390198C
+29A00864108CDCC1984A8BAB53919028C01B26ECC7925E38CBE6CCA8978EE21C2B06E7B3E48FBA97
+8E2A7D186E563C088F84AA23178B60E4729EE87D67B1091F3B6973676C1CBFE6530EB773C62E2C24
+97014AB0E8B71A1F4E86A378AA26591511BEE3CF3D64C94848582E1354E1605B6457823F2C5E640A
+D3802946BB2E7E8E594E8C04B430C2385DD40746CE8534F50842E74D7115F3DB0C72D1C9C607C657
+3B094AEB73B7A79876CFFC3E2F8C9FEAAA07D3BFCE05B61F7749A8793BE90CCCECA2D7077F25E899
+D3331FE161A7E86C842495D584C6E4A0880B2951D8A13B88C4672080A0B1BE36BF47C3ACE7288CFE
+41A8C1BAA6F0814A947FBD6B3AA72B6C73A8C578CA51CCC96F2352316C467BB960E981F2B6485BFB
+44B577E71EFDA16E7405954BC7C9F0759F5A9F1EBCD2FA9CC9648D5831A68887F41B15081A204C24
+B4B992A231DEF9E698D4C3A25B6F5474F5BE6A601F2D337A58A0D21FF37FD91EB86D1D738893A03A
+69F0CD743F611CDFFE69DB2C6ED0E4611D56F803BB0DC06E7FE85A303839612707647B1BE9FAF8D6
+84122CA9E5CB8BDE2936D3F4FF254D31529D7538BBD4D35539489F9E7316F24214B996BCDCF1818E
+749A71CF0E8845AA1E2A58AA62A48E02BA4564625D20AA220EE719608521D7D7A7FCA0BD8904A401
+9819D371F3F59D46C1354E5FC1A6E5F79B20CF4ACA2BF0F2DE73DA193A6F9ACBFE0B4731C4BCEBE6
+D96FE822965DE965232282A3A130361F188B3AABDA95A8A2790D9240BE008B6A6DE4BBFCADA05B67
+86B9BB8E0DFA0C30043A3B07ED46277E07B9808422C8ED16758B9C396F4EA929D769785B2C9568E5
+70A83B989B25CE200F1727D41E2B702E7F88F1784F4C83FA60A74EB26B2DA95126E508ED519A61CC
+151DB6804F61826C5F86D8FA89D06E526FED97A0DB88EDB432FF32C1ACC9B622EEDF601081AF7B96
+3C9CFC1D13E4A9C74FEA0A1C8E3D8653CD92A944D4CA6B0D306619AFD503506D77732D6514F604BE
+4610C2560931BDE0B40939BC1D126B0E97F72AE1B4A9252123B54F7A27E0CFA4425B4546526FD741
+CA77952B10D13E0AC2E32006A903808FF0CD013F936238C74CC75FD915244C56A8412F37F0134840
+347699508D6F3D7F3203A25B7C70100719582CD588590EE34B3AB13E255B613A6D00386A0104CC5E
+D2C646F09A88888D3751651D5646C5227A3C80E8DA1B0A331121DD2429F1F4775D30564DFF47D01B
+BE2C6C72CE4D1FD9A2077C04D2B0274B8916F6A9D1A4A6964A534F47CF241D5A8E34B23F85BE9ACF
+FC2FEA961F277539F215F8728D6788F67BEAF45502839BCF23D8763C3949352F00C579A9A4FC408E
+C625E310DAE61512DFE6844E82D36A2F81709E1F05B38AE9C222ED62C961EE63593CED7AAF73CE2E
+D3667740C77B309B93EEFE1B4BA65D48575A66BE86743DC9E5D3C2FF418D11F7F211B86E827EE1DF
+C3613E7498030F07050524536D1F8A94DDB6698BE7B963C55CB3F74B676CD815A7B3DF4B1A0EA2BE
+1B0B9A11FFBFD5B1FA49668AEE14629316AF436A0821C20BEEF7B3480847934A99F6D85B68F4DDF8
+859A754E009428AF89A90D1852C220A607FF0806E8080726EDC94D691D214B4521C147C4273AEBDD
+BB4A697EF16448CD9B2FC95293305858DECFD406B89B9F3FDAE2AC579E80CF321EBAE5701FB2F7CA
+D8ED04B4A63115886D45D6120F69AEF1A21D80AD3C2D35D2899F1902242B96CD349E0AAADA40F7A1
+1282B6B52BDD97708E58DC5E2D22D1153E5FA3F3B300BCDFAF98DEC2F4E3C82A1C85F985735F3987
+4F557579F422664E07CBE19DA680EFB0FC82C323EC5C4644C51709AC8D674608A8043C91E6C7988D
+430F10BA6CE1FC7FC0604FCD8F723895250AEC36CC35B3FA14FE2A0D24095DCC30B2093F2298F5F0
+A97676A0BE66C3DC9ADACFE2FC0F721A20E945AFC1096A619075D5E9A264C796EC6C90EF1AEEA8DC
+089B44FFC13D27CB2370070A52D4416C53F364393E46EDD7EDE00799960CE6E0D57E4909E88ADD64
+BDD2B0EBE2D73FA6ACF8B40280DAA0637E705C65AABD523B8815F22F23E9FF81E7829C7E4BC980C9
+143AEBE1A04DC0D253396BBB7268BD5AEEA356B610D5DCEE03135E00AE34388251F31714A1C40E18
+2652C48CDA2211A22CB6F02490E69A44CECB169754C53B16028D352E0119F5D5FAE0BD7EA1CDA647
+12A6147374B64244E21E9EC9F0D1381AD22D5B6212B26C3F9AA5F6045F25DD9F5EB4489EA39B1945
+331AC70510C5752557DE21D0A6CFC1EB10A98FA867B76DA6E4249469F591FD154D39E89364A43DB0
+07AA0D7A911CFAE6CE2B557997FBC44F55A27F622BD7B8B10EC9F5D10F2649A646FD964AE1B111B3
+5B46A252C4DEE44E7426EB5739F24E8A390694597DB3A1FE7800C97E59558322F0E49A0CCE2AD94B
+1E2D1026AFA771723E3F523916F55ED866C9FB4A2F759651C613A2CFF362028CDF9D38F05D4C7C60
+24C533E930B64B099FB1AF04B01F5FB9CA6867E6EFF55A772C5391831059987E10CBF987E3F378E0
+1329F73D54DC0484177D3C3C06F67397955FF1CA4EF8AD1606B70455255D631A7D6EB92BFDBA14A0
+FF28B2ACE7E81AD666EA9B3A0F5A6BA3B5DFE35044FA4B3D8ED956009C60E98CC132F2E84967F4A9
+8A67B336D5EE7CAF7DD1F74D1FA08619941361FA7312CF225D89CEF97E864C8369EAFAB94D97F056
+5505D825972B754F6729596EEA91210B75DD8F645382ACE36DE60819A02B3B48DD00F5485F9264F9
+FA926D732E2C267B0BE8CA98526F124F97EFDB86132C5EF16B103908172FC51F286FFE45FF253512
+E0033F037FF182BA536A9EB2DF2D1DB257D9C86C46E1B002FB32AC70CA9462E6EB48994752CEBCE3
+9F08ABD4F4B0889283E55500702185A841E328
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+cleartomark
+%%EndResource
+/Times-Roman-iso1252 /Times-Roman ISO1252Encoding psp_definefont
+/Times-Italic-iso1252 /Times-Italic ISO1252Encoding psp_definefont
+/NimbusMonL-Regu-iso1252 /NimbusMonL-Regu ISO1252Encoding psp_definefont
+295 271 moveto
+0 0 0 setrgbcolor
+/Symbol findfont 50 -50 matrix scale makefont setfont
+<B7>
+show
+370 271 moveto
+/Times-Roman-iso1252 findfont 50 -50 matrix scale makefont setfont
+<4D6F64696669636174696F6E>
+show
+653 271 moveto
+<6475>
+show
+725 271 moveto
+<66696368696572>
+show
+877 271 moveto
+1 0 0 setrgbcolor
+/Times-Italic-iso1252 findfont 50 -50 matrix scale makefont setfont
+<534D4553485F535243>
+show
+1149 271 moveto
+/Times-Roman-iso1252 findfont 50 -50 matrix scale makefont setfont
+<2F>
+show
+1162 271 moveto
+/Times-Italic-iso1252 findfont 50 -50 matrix scale makefont setfont
+<737263>
+show
+1223 271 moveto
+/Times-Roman-iso1252 findfont 50 -50 matrix scale makefont setfont
+<2F>
+show
+1236 271 moveto
+/Times-Italic-iso1252 findfont 50 -50 matrix scale makefont setfont
+<534D4553485F49>
+show
+1435 271 moveto
+/Times-Roman-iso1252 findfont 50 -50 matrix scale makefont setfont
+<2F>
+show
+1448 271 moveto
+/Times-Italic-iso1252 findfont 50 -50 matrix scale makefont setfont
+<4D616B6566696C652E696E2C>
+show
+1708 271 moveto
+0 0 0 setrgbcolor
+/Times-Roman-iso1252 findfont 50 -50 matrix scale makefont setfont
+<E971756976616C656E74>
+show
+1938 271 moveto
+<434F524241>
+show
+370 331 moveto
+<6465206C61207072E963E964656E7465206D6F64696669636174696F6E2E>
+show
+294 433 moveto
+/NimbusMonL-Regu-iso1252 findfont 42 -42 matrix scale makefont setfont
+<69666571202840574954484E455447454E402C79657329>
+show
+294 476 moveto
+<20204C49425F535243202B3D20534D4553485F4E455447454E5F33445F692E637878>
+show
+294 520 moveto
+<2020>
+show
+344 520 moveto
+<4C44464C414753202B3D202D6C4E455447454E>
+show
+294 564 moveto
+<656E646966>
+show
+295 682 moveto
+/Symbol findfont 50 -50 matrix scale makefont setfont
+<B7>
+show
+370 682 moveto
+/Times-Roman-iso1252 findfont 50 -50 matrix scale makefont setfont
+<4D6F64696669636174696F6E>
+show
+657 682 moveto
+<6475>
+show
+733 682 moveto
+<66696368696572>
+show
+890 682 moveto
+1 0 0 setrgbcolor
+/Times-Italic-iso1252 findfont 50 -50 matrix scale makefont setfont
+<69646C2F534D4553485F42617369634879706F7468657369732E69646C>
+show
+1563 682 moveto
+0 0 0 setrgbcolor
+/Times-Roman-iso1252 findfont 50 -50 matrix scale makefont setfont
+<706F7572>
+show
+1681 682 moveto
+<72616A6F75746572>
+show
+1863 682 moveto
+<6C92616C676F726974686D65>
+show
+370 742 moveto
+<4E455447454E5F33442071756920636F72726573706F6E64206175206D61696C6C6575722074E9
+74726168E9647269717565206465204E657467656E2E>
+show
+294 887 moveto
+/NimbusMonL-Regu-iso1252 findfont 42 -42 matrix scale makefont setfont
+<2020>
+show
+344 887 moveto
+<696E7465726661636520534D4553485F4E455447454E5F3344>
+show
+974 887 moveto
+<20>
+show
+999 887 moveto
+<3A20534D4553485F33445F416C676F>
+show
+294 931 moveto
+<20207B>
+show
+294 975 moveto
+<20207D3B>
+show
+295 1092 moveto
+/Symbol findfont 50 -50 matrix scale makefont setfont
+<B7>
+show
+370 1092 moveto
+/Times-Roman-iso1252 findfont 50 -50 matrix scale makefont setfont
+<4D6F64696669636174696F6E>
+show
+667 1092 moveto
+<6475>
+show
+754 1092 moveto
+<66696368696572>
+show
+921 1092 moveto
+1 0 0 setrgbcolor
+/Times-Italic-iso1252 findfont 50 -50 matrix scale makefont setfont
+<534D4553485F5352432F7372632F534D4553484755492F534D4553484755495F69636F6E732E70
+6F>
+show
+2019 1092 moveto
+0 0 0 setrgbcolor
+/Times-Roman-iso1252 findfont 50 -50 matrix scale makefont setfont
+<706F7572>
+show
+370 1152 moveto
+<72616A6F75746572>
+show
+556 1152 moveto
+<6C92616C676F726974686D65>
+show
+832 1152 moveto
+<4E455447454E5F3344>
+show
+1149 1152 moveto
+<717569>
+show
+1242 1152 moveto
+<636F72726573706F6E64>
+show
+1495 1152 moveto
+<6175>
+show
+1572 1152 moveto
+<6D61696C6C657572>
+show
+1769 1152 moveto
+<74E974726168E9647269717565>
+show
+2062 1152 moveto
+<6465>
+show
+370 1208 moveto
+<4E657467656E2064616E73206C612047554920646520534D4553482028626F75746F6E20646520
+73E96C656374696F6E292E>
+show
+294 1309 moveto
+/NimbusMonL-Regu-iso1252 findfont 42 -42 matrix scale makefont setfont
+<236D6573685F747265655F616C676F5F7465747261>
+show
+294 1353 moveto
+<6D736769642049434F4E5F534D4553485F545245455F414C474F5F54657472615F3344>
+show
+294 1397 moveto
+<6D7367737472206D6573685F747265655F616C676F5F74657472612E706E67>
+show
+295 1515 moveto
+/Symbol findfont 50 -50 matrix scale makefont setfont
+<B7>
+show
+370 1515 moveto
+/Times-Roman-iso1252 findfont 50 -50 matrix scale makefont setfont
+<4D6F64696669636174696F6E>
+show
+651 1515 moveto
+<646573>
+show
+739 1515 moveto
+<6669636869657273>
+show
+910 1515 moveto
+1 0 0 setrgbcolor
+/Times-Italic-iso1252 findfont 50 -50 matrix scale makefont setfont
+<534D4553485F5352432F726573736F75726365732F534D4553485F5B656E2C66725D2E786D6C>
+show
+1843 1515 moveto
+0 0 0 setrgbcolor
+/Times-Roman-iso1252 findfont 50 -50 matrix scale makefont setfont
+<706F7572>
+show
+1955 1515 moveto
+<72616A6F75746572>
+show
+370 1575 moveto
+<6C6573>
+show
+445 1575 moveto
+<636F6D6D656E746169726573>
+show
+744 1575 moveto
+<737572>
+show
+824 1575 moveto
+<6C6573>
+show
+898 1575 moveto
+<626F75746F6E73>
+show
+1075 1575 moveto
+<6465>
+show
+1142 1575 moveto
+<6C61>
+show
+1196 1575 moveto
+<475549>
+show
+1305 1575 moveto
+<6465>
+show
+1370 1575 moveto
+<534D4553482E>
+show
+1569 1575 moveto
+<436573>
+show
+1663 1575 moveto
+<626F75746F6E73>
+show
+1840 1575 moveto
+<7065726D657474656E74>
+show
+2073 1575 moveto
+<6C65>
+show
+370 1631 moveto
+<63686F6978206475206D61696C6C6575722074E974726168E9647269717565206465204E657467
+656E206574206465206C61207461696C6C652064657320E96CE96D656E747320766F6C756D697175
+65732E>
+show
+294 1732 moveto
+/NimbusMonL-Regu-iso1252 findfont 42 -42 matrix scale makefont setfont
+<20202020>
+show
+394 1732 moveto
+<3C>
+show
+419 1732 moveto
+<706F7075702D6974656D206974656D2D69643D93353033339420706F732D69643D9494206C6162
+656C2D69643D944D61782E2048657861686564726F6E206F72>
+show
+294 1776 moveto
+<5465747261686564726F6E20566F6C756D65942069636F6E2D69643D946D6573685F6879706F5F
+766F6C756D652E706E679420746F6F6C7469702D69643D949420616363656C2D>
+show
+294 1820 moveto
+<69643D949420746F67676C652D69643D949420657865637574652D616374696F6E3D9494202F>
+show
+1251 1820 moveto
+<3E>
+show
+294 1864 moveto
+<20202020202020202020202020202020202E202020202020202020202020202020202020202020
+20202020202020202020202020202E>
+show
+294 1908 moveto
+<20202020202020202020202020202020202E202020202020202020202020202020202020202020
+20202020202020202020202020202E>
+show
+294 1952 moveto
+<20202020202020202020202020202020202E202020202020202020202020202020202020202020
+20202020202020202020202020202E>
+show
+294 1996 moveto
+<202020203C>
+show
+420 1996 moveto
+<706F7075702D6974656D206974656D2D69643D93353032309420706F732D69643D9494206C6162
+656C2D69643D9448657861686564726F6E2028692C6A2C6B2994>
+show
+294 2040 moveto
+<69636F6E2D69643D946D6573685F616C676F5F686578612E706E679420746F6F6C7469702D6964
+3D949420616363656C2D69643D949420746F67676C652D69643D9494>
+show
+294 2084 moveto
+<657865637574652D616374696F6E3D9494202F>
+show
+772 2084 moveto
+<3E>
+show
+294 2128 moveto
+<202020203C>
+show
+420 2128 moveto
+<706F7075702D6974656D206974656D2D69643D93353032319420706F732D69643D9494206C6162
+656C2D69643D945465747261686564726F6E20284E657467656E2994>
+show
+294 2171 moveto
+<69636F6E2D69643D946D6573685F616C676F5F686578612E706E679420746F6F6C7469702D6964
+3D949420616363656C2D69643D949420746F67676C652D69643D9494>
+show
+294 2215 moveto
+<657865637574652D616374696F6E3D9494202F>
+show
+772 2215 moveto
+<3E>
+show
+294 2259 moveto
+<20202020202020202020202020202020202E202020202020202020202020202020202020202020
+20202020202020202020202020202E>
+show
+294 2303 moveto
+<20202020202020202020202020202020202E202020202020202020202020202020202020202020
+20202020202020202020202020202E>
+show
+294 2347 moveto
+<20202020202020202020202020202020202E202020202020202020202020202020202020202020
+20202020202020202020202020202E>
+show
+294 2391 moveto
+<202020203C746F6F6C627574746F6E>
+show
+672 2391 moveto
+<2D6974656D206974656D2D69643D933530333394206C6162656C2D69643D944D61782E20486578
+61686564726F6E206F72>
+show
+294 2435 moveto
+<5465747261686564726F6E20566F6C756D65942069636F6E2D69643D946D6573685F6879706F5F
+766F6C756D652E706E679420746F6F6C7469702D69643D94204D61782E>
+show
+294 2479 moveto
+<48657861686564726F6E206F72205465747261686564726F6E20566F6C756D65204879706F7468
+657369739420616363656C2D69643D949420746F67676C652D69643D9494>
+show
+294 2523 moveto
+<657865637574652D616374696F6E3D9494202F>
+show
+772 2523 moveto
+<3E>
+show
+294 2567 moveto
+<20202020202020202020202020202020202E202020202020202020202020202020202020202020
+20202020202020202020202020202E>
+show
+294 2611 moveto
+<20202020202020202020202020202020202E202020202020202020202020202020202020202020
+20202020202020202020202020202E>
+show
+294 2655 moveto
+<20202020202020202020202020202020202E202020202020202020202020202020202020202020
+20202020202020202020202020202E>
+show
+294 2699 moveto
+<202020203C>
+show
+420 2699 moveto
+<746F6F6C627574746F6E2D6974656D206974656D2D69643D93353032309420706F732D69643D94
+94206C6162656C2D69643D9448657861686564726F6E>
+show
+294 2743 moveto
+<28692C6A2C6B29942069636F6E2D69643D946D6573685F616C676F5F686578612E706E67942074
+6F6F6C7469702D69643D942048657861686564726F6E2028692C6A2C6B29>
+show
+294 2787 moveto
+<416C676F726974686D9420616363656C2D69643D949420746F67676C652D69643D949420657865
+637574652D616374696F6E3D9494202F>
+show
+1680 2787 moveto
+<3E>
+show
+294 2831 moveto
+<202020203C746F6F6C627574746F6E>
+show
+672 2831 moveto
+<2D6974656D206974656D2D69643D93353032319420706F732D69643D9494206C6162656C2D6964
+3D945465747261686564726F6E>
+show
+294 2875 moveto
+<284E657467656E29942069636F6E2D69643D946D6573685F616C676F5F686578612E706E679420
+746F6F6C7469702D69643D94205465747261686564726F6E20284E657467656E29>
+show
+294 2919 moveto
+<416C676F726974686D9420616363656C2D69643D949420746F67676C652D69643D949420657865
+637574652D616374696F6E3D9494202F>
+show
+1680 2919 moveto
+<3E>
+show
+220 3030 moveto
+/Times-Roman-iso1252 findfont 50 -50 matrix scale makefont setfont
+<417474656E74696F6E>
+show
+220 3035 188 3 rectfill
+408 3030 moveto
+<3A20756E2066696368696572202E706E6720206D6573685F616C676F5F74657472612E706E6720
+646F697420EA7472652070726F6475697420706F75722064697374696E67756572206C276963F46E
+65206475>
+show
+220 3086 moveto
+<6D61696C6C657572206865786168E96472697175652064652063656C7569206475206D61696C6C
+6575722074E974726168E9647269717565202861637475656C6C656D656E7420632765737420756E
+652073696D706C65>
+show
+280 399 1 176 rectfill
+2125 399 1 176 rectfill
+280 399 1846 1 rectfill
+280 574 1846 1 rectfill
+280 809 1 176 rectfill
+2125 809 1 176 rectfill
+280 809 1846 1 rectfill
+280 984 1846 1 rectfill
+280 1276 1 132 rectfill
+2125 1276 1 132 rectfill
+280 1276 1846 1 rectfill
+280 1407 1846 1 rectfill
+280 1698 1 1231 rectfill
+2125 1698 1 1231 rectfill
+280 1698 1846 1 rectfill
+280 2928 1846 1 rectfill
+showpage
+grestore grestore
+%%PageTrailer
+
+%%Page: 3 3
+%%PageBoundingBox: 18 18 577 824
+%%BeginSetup
+%
+%%EndSetup
+%%BeginPageSetup
+%
+gsave
+[0.24 0 0 -0.24 18 824] concat
+gsave
+%%EndPageSetup
+%%BeginResource: font NimbusMonL-Regu
+%!PS-AdobeFont-1.0: NimbusMonL-Regu 1.05
+%%CreationDate: Wed Dec 22 1999
+% Copyright (URW)++,Copyright 1999 by (URW)++ Design & Development
+% (URW)++,Copyright 1999 by (URW)++ Design & Development
+% See the file PUBLIC (Aladdin Free Public License) for license conditions.
+% As a special exception, permission is granted to include this font
+% program in a Postscript or PDF file that consists of a document that
+% contains text to be displayed or printed using this font, regardless
+% of the conditions or license applying to the document itself.
+12 dict begin
+/FontInfo 10 dict dup begin
+/version (1.05) readonly def
+/Notice ((URW)++,Copyright 1999 by (URW)++ Design & Development. See the file PUBLIC (Aladdin Free Public License) for license conditions. As a special exception, permission is granted to include this font program in a Postscript or PDF file that consists of a document that contains text to be displayed or printed using this font, regardless of the conditions or license applying to the document itself.) readonly def
+/Copyright (Copyright (URW)++,Copyright 1999 by (URW)++ Design & Development) readonly def
+/FullName (Nimbus Mono L Regular) readonly def
+/FamilyName (Nimbus Mono L) readonly def
+/Weight (Regular) readonly def
+/ItalicAngle 0.0 def
+/isFixedPitch false def
+/UnderlinePosition -100 def
+/UnderlineThickness 50 def
+end readonly def
+/FontName /NimbusMonL-Regu def
+/PaintType 0 def
+/WMode 0 def
+/FontBBox {-12 -237 650 811} readonly def
+/FontType 1 def
+/FontMatrix [0.001 0.0 0.0 0.001 0.0 0.0] readonly def
+/Encoding StandardEncoding def
+/UniqueID 5020945 def
+currentdict end
+currentfile eexec
+E98D09D760A3C22CF119F9DC699A22C35B5B35ED6AA23593C76D54CABB5E942BF7D6DD84F1664B89
+699C74B472DE9F8E6DF925F6C4F204E9F1C639B4DBA988ED2AC419FF2B2BDE605B8EE3264EDD6641
+2D4F21C64AC522BDFC7C5502F9C3F3E5592B3B2093D33C9BFAEDD2D49E89AABAA832E23F062E91A2
+5032519D1868816E44B4E0747795003D7930299D6E1E2A5BFE0D595DC97E140989CE81D8D7F852FF
+9CDC7A1B1B598C69131DEE005B415805A16D8A123E6A2261C63C769D2F4B60FA2C438AD7D199D8E4
+5F7E7C9A605C8CA14E21FCD81C9A515FB8DB6F99604534D06EA9D87FE0FAA852899C9D0595C7A97E
+6C55F79FAC45CD38E87B10D210CE7501E88C8FCD3444354365FB893A12F596AE2C1E70D5819EE0D0
+87D10BF8DA96F3DABD5405D28C4228C6C31BA4052464859640933FEEFD8071C0C84CDD829A9B1D0B
+A01F25A4D50EE2EA2B45160CA6333B2D2800306ED2BEFDFE155E9D9F9342EB8D5B0ADBF2460CCC98
+643FB1287CCD28ABA7B5CAB92EC39EE2E918990372B16F8487EBA30EAE88708B6CF33B6C015D8096
+C7CFE2F139F52052E3925C0D50FD64CE68236D59CB83EF56BFC584150EC38065059F3308AD6F9A99
+F83EF4E6CB13855C8175E31417D190D036B387D3952344A950F4D8C7781B307A094DF1ECAEE4D2C2
+FD747BC6F7F9C6BD0E90C19294F96C8C5CFE88FB34C477574A1B1630B8CC591529E59B20794DA32E
+61DECDA8ABBD1AE956CF74012AA01D42EE01E861B0AA6897C864788AE59DEF43C493246FDB1ACA55
+4C12594BC7B33657A9ECC9E3D1472EF826073F632BE540C35FF6FB40566773F3BB2204D3A579A08C
+CBC844C14B18C350F003B9DA23A570C362D6003893CA32F86F59B829C78EE3188B6E3F7FA81D7F62
+2825C639638DFB78B7AF1F500F5B450FA54DBFA5CBA277C794ECE93275A3DE0B452FDC8DDC2993BA
+A42F28A636008CDCB03EBF71BDCAF35019778993443F88412AD2AD0D7155A3944606463266322DBC
+0244B07DA1E9C27A27B59664E8566D7A54CC03E995AAD008B0A17E2C3EF61F720CE7F7788599C4E4
+4C709CD5C31B11107F16AD70B17B9AFE2E8CD922A7428DAC171427FFAF51067307FAB0ADB530E701
+FD22DA22C4CD3064067BD4F6089C4B2C87937DD426E4E9D2F60E608288BAC9056554D04947E69200
+61E379CF5E81BFD32FD37EFAC1F61CEBEE551B0851516471A7472C60DF89DAA9EB1DC5A67E479745
+3E69B9E22BAF4E3CCA4192D603295B018C4AB69D18DE52DFDF15E96B557F290A4B8C5B1E7A6CACA8
+1F2351B97ADFC36995ABA43803A6E5AC04A3C93495F6D38106B8B144449C07D1358210F9176E1565
+72363CFBDE576BFDF99FA329DD1346E83F79E06CF68250CA57A68931BC7F342AD295D0CBA17AA95B
+B8EEB53EA6E8E660B814E9F857CECB14F44A43288B69A9E7908D55BF19E844359879D28CAEF1C38A
+36420185D20DFB32C2E002202800E8EF3D67C5D50E919657CA958B538D537D503444865331D79BFC
+40312068D72364503BD0CC84B5F30A74D8B5B6A26AF2DB764564FB65A6BA8F9051AE2B4EA458D46A
+4569F30C6E77DC097356770362E6CF3F1661074778EBB44FF7D1E3B64FF75E77E11FE525BB121C65
+46CFD13300CA1F02D571B82A5825E6226D14FDCF27F06D87452A8B6C5DCA658535CEE2A795E58137
+D48E566B69D53A0C3B766E84C51EAA221C46999CC8065ADB2F129D5B630FAB1814C0C33B5AEA0EFB
+B6E994D80941B53079AF96D90A0B924F9B0E319BED9836B8F9053F868363D3CA554CBB181863301F
+8CB940872ED5FA7BD18CE39218B5AD8AC57D0F752D941076B1C64D99BE0DB86D7A6D96510D772EB2
+4C587F11779BD21CFE5BDE1F29C1EF9022B2B8BCD7F91153C845906722477829C40111D810480F3C
+F62DE8DBA7FD86CD236E656618CAF6FC46827FBC4898EA7672F8C9971AFE43E0E01EC8B77D4AF48C
+BF1210E98C1DB15C16D149BFF58AB0270CF015B107A3A50F5DC8F37FFB92EEC8CB6778DDB7CE4AAB
+C464C4AFF654223006A550EB52485A23D2B4AA7198D3CD54418102F1E9A4FBDE37B841E56F5C2C53
+966DB9B66B000E4588282E3FB80C2C519339F0002D2F83C979EDC5827A3B3C8EF8810A0F9DACB6B9
+998E9AF6551F56313DC4011904CB979AA2D32B11A811BC248141E4B9734D9FB7982A5671002D8279
+CAB93ABE057474628DEFC95D43890DB1ED34CFA8A20BDC3D874E7679A396158E522ED0AB969A4E3E
+C7E4474E192590504D54DEB7B260B7935C4E56548A7D121AC1F741F8CDF259EA1B5813175A77A1D2
+D30BA26F65EB765A04C09ED51F69F41551ADF399E6AA2FC09788137BEA4913F17B8EB838C38FB272
+1FDCB55FD65697FF0B850E7D3D1CE266BF90F7EC06A9A0876BDFE767D3A918B092FC78C775F945CF
+1F96E859C03DBF630D9A940939654C3549D8F7921CB94EE23D5A0535DE9DF31EA0F937F860B4F220
+A99ADDFC343D7CF7BFA0B803C12C26403F0DCFFC8EA786D0D8A8D9C367419CA8AE41190CE93A8086
+583A1E6C9D70B612C84D87D2EEAA71EC2DC12F4CDE6A821303D5F6A9BBDB7EEDCD289E80FA3B75F4
+7F481B50719DCF4A142069393593B9AF9CCEEAEC56A35B8787193D7C88113E9E1E221D151E093B01
+9EF89F6118BEC4735103CC8003CC5AD1B6727B3226CD44C497DA7052DD681695DBEC3397F9598C91
+77701C73BF0594CE93F23D50EC5BEE2FB9DA1FC966DF148B27B28EE3C89526DD6625E2887F9FA076
+7C127C609EE315626BC14D274FBEA56528DC06A27B2D476D46E9E7916590B156A5DF04A6CB15E362
+45D77021767B6E5BDFCC679670263FD891446C3371B11BB6E1DF60F960AAB4149D7753E6A5C33810
+C42C8BFF4E935003388506F8278BD7CB672F132E065AE684DCA0B9064D01DD620E7FFDFE04F14277
+EFE8E60159BA0FCA3FE2F28B902D4AC275D19F0AC6971EBE827C4A232D87650D2688345BCA78F879
+077114F0463C5F058107B669566F8171E4E284D278405580F04BFFC9902784216E0C9A17AA9B2935
+E66E18A783F723BE044389B7E9D62AA36818FF2EA406C3C1A9D2F3436F3EE7DB8BE86AFA8DAA6A4B
+1B84611350D8D27605509612B515E16AA843164D5D0805E36A2B9EF74C5F6A0B9D59A04B55697123
+27F4B1B30E9587CD103337639967CBDC655AA46E80D2CFD24BEB50815B5338E522B3A7AFE8362AB4
+F05D8BC52BBA9C5089ADA8C89529B0275AF422EB540D31A938B8740860756325B966B36817115213
+FAAF92DE63F6BAE1E0064BFBC5588098B61EB83C71F1C2082436D37DAF1ACBE186FEDC4BE7C1233B
+6F18BEC5F99002D21CB7864E4811F7AB3C03003E1E4490AD1AC793BD28FCD5EF0E6CC30EF39A08C5
+2F71939B0CEF620DC69E31E39D6DB969049031B0C92EF2DB653D97F370141456A52985076B268652
+FA2648C792780BAD637C4D7581FB2D62011D57E293719487CF2D1F013CFAA532E1C2D39178D51272
+A6AF041440BCA174B5CC902BD7390C7D3695056CB4BD7791F9FB6D88E7A70DEF2C97869F5DBC5BD8
+23C517C7B7C39D624DF627DC9653EA5347BFDA80B723F05F6DBB4C9EA501D862ACE05B9DBDF21B70
+56FBCD8C6D4B85873DCEE6166C8B5ADC0316CA12D9639F361B15A42F00E1D62EDBCA1111972FA0F4
+5758BECB31DB38316F3CDFE1B41748C93ED58B67E9B57ABBED5924A6D53E99FBC9A994A6489A8BDF
+13EB685548B4DC6D62DA7426C22227D4D43B6FFC7B5EA91C896730253E8941AFEE588359C2BECF6F
+FC415B9EB6D31CCB0F6C7F85853E6449FA6D627A97A3CE8303F148393ADCCCDFA2FE085C6908BE5C
+3C05AF00A6F02840206C3253A559AC5C049BDDFD11AD9B118403B84DA10AE3C470CB9A9A2D1D7B73
+2F59F5FE146DEDA60AE750F551AAC934621B4470E1BC324C436303E25F81D0DC3188BE0D6FEC5414
+C20E4CB18952E12CB6423DF7124627ACDE145500D77A97A8BFD9CB50D1FAA008E2CE2B2505A4749F
+1EBBB092C347023714055A9B63353AF9E7FEE05BB54C9843698101F79888A91531773830C2C967B5
+88D3ACD2192883D5CE3962D51084FC653EAE2C5FB2DA41DACEFB5C76812D2EDB5B109677289CD199
+8D457FB1023A19AC67295BBC1A9A20A426B06A368DF3C5DD083CB1180D287F5500F2C635EDE157EE
+FCEEC5503447382D15C748C1E35F68753992E5C90F900DE54D18F8E1B355D1076ADFB1F3590135FA
+D1A36F028E44F48ABB149B80CA9A54614D467F8D71CB310BBC7AC7100261092DB8C5BFD39E0AC6BC
+2C9D6CBC3A8C05FF8A74CB21608EC4A4CFE4CBAA2D056DBA14206106044DECF59F957EF8A9CADE4C
+9B19D8D30DD4FDE6A9548E50DB51ACA73330142153FC36B69C1C8D5B26D0C689B7040E81AC2C864F
+D7C097C99BE5953843E172C97AB5684F35FB03A725A89DBF371F08DDF40A1531FC1B676DB0E1543A
+EC6E97D3D2E4AA3D5831D8B3C952ABBFA112352814FB6FAB61A0D680E6640F6AEC8426200CF61286
+F7422CB2F78C61EBAA36D47EC16D7FAF8B4AF31D090CDFA255D9D7C61D46CFB22A7D6E1758E71ED5
+67E00CBD8E8F468DDFB477F091A2F915627F22FF47B876544BC1F03B6BBB98385F009C20BB1AA2A7
+A78674692B8EAC2E3C8069B79E679338DA57F72976810F845BEB6B9ADD32B95D78E5E60F16DD1668
+9C05FD82D36A3115BE8ED494A74DD211D58A2CDF983FCB9CDC29BF7F0E29988FA23560EDF514BC1D
+183F3B2A22C09FB179B47E05ADEF48DF02F31C29875D1915037B19407764A4292FE44E741651A8E3
+BEB5F0D972B6327090F664417C84F84FFBF0AFFF8B1D85C822D90730AB4140C42A51AA8B1DBE4398
+4EA8566040EB8B341CCE23FD3F69DD235A080BA5C69AECB9BC732BC2D7D40617DDA6B79FB6EE40C3
+556C7DF9B23DAD89E94054B1345DB8402AE679FC4655A4A776C0150463F8DB2BFC0608EA1F124E22
+1DDAE6026B5E5D007A7E4A0D6B3B0CF3A2669E67C5E4F01551966A7BC48F2F4B6A87E740D8095E63
+F77C7A027F26B52F2299DE5B8A2F6209BCF3D31CB0235F998F781E5CC81E31DC424E008D46EC0920
+2951E5684804A0592EA47D6C788A20487BEA2EC8F2E6C1D7F378B62DB43CA43C4B366F8B4319631C
+FE9854F0E10321CFA3B01C873584863BBEFC23C72C05E695B56E8A52E89AA2DAB543834D34DCAC5F
+ED08DC51825C5257AE59850D101D84F4CAA1D29FC932F9E0EFFBF7A9A7F3685F61F0490CD3CC8988
+2DB52A757A6AF4C4E67B407BD2316B1C0FFE7DC54E43C87B874F57E4903334E2140B011484863CDC
+ACA331175F2CF3D72E0042855983AAF8853D3015E870FF0807014C31D55060DF3FE1FCE157324481
+2744AB51322444632F9AFDA6706E320FFE82B8CBE242A19DF00CE73EE48E25FF49D5871BD3E60652
+298FE3E8D400609E232E0DDC794C0579ACEF89E841B2EDCA50D51151F65E8C1CC3B01EF1870558F0
+BF5743718C3E068617E81BFE120C6CA16E0924BFC2541177D53671CAA3AB641C41557DCDAE1A3461
+47B5E999C4541B08B4AFCBC187AFD653D5B5F8386DF6AD8FE69E21BD0567DF494F736C6A184FA4DE
+48DC9F347787CA96E2E00A296C2DA05C2AD9BC423E9CA428D7F1FA12DC9353A302FB8C529AF8688C
+BB543B45B2717EBF8F6C497935F4F3BFFD285E0402AB7544B3CA4643AE5A8B5250ED987A95FC1F27
+5B9707ACD0641BD0EE2AE9758494F8D8A51DCE408A38AC20EAF0852D72D84D0C6BE973326793AEB9
+55EAC6FE0A2813A355DCD22F6F2CE56588D1C055CDDFA98878BCEB6A018DB22922D2B600A20F8184
+2E665DF41013CA0947C4237C2BD60A75E2FD1A3FB8C8FA19485730B87461AD466ACB02DF8CA24091
+4FB090B3D2B41EB6B8FF05E1A59D9FD668AF70BA5BB72778953BA55FC5F9F626043450E1D09BC83D
+8605098ABEF884639A37809A32565CBEFB3FF39EE53D6C18C58C272BB928E4410E361E59A50F242D
+69747A032617C52DEBBF62364AB5A96EFAF642D9D82BA679B1D70FAC10A4EB62FA5CFC308E86368A
+AAD7E75948F43598CD1C544A0D4091374D7E88D4522CBE902391641327E888E7748FA889DCE67ADE
+61699E7D77763681CAEE9B1CA8837B2F7EF9C18CBCC538C465C8E2DD34616953CCB6030A222C728B
+834911C1A179E2C770289407AB28B303E724D97F747D6134B425216A64C6E0B60F633E2B85300047
+E4C90339CE030A0FAE31E830C8ABA5AB3386A3B69267351A7BFDD66356AE5E57FB2994452993E90D
+E7C4E260ABAB93C37831856A650D56E44172FECA01D6C7C380F250B82473960D2A2A5FB6B4DA668F
+46E624ACF7FA0FD4490F485D640A3ADFC9F8652E7A38CE5799F770C3606DB4B8B947F93967F779E3
+A3C0572F13A5A187D31D7BD12A5C7BE23CB6ED6192086241B76C5BA6983DB9C93E4B208D707D3760
+F03CD6272EF3A4CE89B8E52E6AC5871A3D03EB975759AB4BE239E5EC7842CBB333E692CC607C722E
+185D3C39164DD320C6945629C70FF66A5237C0A9520A1FAD6EB9816069351AB0F135D90CC0982B14
+7D2294AE4A38A527EE40BE9CDE2512AAEBB590E134388BB171D0956A7C4566D65A9A041BE6C4F883
+6B3EC3D2ED1B48B566A783292B15B6127920D247D494F070BB20BEFF60640B11B276DDEEE49706E8
+B2B21BB40B7F00AAFC594C492C25DCA774E0B80D82E927448DE2E74A9D0DC7AC9260096EAF187B6C
+D6AEAA6D1DC4205B4411122751A5B22688404EA7C5861730371FFAC10F5AFD4727A0E402AB5EA757
+606B75EB86A05E8F774D6E430A1A3FE2A37EBB06700474239FB1CFA05EE44B91B82244C575B52E7F
+AF934B04EEB0D933FEB57EBE326D75821C8B23EAA85B583AED4320B7F04B9F2DC591091216FDE52E
+064BAAA9C2C9D9714B95A4558C21F3CEBE624B5403B31508F178581AF6863083ED762F1E2E34A45C
+FDD71660D626FF8648F5D6C5E580D4765A67FB6159EC8077A9F0A88038C8D3D7C77FF0926E2123BE
+874F7BCAF129D55A5B5960F824BD1728ABCFCC51D23936DE9A25C408D786E44C3A2BAFA4423177AD
+060D21D38E15E23EB6FFC0B4120E814695D423EEFC2744A1FC81B4DF89D76F0A6803D8B14E75538C
+AAD03A72517B86514F6952F6FD619D9E910D980F00964DB325318C045BDF79647F453D4A5CF4E61D
+D5359782827229310405FBCF6107C3AD9DDEF9A9A339D5D5A6EB2E7838A0A43221BD62CBDF732DB0
+A638A52016FB35BA7761AEC846A023D3BF2D1BB183543E81EB7CAC1E5970CDC6F068C5EA118C7AAE
+528D1396E6DC939112DA4460C890EAD5C01BDC438F5BB734218BA6270ADD0DC1778FD8AB16831D6A
+302B814A1A44B07EDC65956C9E6CF4875DF521F3CE5B422F71081B6D69BD270F739095C9E81C0377
+934A8BC6390C420C4E4CDD9CF7E32544C68D884E15ACA3BCC07FC8C132D8FB9D752C15D75C52C288
+57E2EA461A6FCAD90C56843513F74461F18D7164BC597A28AE4BA7C86EE1703535A9B9ED50122627
+71FC12F102E800E0E1AF7BB46681BD2B14B614CEA91B7B2AAA35235DE76C0E113C92688F8EC81277
+D58C3406778E1EC1CC15F1CD9A137C8FFDAAB99ACE3BFC782916F1A877170589A92DC921E6740A22
+B84DC6BACDABCC76E64C79E3A588D80F8F4D376E1B426F15751CF7391102102F0AFAFD8B22DFDEB5
+48AEB5F30B1673023D22054A13391A0EC08DE6E7B685A0D031AABF20B7C62187C0284892D5EAADF1
+21BA28263EB863D5E36EA9C06A77CCFC0E17F593961591F84D82AF823EFE41044C8D606FEF83CCC7
+B0E961E7994DF8A3CC36B209D953E250ADAB8D22D7F2B4E2C9CA39EFA2D93E56195C1560E30A5190
+CC5B17FAEFCF250DF79F6B624A4B917E11C332222FCCFEC4F6A47BD9E75DA9854FC3F7AE554E91ED
+DE144D7AEF38A0E3EDB5E5A5626374DB94F022C8CF549093041DE00D7269B7CE544E748439BA2870
+718C08E58FB4A77D93EBC04B7957D272AE1601D41BF85A2BADAA0DF73B0D3841D4839C85677FB2E1
+5F1D6CE592669FF4BBC9C69DBA334DC37706F2F6BE83D5863E8CD6A30C08640AAC4C233684E66B4F
+E6B62D4A8BE9D531E47BEF5640D9B5C27D990092BE1597F6995C8A77BE9C18AAE6C1CF130775DDAC
+41D34438FC7AD8E042CB56CBF2944932EBA7D053E9376FF398367450E35A1945FE23E05C921096A1
+5454721FFD0F429A3E06DC3ED36F1C170BE79C66996EF8337AFF85B90C5D3A4A94455AE9FA32E211
+7A63E59001F052D5F6223125BFAFA40901E98960ADF7BB886729DCA82FC3B8CC52B37FF2517299E1
+D769057F8154FB95582F02CB0BECC873A9C71796ADBD3E91324FAA94F2C41CF57C30B5897D031C02
+D256C909E080E70BFD1F32E69EF67031138C2DDCD1A8E4B65E485C23C3E450ABDD9815512D6F34A8
+4B9DB715DB2C7A93BFB424316E1AA44397749CB01088428F149A3B4324737ED9957FD388248462AC
+1B2610D72BF5C073ECA567E7385CC959E37CAC7E05470160FFA5A9F63B8E9B082937E911586EA165
+374938F492EDF28CE6020953A5B5CCEC7737F9D9CC8538C4339567AAED3794ABA3B9F4EAE65466E8
+E326F6C399B36355935FBDCB9972F10B13494DC25097FCEC5A6398F275C8C151558E74C5175F7BAF
+4155E36B733F75CF9D5C5979B0764F14D8306E06BA24BF791141E404C69F3F8FCCD91B9C58C2C671
+AAE7D4F9E5D6414E46ED633A5F78AA5BF04E652246A066EAD9E582B181CC196EA2D3CFAA383B5D0E
+4CAC9336E119C08CC6AC55CBFBAE147C623B400453BBF447E96DE036FC025624384359EED7C7D5F7
+858DC0521377CF647A157FC3F188DE5EEF094DBA125510FDE34C570D7BE76AB5DF0A28BF45DDAADB
+EA7EEEDB936332DFE93081E0AFD3FDD46BED08D6914B2EFCFDC41662A33B90B03D76D34F48D30FC6
+BBBB600E90E6AC7243FDF026762A44B4D6E4ECBEF48C9D7B696AF29EEE063E557D8FCF0F09E0136F
+45D17E608DA36E59F2AECF8493F8D62536119B5F7E1554DFE3F6E8D7C9A2C6F557D18B4AF92C9F6E
+050975C3B5C54F9B5F4E39D600B6FA2CD6DE203A174028CBB2A201AF126D1013C229BB82CFD013ED
+199D01E51EE2780FE896E01C63C655087A3E61A7F1029FA5E97EA1872F1B45F22282DDC317E17926
+7368CB52DA9444F6055A3C653659CAD2A1D8712BC2B1B32C1DC6906D957FB88524EE066156ED6BDE
+B8D832F9338F9912E29A250A8C4674E667C1C278B677AEC9972BE83CBA3FB779893FCB8F81A323AC
+91474BA2A2334A07BB5628E905C518E634F6761A3289056F83D5DD7B3890987EEE1C18FB2D379CC1
+905F1AEB3B3D2AD578F0D6C845D2D40C4BCEE3F71C90E68E5417BB8CDDD878D83BA80AD8485F4067
+E5C3CABF28AB56CBB219C0AAB8FFC6C7E192BEC8CBCA1459AE4450AFCC81B9548F40CE2622E5A7C2
+81F74DCC02DAD57EFD92D072318DDF05BF42F1EA8163071E23949B0179CF7DE64677CA99B23CB926
+B3E294194EC13397EA1DC9A5E1CDCD828156CD71F81B64167D4FB01E6002713BD8AC6F82B20CD369
+9C6CA4704DC5C65A2D66EB155B7AF1C9BB46469416FB49C1C7E17A30A5F045271D7DF3FFF2F42C6B
+470701C381E3456A500C6BB3D0E47B4D91C5F34B49BB6272F1F8698B307D89EDA3A1565DAD1C0864
+627560CF922DCF5B34C67860352390B282F95394AA2CDE0E97CE3ED39546A6AF1C52BFCF81A29BE8
+2C47C99E8050E4889E4575B75F39E662F2DB7420673797E2ED3D67CDA7AE2C15D0A0A794D57D168E
+BE13214E89E0209AB2C0EB7784E9491AEFA3C02D0DF3AE5365A0FC4AE023CAB528162C7A1B173664
+9DFADDACA8DA5FA18B7D6489E4229E9E24D38A620464A744A5C60F6F9D334B908706B738AED18669
+8A8B278341FA4D65A0A88680BA484694921512F7DE93337FC1C02BBE6E64AF2DAD07603279D87329
+1D1F4D39C1DD6D89C90F65240F4808F6F1115CA55B88E242565E59F3BBF1F10EC7B88872E9AE61D4
+4CAE185463EDFAF7DF63DE4D2207D307AFB61501892965170D2945846FCF5973A1D458607F50C15E
+06E5BEC715E0C156259AAA6C735593E5564F65F443B78CC7512EC35A56F126DF9D30974A40872E42
+65E1AE5FD483CFCBBBA26DEE426CDC4721F19C3FDA86ED7AD4FA1120F63669BEFE7002B128CEAFD8
+C63E8AC09943B6CBDFB3D2476A026C00A8FF81B1F651B97F310C82ABA5F388CC1DB5AFCFF5996D52
+52A6A42FA4D972E41EE56088F78CB966F9051171C472C774879AECFFF08BFD9CEA40D7C298922ACE
+64F28C14E0B81F4DCADE81D71DE3983D87D905192EF13CEE71B2D3FF1A88AEC671EC318917DF98A3
+C9054E372D22A3CEC82FCC217F47319A40900312F6E32B536B9E7A7FA0837EC65CCDB5FB0D414371
+17596CB39D9382262DE6E65379D3A9709B2CFBABF5FC5D5B352425F06F88CD31012A2A4147B112F0
+C1C0ACCC808CD625E0228EEF66661F70AF96D3DCFECD402700E4F6522AC9A856DA466D55C84F65BE
+2810A1565163872D62EB81333A698ED7B68352CACCA2D7AD38AB55C19E4F5582F75818302F5FDADF
+1DCED09D94872F2D48FB636C8E38C7563C72C771A08C6B1F041F3532BDB39006C89A33C09BE1E3E6
+03622D891F98010BF1DE5355F557A1E09448D486ADEF565705277B31B8BF2B86761E32631E3435B6
+88B79D566F1747BA456DDB43CD239FB47FF7B425EAA4C657C8EEC26EE01AED07CF916E77D53634C1
+37AEEA009C6B515B6342C54BE2C7B95955B1A9DA277A0ABCDA2346E88018C726F481F71D6011AA42
+F8852F2E5749518FE3B3AB668213FE1A05C10A1C53953D75312631D6BBBA01D418199DFEFF8CF548
+6109B099FE8E2F606165FE30F532C03567785D5362AA873C9D3EECEB20F1945D55F49B0CCAC84967
+59FCC7292E46938943C262D78F3212D3F9D0F7B103157F423D71B1ED54B2A603F4C269029918F238
+EC6828FFCEC66009DB9C9E59534EABB183F31D7AD4C57B1BDF0BD2CE5A421882BC10CC1BCE6A970E
+2B586BB221567CCA483989DD0B8DEC424C1D1FF042DCB7834423CF244EDA28D2D969B17440CAEAF0
+24A6119DB010CE366821AFA424D1B8299609C04148275AE6E5257A7ACB3C766C747CE99CBA2D703C
+F19B7CF301B634D8B613DDC4AFE4633A4D77BFF8E00CFB5E289EBBCAC90A24307E7941EC1685CBAE
+400CADD876FCEF7F6557EEE167D2035A05120293527700DC510B038A496BE1D5CBAEF24ED39F7421
+1A93AADF22214ED606A80582485AFE358E3A46D0671148998A3B3BE209467009B43400870359D418
+9A8CEB4D5866AB52D16D9CEB1EAB71C07E6CAA34B70E3096BF7604C22C40D5FBFEEA616DA3BABD59
+DCDB97D883FC8742B8267A16A99B7953225F7144568D566E64542C92E538AC140C851E5D295528EB
+7CBB49909B1CAF6409C9BCCEB325468FA0B5F7CB2987382616B477CCFE4F4AC79E4A6F7165363543
+F04DE5B6F6E1C2E910CDC3CDD6C4C92737198F892337DCB6647BD226C820AC99C65D8E7772BBB74F
+E65DCAA8A22C33BC168BF48E40A82700A3A7668C5A9A71E397ACDFEE7D556C5C19467B7AA69C260B
+727407AC837BDB7D67DEC055C1F45D8BAC61048C45BC9FB3CEFE7549EAA2992D2EDC126FF7A05EAE
+58613332A2BC1465B2BC0429162B907D65F793D236EDDD8D35405866D71B25F62DC4A7E06D4DEE82
+840ACCAABC0774F8A63E9C0F7FC980B3583E7A8B01C46590E3BC04EBA565C2EA94F057D964A78A90
+EA9F52ABFD70F84E44E434BD10A42E98C794065724341F907E35D3CB257161E01C7084E3A0166D15
+CED65DA7BA87DBB2EA33D39BD99AFB93D3548358D08330E807F8552CECF63C84F805205491BA3A1A
+622E70C232FADF3BF2DCFD6F0539158D3306506F150B0518371912A25EB96163D73E9EEED42EDC84
+D688BC7F7708D9DCA348FAB4DF62E5809BD094842D0A31DBB7C4B41F94D946810C5EC10B69AABC2C
+91A59500B2E5D37F4755DDFB7AE4ABF757F4C5BCF77C7F95E6A616646456FE8F18407080BCABBFA5
+7704287AD26222DF91AB2613951E2D679472F8ADF06EA2A20205EC19972299A78BAC52114334470C
+5F5890C2F846B4C6042D73945127F2E3910ECA1C4CD7A16EFE4B4BE38A15AAA710682C3836A8CA83
+FD384970139D8B46FB0AEBB002DD224199672FFA02250FBCFA4E649E335428FC71F50F45E498419E
+DB0E970F46894A48F65580881C9C4250FCEF65C9B28699408E18B26FE6DB7F1CBDB767564E73CB59
+54C6D639CE33220C894F36E70F71C9F9AA3FE2AE0AA0E3F2E304EC5ABC661675CDE2E70519E4220A
+E26FBACBD01D5169EB844750753E6CED53E3678FDCD08AB93E10067E9C64F38B40B76D99B6CD92BD
+F4155A1EA5CC824998B59AAD06E09E5F15EBB2288D66EA71B296616734FEF2796F07FF0D8B047074
+A1111D68B99C2B70FC56E74A51B062F4998ACC85B1943C9477E436E5CD7AB18DBC898D21BB93475A
+623BDDA71D7B895BA2D4C10F4B90BF335126F4FD57D73AFA50170F6B3C364922E551D40E35DA75FA
+891762FA23401D39260F2E92C7807C746F13BB35CEF9DBF2E76E66A72FEFF095DA482A4DE8A42091
+7065736CF4DE904FB52E649A32255E2030A7B31B686353492F31C064A3C4B0448C4BFD44B8E15384
+FD809B8761EE26A7DFA1758D57CE4F0BC376EB2B3833534B15A83436BA553955ACB5A7A66796AC5B
+92DB5388BC53EFA27508B08E82821E5CF669BCE52BB860780F749B4F38ACDF5FF12726BF3EC2743F
+01014CDE96FE6B4C40A034E9EAFCA2A35CCC776C2669E6AD138070A40F48ED79136D7FF57E993E09
+B81C543FBADD350FF5B5F7A46F060F88E30FE2D8233832D18B6C323EE017EBC1DF5C838321CDC8A8
+4CABCAB20B60A1A3AA028F36EA6E87C850AF8AF7CD50AA6359038BFA8818821D02CEE8F51DAB8C05
+F7AE9797814D97F3DB8CCDDE45B21DBB15CEE292FAA534A5F317B357F4091F3DA357325B8B9F5EDB
+45865415973C143E5E5BAA483FBF2D06CDD4246675EC58B84C6AE65CA743117FF00F229243772561
+31A7F2BA26A9115AFD96C18216CFDF41B7220ED0CB3FCC26C36380007B382A02AEAE428887DC8BE5
+FDD630AC57EE3DC156C7B8B29E687F24442E35CE10BA4087295A641F7139C831F7CCDA6CCEB5DAFE
+537CC1A97C5A337D3C48A6AE947F58A30DC08CC7B58DBBB4737AD52783C573FC1E9408F55495A80E
+7FDA61F0B9C4F090158F1A416249EBBA936C27BEFDEF19D1BFB839EB70576A010706D8B95657B218
+9C2AE04C11EF9E57FE09880273761FB4302C388BD608FA0C7F00F033C9C00F4E3D5CE2D903E0DA52
+E69C7745EE9FA75E2AD93DC6CB5CCFCD3782A699B807AFC36AD1F62B05856D5DFD6F88831B90EB3D
+CD523582A49732E3FD7253126D39E8AFB8458B5F7AD7F94A8DAC13365F433C857AF4A42C0A08C4DB
+9887C4957259ED22D13CFDF5995DA957EA5A0F620B0214FBFE08AB6D552DBF048D62CEF6EFF12F15
+3511ECA7833E0E3E95F85E6AC0F95438AC4C126E1F1ECF336ED31CCA7EB216D279877123FD9FCD8F
+B5E52B587CFFC4428456DDCA816819A8A4A211D8F1629E5D42BA4C5C356E580C8A22C61D987552FA
+A97893816DA73D423686E4EBD44375C257F031318865A20F22115E72BF1EB9F93AAA169C140A33A0
+6C35BD4526A38BE79CF40AD1EFA10411E8F3300A8A8B97AB140EE6734E1BEE6C8EE443D698D34159
+97649C6F10F20ACD80236422E215E146D744A262DA3FC88DC0D86FF66512F49D3F957D3C5CFFEB42
+4823509F33F155057A4C6F37B52F4667767BA94F6B8B62856B553F307E5D230C44CBFDC9A97A45B1
+39FFB2F2565EB0E22026972FAD0FB7B9576FB6F368B61979943A398773600E7EE1DFEFBF26D45D40
+BDA66EBB96A56EE9CAE0B2420C5DD83E24DBA9FF885BB844BF3D2BF93B07325DFF60C0CB5FDCCA0A
+C8FB5A2E119D5AF26E53AB8E3B428481C2871DDA26EF0B621CD8572B3C664BC7AAC01A1D05B98F79
+1A7080D294BE81099BDA7982432F3DFF4775C44D23F4F1B2E0162B61A8B2CB5EE8564BF98E2ED403
+2219085FE6194C19DAC98A421826CAED7F1AB1477AB327506010217283894235D7DBFC1153D5ECC4
+8AA7293F19592B4D7E95FE55151889BCD1D7FA7DC2370D2DFE11D7E4EA34B5C7A8E73BD3A348FD38
+9EF45B6167FB90BA44C23E912F9A4F2FC0427ED070592F7110183BFDB2C400393BA7569058227926
+351F07FED4F33633BA03A72AA2DC6B598E49B96021DD868DAD0F352E5722FB714F667C15C68D49C0
+3D822D82677EDFE86FE9668E537DA284068C9B0AED83074C92A5B939296D505B837E6A9DDAB1AEAB
+7455A08A114C2222B339284674B74BF4CA9EE0C020BF2A148B439C71C6BE51A94CB64FBE4A7EB295
+5A455047CF5CB348B062ED4F6471CBC3E9ADD9BE9B96879AC7BC71BCE02FD02F17C6063985A5E898
+3D205AA1489DA13C408990ABA1C54F2F501AA172F530480D789C848118C0A74EF98D5F607A067BAF
+F6030D887AC6A6497F9A0B38F9705F328AAD4BFBB634F739386177B07F22D5771282444E5EE17335
+B4D0EC86117C697E79A5F4F65FDC08E4904DAEDAB20067EAE2448FD4301849E456D085F392DD1316
+7ADF75CCFDB723E2904A9C0C976D6B84DDEF9D92B0E15FB246C3ECC2D0BF314CFB957757B3A3E8E5
+801F520644E4601D291DA0F7507C06F3B9BB36FC1C70EAA444E14E56C0CFF06C7F853DF36DA9D8B6
+AF2544B853DFFF535A7E5C6FC145250CDDA229956019659D0D253A19A7B51A4E538BDC01F74D7704
+9949C2C97C7EC6392C2E61CCC0992B66DAF1AB08551063E53180D2A67DE496716CCBAA45462D9F91
+B66A22545962DDAB120511FF08627131B95E5DEEB8B4DD9643E7B2AF65C0FDCE11F5F1E8DD468DA1
+8D41C8C4F00EA73836F4F70EC50FC3EC6D358C0658A4261C6D15A582A2C7C994E7882E661855B352
+014576858A265FFBC425160669CE159D07EDAC04D060B44E5800A7AAE8E339C29B929AA81D2F515C
+46229D2080D5917AB20AB6B34FDCA8E4AF64ED660A3173786FB1A1D005D575C2A5187D3F7CFDC94C
+CC44A38C5CD523E9DA726D8EFA6DA7B6131DFF3435FEE838B2C7D6B97934295F06202D307FF78D90
+6699CB9C5BBB10D1D4DEA5FDA5BFB094E704607083B646D37F5DA1FC7AD21B813F44D8C1AFEAB666
+55AAA19703BEA2E77DF3BF350E17C74B3447A452235919452B5175570A006C7680AC05E8950A62E1
+1D7E3ACA35A397D1E19630D094A86807593C97F4C484E4E06BCFF708B6DCA972E3A0009E1CAC0EA4
+141530F5C1B8AEF5E1B933F37FDDBC4BE22B74FE346D1A3F5FEC0818F8E61765568A2AC04713E828
+F98C449D9A1CCE52D10D61DD8BFD084C8D099A75D89DEA64D5A7CC68BD5B0593D97953DADA976383
+F5015915618AEC56D71D1DCD55B89736395C609B315A3F1E1255432FDBD37F38CC43C354FB4B7C44
+F1A7318B0B7E99C3C08C33B953727B6A6328051783A0A33E3CD9E498346A3CA6A77B517096EDD52A
+E443B87643A646C3A7BB97F742888D33F9B3127E61942F4103C1DBDCD8EAC8F9E259773066736CA6
+53CE57E8822651261D847C131321BB9D6626A1AC50D047C0BA47B411DF2A995545BD68EC0287CC9B
+31D5DDCA8755EBEB10ACCB3903AB0FD5788E984220443B8459E7C078DA4289F1350905881AD6DFDE
+C47302B0ACB0D4AF8CAED02B4B70DF3CF8FEC118F0FC2D3DDE3E494CD160E676E300BC464BD4400D
+B50EE43B314E0517037BF971ACD7CD327CB2134893B8A0410E68DDC518F5DEC966C7884CF5FDFE74
+723177F20DEDC039D879056CAAB4BF045062D3904F615C5CFE109AC7A35599C94024B41019B9AFD4
+04A80ACAA4837929F5C9317680A13D157A03B59A5588DF79D2E113F5F51021D6F6F90E8BBBA2C252
+FD10651BE80BAFD59C53A3367BA3C28DB6EB9DABF1EA99F47B503F627E15DCF3FD645FC52C5D5D0F
+2F07DB4C25C0D1E1C00146E1C4D973E613CCDBD3F9450CC0F5343D79F05E9492E86A1BB889ADF405
+03BD7F3E7543436859184A5B20BD8A172F350D846B7570803990ADAA48D4B9155A2B4C4BFBEF1E1A
+065C08E03928559735BDD442FF1E83E1FA20A5DA57D8BDB2FF5427C034CF0128AF111E6E73099E04
+6E0C240E80A73D7BE72B87834E45898D475521CA3306707631F5C6136199F354632D1A085F12A1C7
+C473868B62E534D15F5484323E63D0574196A19EF175214EB35A90873EFCFB92D6CF68761D45E37E
+AA61E1A1979A82009507CA193E44B36A806486665CEDBCF387053ACEAB979BD35D30978FC7659ABB
+E844F4ECAB3303318ECE80777A5FA5A9DD91B3D06804C4B4E9B4EFCF07EB89866D0DD8CA390CFD15
+98651417114D78776B1A1D36B4BA17746D6BE7FC123D473EF1EFED1C3BC1D555F914536869FD5B0C
+35F9C83F65B0E6BF7A627B9202D787D72C600DDB6BCCE613D88492E13CA0AAAB196E8A49928C62CE
+A4FFE2D0208EDA334ACF47F20BD793124D2C5546C03F4A364369A76A0425262F9D9118AF54E37D32
+E33AB25DD533A49DF5FBF1BAF4CEAC2D9D378CDCD13B00FDA432D9042F623DA41AFB80699B5538A2
+5403B0B3EABEC9E8EFCF42FEF3EA9F91766902CD206B0787C187D5370B60AD6DCD002DE2DE8DCDC0
+B4719A797C5E26BAA67665016DA0D967FA1346F9588AEDA174CA001B31213617FE19EA218EC23597
+79D979E2663166489C06993230B0D07973A117C4E3F4A4C93CF8428248DD5389414D679C69644142
+67C7FEA17E35B0CEE456667A9B1875C81B2302BDDEA2818D6019FC1622A82051F60584ABC904CD91
+8676305DC03FFBCC64FDDAC8D8AA9CE2EA00D6C97BC63C8A617DEDFC0E40775649438E9F61AFD179
+5E3B20560B01BE5E0983F136CF48AB206954E41DEE0D9DDD953DFD01CAEB569151D6BC0DFEF29D70
+FAE3E198E7EDD8922C0E0BCB8BCCF1C016142C1A8B337AFA7A05A9D7534B184BF3BF827F371E9BD1
+9A71244ECA1BA73D484CD2FAD54DB2F0EEFBD54B536EBCB5094E6BC2F5B2AAE41F05B4B311115876
+ED42C34F8E643B53372E3F6350DB8A38445822EA9A33E27FB0CC42CEDCD1FE2FDF723FC47C996EE3
+56C402112F24D0AF899B2D00BEA1CFD427998BD22B2A09046D6737814448ACFB10D387547D7009FB
+384AF0562C85694C071584236D0F1F3D3FCD0CFB38B77C81889061E668BA7AB37AA60F58A3967DE2
+6F939B79CBF10A9DCC42852561D8D6754F1B660D216AAB1E133FBAA321C56E2584BE5C9BAE20CCF0
+0E8DBE6D9C2FCEBEBAD945C3C04101D2387351F132628786F6D9D4CAB83419288D31F9BC600D9664
+12E6AA457CE6CAD26A4C0671097B98C2384C81DD8B9A3222D4F4BBDA7017895C3EDC26662779AEE7
+40D9D7E24185FB821970B0A3A94041A69E4805EC88EE1EE521981536F2844FB8F5EF645F67D42CE5
+148E2DDE43AD5AEF200EDB3A2C7866C98458A92666E5F9E070178BCC39F65A893102A10564AF4E8C
+AAA5075D2F8CD7FAB0401C03AF299EA3515CC93066744EB5AF7CF0ED06675BF049A6E3C211A89E16
+DE5BF0445A7CCA6EE8EB0347454950485D884606651E5887FE8B24323E2AA16DE22FC1FC8C4F06A8
+2A1FDE5758976024068197E1F4506E4D3D8A16D40461A4586338B374A592DC60334402F76388AD6A
+457DC3F54E6169CF7AE3959676E966A45609621055EC3AF80E182633300A4418E34A66DDFA6B569E
+5A13C9115B5FD3EC1CEBE50FBA247F60803AA83976F00117536342DC3D9890C49B2AC701D370E43A
+955118967827760F7091469C5406F08F18D7E3548148CF0E312B1DC71DF67A5E7A1656CF2F47F3AF
+F3DD50FFC2FCDAB7177285B29C17CA43019F62AC6FBA52D1493ED7C427526470ACC8389BAE827759
+4958908F517B2863B83292EB5AB3F57FFFB08393CA610FB1FE905D88A0A16AC395E2A2A6DD033D6A
+0D68992F830B2E1B95FE357BF672716E88FFB92FFC3D62945D1EAD22BC68C51EE0E10A43011DB94C
+44685A5C4576F6EF44CBFB45F2A4BF110A01657DB51FD499767E78058199B31DFD60813F1A344F86
+289F9378231D5B151C92385E3650B4FEB1DC91018EAB8474CBF69FDC1496A4D078D2C351C8196451
+247A9DCF8117E5B637371D8E22E248C64D999015C3FD2311E9950B8EE0922FBDD3D7BFF766BFE9E7
+CE0BE12F318FF2A7B5A9C6D00A54401609304ED2C55F5C1EAC3D4B38355BBD85D66D61636FA6E30C
+2E82829376BEC979A6FEEE040E452359768ECF90CC539A546F17AE906C76F14F86FF697797322B05
+1EB311A759FE260C1EEE5DACF383816AAF1294CFFA7BF87A4D9BC595EE8F2C2F86FEEE11AD959D86
+F22FDAF4CEC098942A57E57813A0FA99239E994FFF353C1E781D666B8928CFC648FCF0869FC68468
+BDBDA7D280DFAB8B0B3A4CA35B074B686DE8D372C61FB32305169A1A9912F6541DA16CD6316A6EA4
+51524757BE5CF6E820011BE3859FB8B8578C100FF029680E05F0E0BF11D33FE19460C85EA5E4C0EF
+28E29407C8AE6BE01CFA0D5022BF9FB01416FFF722A784DFC8FCE330EC95737A854471D334FDC58F
+AB42867A7B62836A8B56466E9A6C1247D46EBAFFB905CD4321970F59FB8D6FF65FDDD34BF913AD32
+2E68455C5FF2D23C1A5EAE687F259BC982B6A384D35440F7C693CF50B9ECAC0B5578CAEE87588B56
+2EB6B7F42034C9F2E545EC866316552354EB3728C7D26527ED75174EAF635E048B08DC5D23E88981
+070AD5641A652F2344956E9CF4C16E652A99F4A644D1787D6D36537489DA4D74E61B2FC4DFDF1D1D
+9D58F9C26C5EB63200526AFD168AC57D5611ADE4D4A382FC28BB60F9E7D626A6C67AFBCCD1183C5E
+3CF2EF210D0BF5CFA7BB10FA3887BDD4CD96EEEAA8F9219AA2F10ABC0A960C3B57C0EC0313AE10CC
+FF1F522124CFC8D2D49BFBB0C193EAFFC5B48FB3FF30B21CB76F0A4C0F1377C9223145BB0468A5D7
+1B9BC25873EA12E1C60334571C67385C00D0B570D3FFC6C7FF0DE62C183C76AEEB12DFFEE1459E0F
+C818C621B8D12FA1357E2B55D48935D70BF140B4CFFE8813DEFD479350B20DC2EB1D3CBB1A2D3DC6
+EE975D58C89D61FC50E6A0197DA9A586B72255023DE47DABEFB11E8AA02414C2FF6258A281219B9D
+DDFE41BA7D7977D0D6F18224FE22F7D4E9355FDB35BF7ED3418F4F68D093AC48F7D8FE4194FEB6C8
+0B9DC1F74E023C604DEA27089F98C3973FF9F4AD7BF7BAE601DB89B08D5D8139B95EDCF6C885FFA8
+B3E4B0477E7040225733826BACFD1EC4A0DD72DC41734856AB9FB700DF83CA2CE812913BD142D84C
+5C83C0B2583768198AF9E885F2BA74877A414233207234AA5F18840557CA11682AABDE8993533887
+7C6D404BDE4153C9827EB16D66C1D73A8143C8A2D3604FF72CE579FAA3C5224BAC48EA83BA848429
+9472007DE96466B5B29ACC7C03B05DCAA38A48BFF9F214DE43146AE4E04FA705421917F99BC54533
+F0EBC01849E396216B9F0794E6F6C6B61B52EF1B1950C0FB609895C3C55FF574163FC8B6B09E66AB
+AED1810E698FF37CC1F926B2CDA3B48C7D77790EBD2D514B6F385D397F713EC3AD3954EA9C846158
+6031D369E8B99E53408A79D64C34EB5A56DE8A67DE91837960E98A66FC04DFA0EBDE21DB003234BB
+78665B039D0A469A0221BD541AF7149A2A659C300132C14581EF766FFFBECBA8B58A5EB3F95446DE
+F49AF863A8113D17B2E7E6ECDEAFC3834D4DF900E3475596E86FBB4E2974C090DB4AD61A737D611D
+92B4535AC291C56AD8B1C031D2F9B505BB77517B737D70AB3723DB52AE2ACCD5DD2F617423ED3CC3
+9CA882EF41757BF7151806A9B8B0F312808863E3673FB54DE939B35CDECA7FBC4DC3BDF5A5F47D35
+E345916C39366C8B4F439CE1C6F1835C320BD1E67375B03B5DE18C93256F251761A4C8CEC01019C0
+68E34447BCC503B9571FE8000627A6B3DAD5854CBC0A2D69E5A8F46BC78F6A7B1422334EC7A98ABE
+FE9B83E01DCF3C6C9273B346F3240EA225AE4A4083CC7B0EA141A0773FDE940768358EB4B13D82AA
+304A1386D450C1C0C6A7D5A8FD2BD313F78F85248B5196241E31E5595F3BC01F37700A2DD3D4A0EE
+2DD01A36569CD507130E8F5B1E96CB560BB7DA15560CCADF3B2C9804A11D9E8055C9EC70E48C1D21
+3EB756A1376F2EDCB7189D78CD3D6CA5865537EEC31C17D801605EFD860B0B629472690588D02575
+02C6F7A75B9A1C1B397781329832CF3EC43C09F1559CD562C48FA9500295CD3B0A790DD3FCD4684A
+7C7AC49AC9BFFF36B39A9FB148BC28D37907433943CBBF0CBDAB46D3EA86DC8F81C859C52D15302B
+94A9B51C199B7104DEEC9D769C2634CECF8B700CE9C04152CC59C9326BDACBEC4312DEED92DD087A
+1C4840868D9F97CAC046581F762F75E8D24D6445370A3F1E0AE74A6478D9DAC37E7FA5BEBEC0A1E0
+81AF89C1BBF7F51E3E2E22C8C405E8671BA85F1BF0DF79A465DAC7EC07F731E00632E017D190A99D
+83E27E5C2E63D7DABBA23B2E88334C63721AC5A4CBC5D45F4C177259F34C2EADE01FA008AF65EBC6
+01D8DD16436D86AA94C99F3CC0A2F87134E73BF22F108B825A8963B49C6C685474AFE4A542C8641D
+C0375D7EFE9AC1168D9700459BE52D0DA399023E141969F25C0DAC4668534B6647EC85454BE945E8
+26B26DE6E3C4584B97A38E2B40A0D23481BCA78084FE80E00A71A790BF31DF468A435ECC88E60A57
+860BBCA3D65930186E9917CBD209C230E8F8255A7ABC7D3F043AE4D7AD63D9980BEDF062B7D5C298
+C40225B6D03F29A0339E0FCA02138E526F06B9EF47F5E7A8068A846CFDE2BFDEBD24F5A73A66C079
+18662AEC80B43246284FA4E2EE0D9AAB172B1E59A6CC46B801149D8C0DF6DEC9A55D8E1B0EFD9D30
+2FF618075944CCCB6831D336B11617107B0530D09885E5CA11A5F1FCC8D69D603DA16BEA51116D42
+CAB1AA1E4D7B9B4D79993F2BFE53EAC904FEB70B2D330A89780EAC10D12CC0C35B8399F218AC2976
+E57A26BAD20CE2FA2AE2363D3FD2A8A971747556F2959DA74A8963C20B504711AE1CB0D0C02457FF
+2E9BF696B159AF031DD5155F21C0F5549B0471A3C5DC8918B675CEBCB23E29322B959ABC05283A70
+2E878DE8EF25EA760F3C5C7B7B49D398283DE2ED837FD59F7C22D62C58FE4448B1049FDEBFC8787E
+67D7DAFE9774979BB3802254DA59BCC0219F98C219F84D995CA768B8B5D9D4A32525DFECE003675E
+E4BD5D8DFFC11025AF2B468F9207B5B2B42349B98232BAC0759758C1F4A283405815BD7145C93FA0
+8F3ED2826655053A3C2559073D8ACD199DEA2C5BA5F616A2E48548B4370EC73493BA07E197165DCA
+774438B0766867819C1154D1959FE6E01E6312E0AB91FC2E2BD240FC8652A2D456A1DE7F34EF372A
+53794D4C4E050BF3CA5B7BD2F1B8DE93B4C8002485CB219AD2D029739FD3C81CC6E78EDF38723576
+1A57143EEDE5CC887F282FECD261F6A25D0A7E154ECDF5DC38E426811BE86AAA458577E5E0C5F0F7
+5AAFA9C41E5D1DC9D91ECD79B514F8CDF7A5F1A189470D35FDF4F9B8788879CCBD91B427822ED658
+389E981E0EE5F7FB87692A3E3E931DF8A1D1573E3B0166204240B7080089A09EF7487C9AEE2D665F
+5A82F94C877FB5B0DC531CEBF1E71C6592CEA2401E4B5122E5091DF03D203DF979B9A6EFBA12E2F6
+B422FDF15D49AC0914D372D21E871DE65CBECD105FD4A3E4714B9CCA5C6803FA39DBB015EA8A88BE
+7913502E562E5B170B87BFC8572DC9DF49AD63694311EF1334444BDF0B4CA3245271C1F7A4D7FAF1
+703E3AA0E1EA8D5C6E821B28707EE0C9B4F22F23796FE87356C58AE2CADC191F4C58E1FB58DA03B4
+5A25AC95DBAE13A293474217BDB214742B9D9D6AF35F70FED2891942EACE3E625E55FFB820543FBB
+250A062D3D395BC0F219ECFE0D76686AC148BC41476A887BC494DDBD396BE200FD3E03CFA12EC9AF
+6B934A283C42AA05589AA6B4A8D16946BB51F50419CABECEAEC5AEF9085C9989289E9B46BAFB6FB2
+782D84DE2B068F91A9744AAB237CEB1BA513E57E4C307108E993C972A3E0A898D5A8D27833155031
+FDB98863C3BE7FEF3004CBAA5CB60A1F2E3EB4D7290FF5FAFA088B1CECCB6CF51A58DAAD998F0839
+6CDFD68F5ABC9C1CCB8F6514107773C69C26873E889D1F79D10E866910E4684186FCD71C965ADF62
+39BA3418B313A27AD632300969B6F284519366ED85E7CD968D64823F8C59B5911A72D0A20EB72B60
+3A61E36F52F256FFCDF706B4560B4DFA5D918FBC530D83A4B3C01BDD3CB4572E24242D141BF9E775
+36693A0407D002E09CDA5B195BF1CCF430AE9824C07928A050D0B460F2704BE8F9E647A4884C4567
+0A81EACF7CC038643EB0FF18A376FF6F32B6FE4F197273327FBBDEC6443A299CAD4B26F7778A99F6
+5A11BDE047153E764039EDB251936AA43DEE50DDFDF8856519056AAFC4C5AE6F2051AF0579A9ACD4
+1D00775D7DBE70022CC263DCA5E0A25B9C7C4F5C418587666B2FE24816B1E0EC92F9074F1403BB83
+AFC3F1D52CA79C387BDEF864366E34C90BE52F7AA09935373A07E4E026224E76F9EC3CB9E7EDE50D
+EFDA48248D61F3CEC880A3B8843306375D9711E58645F3625BDB8E87052DA67F9794EF4AF8DB0BCF
+E00677C3A26907DC651BC838C40EC39E2B5A5DC0DBD345944A6C32226089D63C52490FA10B215AE7
+03CFB663EB8A47793B84CE7364DA1C4E7FCE32DFEF09490121222774915BA59C78C2275F829D15CF
+4D8686B095C38C731B83D48738C25F40B8ADD487C350A2EBE846C3916AE384CB1050F9F5DFE09FCB
+D9129C6270FD86D55A459618FDFA4F907E6B4746196BB717865AB378414029017551161A52E9D24B
+E4F7EED553A927933D4ABC8F25DF607779A717909CB4D810DE8F5762581900E224E4B91598149BA4
+71CF8068ABE8744356B261600BFCC57FB8BE45036CF6571D9B2A95304933BD4F17215F8EF53F8E08
+1AF61FA7F9583C34EB5655CB0ECB82246959F09091F36989EBDD646BEDCA614B9A61AB7696B3FF18
+1058A150FA6EC1BE2EBC7F64357A3FF2A2B0491D2F4E0B970DE5B7788B467CA678039B5EF55C88A3
+84578D427FD2CB16C87B0BF0A3D37CE8ED43E0F049AF2436344D5F47C948C632C94A287509282561
+6C64C5D262FE5B24916FFEE982A69A6CCF888BD01D62EA591EEC51F4B7DDFAFFBEEA93FE08D736C2
+0129E345D06B10246A5F57151C198D407730713F32299638EFBDC01367E23EB59AAD42A83AB41B43
+2DB462652E29813740F4680A5D4BD47B18328FAE6BDF4200CFA4CE3773809B45E8887C9B2E423698
+9F6C48D64F5986F563D9A7538A8716082F81936AEBD0461E6F4BD470436D8B7656F0FDF89108E6DD
+02ABDEF907731D458D690BC608EA9CED09EB1E6E64C0790C7A2378201CE997FFE0317679EE1D4EE9
+F91157449323E53B4ADA8096CD628B5861BF794543A98F2FA2AB54FF0F25A13DAD43DAF9394329B9
+5AA53CA32749FECB0B2BC035DD1EBD53FF9FB5AD8BCE06CD89E5568091C1CC314CFB1D9821D7F9AC
+7C55F55E0A16E39A87D43148201B928F3C42B110FC056189DEF183745F3B637441DE8BD4C3C7EF12
+F4258E306B2877ADAEC63441010750DB4E6269A4C78A0AC01BB3603C386651FE814031CB5D8C1F14
+9EEAFF652A53E57BBD4C8C0CE36A84A319A53BC1E5FD3F1ED1EE72F4C1A9BF264B594062FCAFB22C
+C1FDE3F2E3D3C17DD3F7FE0E15EBD812D550227C06D01127385374A11438ABD50048E17255FCD2BB
+85122A6FB9B7DA9D5E9DE8A747FAE0DA45A1FCEFE92B9E70A5B2CAC668D4D07527A5C1403267D823
+048BE671F725CFC7474B44FC5AAA348420B2D7C23C6CA066666FD6F2208E329878D90CEF1C2E77ED
+22D3BEBB9D547810B189F08920A27E7107F208591A84D463CE2576C70C3DFE6643E4EA93F4E1DAEB
+41D46F0E2F56FC10C69AD5034FC9859D31CF27A3A1EE256C93111F81C11ACF1FC0CE20B90BAC9AA3
+27A5C85A7985B951519FD4B03C40BE637162AF41B2FDA68F0D1E9B7602FE2659D3D75955C579AC51
+DF6A552EB9581AC3F712F083F19B52A6C4F560F36C59CEEB0C996AAF1728A2AA45DCAD79BD7B23AB
+388D5B0B64A2B95154B6259B730B0F4A72C8C7F7CC93C7D64D9D8810D1F63FF8ABD4DB89824E2D26
+4FDEE916C41E299211DB1A53256E1DB5CDD04862F034D9404B73183A99D3D13D642A663F129B6D16
+7095BEB4EAEFD03DF2FF2F0B6B594C1EE90FDB203DA89FACEE23F1BA3901FECC75FE1811BD701259
+343011262B6A0A9707AAA6316BC3C17F787BB80AC8DA5AAC942D90F80C5A3BB59E47EC767244AA95
+C63E50BF809998957936D3BF6ABC24B0A397258F9EB4DC8F65692CB023D9091FB180C69498CD0C08
+BBEBADC84A7E0016E8F8BEA325D924EB0DF82E75D2CC2CCBF039B11934363D4332C5FBC5EC556BE8
+5EE4E707CC2753CCC43D2ED50558E51A104221C9323CDCB0199B7B83454DE3FDC810D0F362C0299F
+5DD981B31D8E3DDA284FEF9DC8F9C8DE138D3065437A7FE8C30572AD06D62E8527AD37AE39AAB0B2
+25F76A25F6C6505241ED73BA494CF923E919F688DDEBF193E188F8C4C154F21631080763B4D091E8
+AD1D2FD6649E0CD9360E8D1A67A5B5FAFC67547CA31C95A5EA8D4EB5D68B9F6D6532DB9B54584735
+9558542A2AE58C09F3BD2918EFBE1699E9C8F2C2A11EA4D224C726D2ACD4A8D8ABAEDC6588CF2AE5
+66528B94F55B823A2A1F7BE19000F3E7579D094E047075DF18C8C868760295533B26EB3ED90635B1
+29C17ACA679C3E88B06998CE5A7A2544B700229F5A6A504BD3E45B276471959C8A3F81917A534287
+39B5EF9E3D463B3BA7318448E2A3E79520D2D245A2A72F31FF7070B6E4624E3A5E216BD103640C8D
+F387E49D732529C611F8B971073F17EBD2F6EB18F9B74A67E1997926DF178D4C9EDED435B9682F1A
+279C81BB9F60DAFE125845A2FF3B02979E5481C78A45C479BEFB9FEF3CE2BA9BC46C77B50B03E48D
+A6D17B76F06F3AD118371ADC69E178C52B5FB4B261C9311874ED07DD6D5B3226A005FDD7A6D53848
+09E7063F036CDEA41619122635E835D2D74CBB6AA9B38CAA4D819C26E95115FE0DBAB4198FC5838F
+2C91B7A87B07D734C6D4F4F83444C1E90AA9BFC908A2BAC4B3DEF9157AFCA5248F2DA31CA87BD363
+AC25E9E77F741D4B2C6E02F04987A6F49D30E9038CEFC41BA172DD675AED8B392164411144E5B738
+F3210B0E66B17A13CB9631C33D44484E792A7C082DD0A5382F34C5637653261B1EB6D2035B08B4D9
+1FA9AB770CAF40A103629511F7B43F2743D7E583433DECFB19C21FD4FD0AFCC22A4119E77C87BFE6
+FE50068B22479015BE5A9F06BEAB4D37412E062A45E0CBCD7BB39FEE747E96306F79FC4F2E8942DF
+5D9DA0E55AACCDA547DA19D30B8404FA121298B44C9CCE198C708C69A8D6BF17591C5C50D3FC5BE6
+961F7ABA8F366DAE957A1C3730DA4A5B4F035A9274675EE3BBF0CA8CE9D8349F50CABB1C3EA4948A
+BE6F9F143592F1EA95404E6909A909168E3279A957AE1924245C356331A75E7008BEE92BEAA304BA
+40B7C3F48F74D9018B3247DF50EBD7CE541DA48ECCB1B0BE51A455C3C13C279D4D8676078C3EBE43
+08748D52C9B041D3E7244C745B1F2F742D010A9E60695F3EC4FDC1050AC082B905D6A57E8F407A3B
+472F731011A5798965B7B1A307E252FE02C8F79CEEDDEB6E165F1A94D7FFF18DDBDF79477F14E9E9
+3981ABD200FE7771B29D1D2D120EE79D28B9543818527039AC74085EAFF241B56D08220C958B5D9C
+87C0C04A14D52AFD475B542D391BC54FF33DEF8D9484AFF6873BEED32DDA4B371112B523B6CE22B4
+0D1B416B64C9370F1CDF2C548F4CCBE9E12E21C36CC3EA52DA232DCFB65F66B22B5E2EC04852510D
+5E264EE939BB67AEC4764B87062AEB7F680B40BCEE04AD45C7519EB3B6199C9E0E332661463647F2
+FB7EDF303EFEF84891CEBCF0FAC5F723A9D0476C3F8C092604C87FC69C7A90F4D64AE45A478EE8BA
+2DF50FB93F55A3546123F0B0E2C1C40C98EAAE9F0F26B8F80FFE6E6B94B7E27D2884D58B8A119662
+2DF6BE608C5569D7864BB756DF2EDD184B90812B44ED4A32D001C31383A40AEEE9743651F7950846
+15C48E402DBC01C818D477EAC0347795CB2792E9C11E8FD4A02E194EED1C919D4598FEC003B6D9A8
+A0BC7D456047A1C0579453FC1D7CB2D158D466939A23D7A7B8ABED7E2777EC7487973E73F2266D9C
+250CE30729E3C5223AD93B9AE8443B35711E446A3DC660123ED45CE1942A1A2AD0610467E081CE2C
+8B92A6C82F0B17B5D2429E99F1A6268072C6B5AAAA6EB6283A872C54D3694CD825EB2926E57DBBC7
+C1663075E687A144E4D61C225781D80FCAE1497B442342B4A3F1CD6BDB50E31791CC3928C30835FE
+F845B6BE5E2D7E3F2F5F085AA3FAEB45CAD0D76BCBB1ED859A9CEBB9F7457036F0BC3F195CB1A98C
+9C8648F6583CDBB23894BC719D68C2DBD8003B10D08C8CAA40BCE784D7BFB4EEC9EA5359AC056E57
+B8B0F2EBCB1F4CE40C87FC7861180133E0CB6CE2FC4FE690756D327A2B5AE063E3021C0C0BD420D0
+56F0B941E6B36088A55BA11D0C35FD0132D5F48E5D9673572347171B4328D4807B972831C0D74CFF
+A5638C145B89C989E6EC942148207D6DB82257585958034D9F9D4221C7C9F7013790DBD130F277E0
+BC88BB179DD09E27062379ED06F25EEA8B7FB33C35861A0034776E3813D2E9E5C10E227CC569AB36
+CB2D9DF2E7B7B44758F9DC4FFAD7A24AC7E9F47AA850C221048C3CB35A37CE8EA75632AE65FE3212
+175146FECD6334AE3D3C5F492F067F795E1E8FF386BA198CB74F0BB4DC0000DA383BC4CC3F070DE1
+7721431988D69C8B1A5AFDCCC83C22E16A87E01C6D3E79DC7AFA3DB0371B0866EFB8B6F88900472A
+FEF1C4A878243C52D4E02E82658979731C841C489A6B97E271C4C93800EC7D91F93EB9B9C659A554
+E1FCE42A5EC65AC39190EF4B66DEAF6FC0569A000A9E1495F42F706FBEA4D32EB7EF11A648910259
+6A65CF899C2F322F5679C6D123469192A9BF1A7F1F2C81C554ADB97BD19ADB746A4F81A4D5559E60
+AB94C483DBABF6CE2F28CDB412D50FF3FCFA3B3DAAACC6A83CFED910CCB3B8D2C19590AFF4D75303
+4A6CE7F4156896A13808E0DFEAC547E69D3C886691728E4A35ACD575B40D721E8FCC5385A2EB28D7
+08101DC50811529528F5CB0C009BA7E3C88468E37768FB0D83895AB54DB2DD5426562AF9D8AF304B
+F6EDA54E9C92643DF926F5C3578269750120302A37CB140A18BA56BA01108D4ACACE8FEAE640A6C6
+958EF156B588ADB0EA5F3B0F37BBA12B7BCB221C811415387B024B7076FA4403A3AD6EBB5D9C26EF
+EBDB7ADE7C60B444AB9F90EA493B658B7767AE2BE649BDBB3FE85F460F1ED137C61BD95F7CD3D8B0
+15CE45138538930AB62AA0E54B4CE1A5EC5FEC0A2B28B345B67089A4E4AE14D2E1F5A9C8848DA688
+CA298F93860649EC3AAFEF3E820D86988C8E3E5A4D4BB937791827994AA3E81D0BB3EE115EC36D5F
+B9A392D09E79AF514D11C7B3A03C9F9C13355CE79E119A19177FFDCA34704D38118A8976D1EE5AA0
+2D14FEB1414419F5E85244ADC5C0A765A522EEF36170064BB19FEE3B5F7B441E4DB967DAE0BAC2C4
+8FC6A836E0EF5A69F073BEE1699F55E9C757EBD6FD8B514E2B49D6333815B7DBD1E0694695FCA3D2
+1320A0C4B852D9706DADD8369A95FDD917328BE93DD33818954DBD2C212D2CA81560ED5BC284EB04
+7A5F389E24E43F4FA8C97FECF46589FA7341076555CF55B1C21B28E0C1CBB00AB8B6F67472F27BC0
+D11148F407824B0159B5188D4BB7386FBDBF1C0FAF34721B7BCB5C0FCB7C4010DCB6A1284E9D7883
+9E3C2111A05D29AB7997073B590A81C6168020F1D48951BC7D8476D5BA593F4F23CAC1F9BB0E091E
+84B4E99E5C584D1370DD12DEE8DF16AF8BC6B7B23E2FEABDB7F32779AF8E2B5094A6E9B7A7225F24
+C43A8E5D2B977E1E19E633C26771E23017ED233DBB02C64F8CF03992C6484528D0C8464B46F24F9E
+8380F385D5D01B8893C67FC103498983CF939432AA380CA576D09030CD52FD99BDC3BE16C7204CDC
+3365BF76294A83A1FC14A236F5FE5321904E779B13232A76F8FE521F425562678436359C2461BEA5
+AB27209541F557AE2AA60009C9CA0A9FC7898C14306CE35A50017BADEFDECBBF94EE2905220706DC
+806409EF87DB1D73EAB0698AD2DB72CDCDB293E7FB13C94D9FC87E74502E6927A212F0D7D2F2D194
+64F7A66AC07872E18CB1DDE8F11835DCBC5C4EF039333FFFC0FC1456DAADE7DAE3EC2EE0D3415B0C
+ABB69FC5006F4D14A4EE1A5CA99AD4D5E629C0DD1E0F097B5B93DE2DD001A8C418234C9C45E8C13D
+1AE04E9466DAB8CF1ECB88A4E059C111A6468D2DABB90DA79C7C79E94DB28F6968B1A632F8C57D9E
+565FF91C6916026FFAC0661856B9FB8DE9C81661816221B1FC159CFEF1751E7E403F5F2CE32529DD
+540792FC17A12A3DCD7C50D38EEAADBD10ADBF5D8A82442AA900CE6150EB7A4639DD9FB6E385B2FD
+093493DCCD9014B23EB172E21AA89643A6CAD1093343D85D81261972DE0ACB16A4C6B5F0BE4C978B
+FA12D3CAF0134F9EA49F6E9687C8F99A456745EA252F0BA9968C7F9586E3DD841AA92DC7705BDD68
+2DAE41518A09DF0E209F321D7FA3417202F4BA76A984DA3ADDBC58136885362F02F0A24EBC439B3D
+BBDACFFD8498EBD29F88F016B1FEABC10785438EAC860B554525F3266097A675299AA0967BD3B7A0
+EEEE3FC578D1BE99D3533BD91571AED904BFC9DA1A1451FDC5406E1CD614E0C7FBC733563CD6CE6C
+C31E9237CA153F1F0411114361D731636BCF98555ABF12848AD109371A42B63675A4130B81E97C2A
+2EE2BB5D8FAE2640156001AF0F55D9D5DF8FF23C8AEFE14F120000F14149A36E5C94CD9081DEC277
+C2C34870D05011F99D48B0875A5FF542F067F7E9880109F586BCF2B50522A1F23ECE44349E539E70
+F84E207DC9BEC7CDF856A046F1A03226AA41F541719AD1AF88FF211E57DD0C1275DD0B7B47440DA0
+89B98C6EE92A7D94700B83CEBE19EAEDD8A615F6587587BA8BBA3CE3AA5E8EAFB1FB0F486BE3609B
+169EFB178A4292F4C0378AFE5D24EED1CAAB514DDC66C696D8E37F294A6579131DDF5488E9436609
+ACD750C3DB0A940C84FE022B22ADC2676F62E91E8F891225F891FBA537679B24547BBBF35F04915D
+20B11739F620D18B5B216921D222F15044368569AA302980B9225BB839F494588481B94B0C724352
+B2DF600A22B062561D86CB8F81514FBDAA4F8A043A0265F992FAB71FC9124A45B8475E1EF3DF6B6D
+E35CF329777D45F08325E8505EC0D979F542807AE77E57E453525F23BC59A50740371EFA98678AEE
+6C425374AEB745B99DDB5D8D908FDB551FBC0DB15832107BBECC4E11A1A8DEC69358A574A2ED46CC
+31D564549EFF23102D92BFDCBB2BB985F78F36033E34F59C0EBAFA3BDD71338736464CEFDBA91398
+33995EDA4207BFD4A9867D32E867FBEB7DE60D132803EF9347CB17BD91315484EF6570892297DD8B
+7D966103339535E28A00CB1EECA4A9775F60A9F5FC9BD8B06D78FE8E6318C31DA2E847E3F9CA587C
+B01AE2BA0A2EBDE308314413F4F230A758184ED60D4F71F6CEC22A93A01B6C54E0449A3860FCA895
+4A347B7588329A80974ECBECDA1070FBC055666375229F13DD995E99265DF870BC8B8CC6347FADBC
+1A6AF64599271A475B9123493D46BEC41289BEEB67EB97A8DED7A9C9730D37C65164CFBDC22E5CA5
+89D2E7954C7136EF4E084C43A6C7F361A3E96989239BDDB9A593CC2A80BA16DE9EE90E95CD39393C
+212AB22EECB677FD36D34DEB46C4AD0D21BF7E6D7CBD0C8083842FCD87B18FEA7CECF939987E99BA
+34C214E44DD84C176C9CC5A4CEA76D380CB316BB4EF9DE73D73B4AFD4ADB54451591DEF86621D138
+D5A0A29441502BF6C2ADE671CEC3CB5CAB903A657EB2D70C943F976C110E46C5D9D29BC00A875F27
+38E5D22496A43E096E009C5D3CB724B4CABB32838DBE527F83B18CB457E57B092C302EE557FD4F00
+DB9C56E66C9FDF4EC9FFAAB85F60D02BA79694FABA476A199A0331C30A78A92E10417BA236E23364
+8174C826331DC1BAB87C5F95027846130C6A2B4027930EBF9A97BA1B039D386FC51C302648E25980
+212F6A582CDE2778C677A01FBFB3C5D1B8A374ADAF6ADBF7DC94075F25ED66D440B3922C5F255FB2
+3FD8F6E21EA65B1D93BB225684B50F11310E242B087575973345B229BA62C1E2C35BDAEC04D10148
+F5B2F3BCF7399BDFDF1F3F79119714AEA697245BC647316EA157484ECB951BE367234FD02E8B1F09
+1AAC3D29BF282DFF4011BC0CBA8E55234D943DB3017CC7A766720BBC29B2D097A956C0F1067177F0
+12D42ADCB473CDE8D1BA35B4030757FA1D8211989DF3BD22CE5D501C21EF8708FB3449DF47D88650
+9FF7B59B76C0DBAE443F336FEE2D615D7EED1C284F14335BC8A26BF4621E10DE9611FB2F1DBD52E4
+B7565D8C65B54EA36D508BCF0C578A49A2665227CDE1F9768EFE847F9D94F1BBB7DB83701C232198
+5C7283D47B2E40B27A268428AAEFE75F6B2F8764A8494E5827573758CB9CA46FA93208836BCCC8B5
+564A69F5AD882052AF1C1417C3FA7F580569528682C77080F3688B65E7FC24D2A3AEB61574B4A321
+5927281544DDD7A6EE0A3E9388F8F631CE7251724DF70726E5912DDCCC8C652DD6C9608F8462303D
+867F589DE0F2F71711B35142EE6EF93B64D6326C4DD7DC83278E057100EE772082E6BA368ED91A55
+53ECFE2293A481E42F83BC8F9148C70EACE91F7B7D9CB8A72415BDB3AF66F68EA733A17ABE9DB005
+3BF148629132969589F38D30EABFA96A01FAC72650B5A6FF3935670198A1EA33810A9B11E330EB8B
+451F24F93544263436F669AB5A90A53B16CCEEAC36B1445574EFA7E802DE73522BE725E68704822C
+B7D3912717333367895BBFBE06966A5CC653AAB5E9B3596702086BF0010085B900711932A95ACF15
+CA4DC45A754EA334E9EB84D6FC8E3FC4F897456BED64BB93B593549FF0D5352275D8E417172A6664
+C5E0ECED1019494A7ED49AB0B965BEC1A82E5873766BB38D7D856049CCE2FCA65AAF61E961B60634
+E2A69EF059754C9D8163D87F928C222772D070D83FEC6FA5AC734AF65E40BFDE521F7D9CB1650FDF
+64754BFF21EA3FF0AF7611A93D525EC9B28C51AFECB04E7FC8323DD6C9B0D8539A34FC3CD8CEB795
+8E8EBBFED4313C77ED469C199552A9FF70BA5423B03B6148D4EAAE17B71C5B39DC436AC53D6BA8A7
+AD81AA8B02335A8B2B11E9F4FA913159A725B8AB60F52F1A2EA50EAF4D56656E615BF382CC68A690
+BF83DFF24FE986570ADC0290ED1A37C1C2AD469CE789E0EA0BB5CE01020100E729721AF3B5BADD33
+A2DAA6C33EB8F9064F5292F715F820B4BBFDD56F76D42E7A1A068C1CBDCE4640082F6E7D582D1939
+990CE6EE8D270015A2C461798B37DCB5798EE9F7512168B76D26C28BE4A49A1BF96C89D235F21A1D
+B6A96E5DA474D0B19B808D13D7A11BF39EA8647499C410ED9894A1ADF33D41B6FC2E614D8087F4C8
+4E437B136F3CB32DB8393C49177A0675A0C9E7EECEF448A97AFDBE840FA01FC7E5F2E8FECEDC1884
+84C312E8635CD79195475DDBFDD4D38D5A0246DE2C7F21608F8D2C0DA1371D302E941572E5792A3C
+F4E51A33228B93A814D03FD4FC223C314CF3714BB3A34BD4F7ED6348577FEED9DEB082C4049E57B5
+D3CDB7F26629E9F3BA36893E09E3C7463D02A22D7056BE76B87763260E46E48BB832B7EE13F8DC05
+37EC8E81E9BDFEAD8C27EBDF1AD706933EFD11131E12814F236EBB01BE85B7F1B2D627413B324918
+D247604F56EC128909873FEC3857028BEF76A3494364C2A7002D104D486236C30B48E2B75D851C34
+EA50BA7FFEB4E19190898AE21768C157C0CAC628A2181A32796FBC1A7271D2473CD88E5395DDBDB1
+FC3AA8DF0F3D588637F19A8B833AFDEB5F655A8838EECD684E2315B72C75CEEFBCEF94344ACE8D6A
+DBE355008EC72FE7CEEAB01363A895F4E73F867639BE0A0BE67333848816B05B419221BE8F9066C3
+62C23FE85B7F392930BFE4C12B9526FF2FDEC38F23A159ED61A0718E7115C24597D849FA76369153
+54A40C965D4D72EC94DA61A03766AB39AAB684E134FD1407A5B1B19BFEBA52AA0DA5D99CBE5C82DB
+AA663711E6DEBA180E1D4A39C320516A4350D296BC19BF1BE054859A0889C7E9727A021F3176FE62
+0FB0C837E4141FECE531A950C03D319E3255703220B7185BD20FE5DBA673F8129AB211EFCF36EE39
+4C7E00EB0876624BC840FA86E58B2F584754CB6BFDFD76810E300741EBE4544E5AC17413ADEB21C6
+2F66CA4F075C32381796BA709782DE34A675B717A2C7F6D88104CB924FDE5DF775B4F0B68E0E2E5C
+2F788BBDEAF06D8E1FC2105CCBBD5827C0B03FD6CD64F0D073F3192D5F94839644E5EC6C5185BADC
+F04112A65F49A8C83174A9AE958E76A2F5AF469E8B76C833782C5FFB8BD7B1BBBB3EA0CB7C9786C3
+BE2ADE5E7AFA8C8F20892659A59BC421E28845A108E34EE17864042EF587A6D67DECDFB3F510EB40
+D2229585347A0035670FCC76C2837A4E4D68304FE113C539B35C1F0234B5079B8E32934546982978
+C5E4DF955A454EA263C3CA5D7101F31A318D82A3F9FCB5A8AFD7A65209663B0FC9DA400B26F285EF
+46D0E1EAF8ACB1F1CB805E3986D04BC585073FC64895E4DAE1CCB749BB439CB32EA91176D5C39C36
+50D10AFB9C9884D5FB90183424CEE67EF2175D01D2478D67511EC9F54F88763C152697B06D948BED
+49240096EEE3D06AB4575E8E8B2CB8263B5BCF4FA1608720F52B675309833071879DF52C3EC2871D
+20F398B5CAC8F8A4D41D0F1D47584DD90DCDAEA4A1CF160C4B3BF1AAB890B5CEB6CB3488672AA68F
+BD938281DBC1D8BCFE92FBF514DA5358443CB6E0147254E91B38CE6787B2BB0DEDD2D38F5938737A
+977B5EA42892520C58F8FBB53C994B57382379E9490F0D6970B980E1BDF8CF9F4C3C5E0A18F66E86
+EE93FFE7FE546DE50F41364BCB3721B637072571FA1779F1D672FAD260C16D7F13CBDF3E4376E7FF
+56D2A710AC5AC35FCBDBCE2C9C17E523BBE6218617B13C1FA6679B308979AE7C61DA6E68369324C6
+CBC7DDEC364E5A86707266C0B459EE7B2C03FE584E529BFFDCE98C90A2F3D9305AA74D3ED8430DBF
+3A49FE2ECFD9C4BC9FEFD22618FE9C8A973AD072AB6F713E4DF02DCDA7AC5359B2D652013E131B76
+B3ED6C75FD53BA58D862846264627F6B9E70D8800F6D9B32242B747A67BB2B45675840D34F852AA8
+062FA6B01E31ED24DAE02F6CF788A17F7B9368175195DB0072259CCE0FFB2C1035C1D26E1777CCA3
+D56A827C3242069E76D6DD69B653768614B9ACFF16567FEA61508D51454BC02F6C60F755AEF6AFAE
+3536BBFA1823F8E1A53C41124DE983E51CEC92AEF4F99785D554488A51C20885346D1F761DA79017
+940A0C557D93F1DB6B3D00FFD61D08E96FF3AFCE5FEDF545CC9F47A2B1BB26713431D6D1E47FD6BD
+6E3C668B0368241F0EBB5FA9C991DF79890E52E83A3675EE699B61BAF869DE91F67278F510061C6F
+E41DE2D883F48CD0E068E2A652B244128D82E5CD52F35F210DDAE3054691ED55A7D99088AAE8FB04
+F525C2084AC09F5EDF80A4EFAFE981F74C0DE9D194320709B3464F3FF2C0F6AAEA6D973D9C323F53
+DE3D741F698FBF01036716BBD62957CB32CD81D3A2674560FFBC5BDC5C6E4F547E589AD0B1CFE14F
+5E17FED1C4A8ABE4E67CCF8A49F32C4C6044F1431E1CC382E7758722A6D0DF9ED23E51F8AD14D11D
+7B6428E27443715EBA4E9C05D6F238378F9498AEF0E7EE4FE6856622CC8E6ED141EE5F109E343CB6
+695C4BE1E0F66601C27975983BF557C04ACFC19227A1AD7E6C44C00529FC7EDD7F886D24B7E029B9
+C395260088BBFB96972199A7B32796D27257DE83A7402291C14FECDF7998C5C96B1EDADE0280F856
+8A8F5007852EED303969180B3329917973C2D32C080C9765B6BAB0673BC7ECFDBBFBEA980C263843
+39B7F1052591D91667D4FEE413AFC23DE2D4B9DA742F4269C6C939F5FC32A38040730A018155AD73
+3F231E4D5B9D01C03A58EAE7B5F590CCFAF25EDC8552CFC8D95C60EBAE1837D7A97CA137E9D4A4BD
+2CD34AEFD68D64B3F4F62326AC429921D7FB3C235184FE0899690A0B775F1A566EC29D5830D32372
+6526F7E7F5AFDD71B77E07613DDC4FC63EDF49051AEB59E6337AC0A4B6DD872E776C9CD0CCB86130
+5322D816732124F5978A86C186BF0A0F88E733CE38E4D7C1BA5378C5629B1EFC97806059990ED42C
+5CD183BAD7E94070E4058569DA2E51831FFE0D080301AEAB4350BA290318AEC582C78D05DD92E5AF
+B4424EA808629BC972E68F4FF2489C245593F07555CA6A2B25964794CF31CBD3AE5C229AB9B8C298
+06C01D116EBD0FF0F159ED2D3D7DFC73EAB4910BFF5B0B0B587CD9EA6E6FC45D63C09766224D8346
+1F0588140B258B1729F70BAE7962189B1554483392988CF230AF4077193E53330519394DD99BA135
+6D4730AB221DC6A66019BFAE564893DDAD7B177DADD16ADD21D396CFA6C3DC818052E2F71149FD59
+4A16DE0C2FFDD366C99B486C55A6E991E4D22CCB15843F0C3363676AF2F5B2D1B7EF66CCF2F12DC5
+0D63776BFFB058D70A9C76DCE96C754872D72C82A0C33F90D49C935402CDD26B6D743B1F43BED5D8
+B539424849C1495DAE73044E885A7D0F307F1816DF6244A6F2D97BFD4E200E93F69B08AF39EA21E6
+E347A47CEEBF803F73B978ADBFCF056789BB8E6E2563DE87DD9A8C877157B934102DCEDAC54D487A
+1BB2694F0034093C48F10A17D32E2BDD0C723CAF59ADDD1BE373AF8C9BEB4415AA5AF36310C31F24
+354A53C0B962573148BEF91D994FE3F3D8450DD4D686725799F53C373A0A3E3C060C2E1A3E800504
+9F26D716E1F381B9F83125E4683264A07E2D8938F605978E2513DD2050B3D8A1012797CBA8961632
+BED260916338A812AE751C7B657E086A0C7DDCD3BFDDFF3E48B84751925736D1310C4910FC114387
+F3ED7FE163F91895EBF55FCB425CEF5729D99BD8F2C072E36C310523E75CD8E5DE49C031C4263410
+9D56E91A46C8C8E89FD92012A00C33D0DEC52597B5C6933291A7BDC5CEDA95DCDA5600F9AE1C8250
+54E7EE1067458CCB66610704C58E4A4FC0CB5FC933D0322A716B2CD430A3AD48DAB3D4CBE9D23F2D
+092368CFC4E1F5495C133A92942EC62118D45C17723646E69407B4A89DCDFD2AB3FFC099A21D9D29
+741D68270629AA3A414FE58658DC9170C247B6E23F35C4BC5FF83009F462F2EEF4DBAC5FD158A658
+57F9B6DC1F5192DFB169DCB65621CAB2F1B07BD22F4155A8E9E2B6388D430FDE5EC1C834D22EA035
+C52E1E34482EADC36B4CAE902AAE89A7284E62B3C84B608D6BD05F75BC31310B2DD3B2C08A00E073
+7F104F03A41989D5F6B9A2C38B22F1D1803EE5D7A4D8DE44E4ABD496A1DE0C0E12C4BC96D0122846
+3F0EA9CE9509FEE987139F3DD3F9D0DF4313F555BE85433718F6D05F197C41A9D9C7A8B0D2740196
+82D49F58DD5F66B12A6520D9F226D1DF1F1B65CDFA261F980CA25A92645B86B64606293F8BFDE364
+C47D2AF2C709BBE77A70A5712F2CC26F3D66F5BE2C307A48E6F887F681D30121E32BBD87271B5DC4
+615D28C309F15AD263FB37424E56DDA6E17B998B45BE6C7FC6C28E3394A8764C9EB2DF5C06626593
+B5C665D550D4600172791CD208AE9F37BC082B0B242B0A504B751B18F4D7495172B697EE217834A8
+A4FB7CC16D6F9E8BB400BE8AEB0850960283DCE725249FCC4DE97D9886745AB6066C3E2F64DD8AB7
+9AA11667F11188D7965DC11EB760B772E282DBF13249F31986AC6898FEBFE23E3E8B8D2C33E00EA6
+FC493850ECB2E6D831D1EFCA3C2EC8EE2E394599091ED58BEDE97D7A43B6F739EB0F845EAC1DF6B1
+EBFE876009CC5D804B15ED4B56761B3CE1AF59C07B49DC798A44532297AD73D5101ED47F36A3678F
+818297CC27F6AAA2AACCC9AA9B6F5459911D8C56CF499E390AE607F3790450B2B9C9BE0F006EDA0C
+715B5CA0481734CFB0597478E7602B0D2C1E4F78F03C68C17C70E4B42D7D2D3C95CF40F73488B371
+8E2CB05A549944D86944D78724E266C3319AF89AE430E777E95F0D792B1C654306E421F3D63A26B2
+1E74B6E8B21B2E2B9DC596D013CDA16D08E65E8F24A84B12B2BADC653E6E1110DE2E709C1C1BED13
+707B70A421B384F20CA7A9A9D20324DD383F28B2D3C7A9C53F5D4C6B7C378D26DF11CF55238BE1B2
+4FA70DCC178DAD3D35670FE4919085EB1CD905971D76A368FDFCF9D2F0A23739851A3A6D2E02D65D
+54DEE69ED5D81315D3EA5E356F94EF256DD267FD1E1A9EDC9CD63E743F299BCC4A4506233B8DD765
+2CA067F741603F93250C087D368F9E9CC4CC1A6DED567487C05BAA992B0056A77F630A72008E3946
+15A9DB24FE56A956650EC9DE90A6C2259189440247970541CA198748928215C0E132A81AA13208D8
+63C1FE817F70CA573B54577D10B73100AF8EA088208A44FB92ACA314AE5879706180788C17BB1D0B
+81B6B95A1C4E0F9EA66F9B39BFE12444A6446691A7BDB03E0F03D9F07A10A7598F2166F108529F34
+CD90E601FFED3479ABCFCBDE8F051C348E48C61D95B00C59EA1287423F05666C3D36288844067E83
+E14F6B5210842C742B89F13ACD126B9FC50ABE2CA7D7ED513D43B6AC7F41EEDA416BFFFCC5C844AB
+2D23D4DC09B2D510504CE98D02E72020D9E669DDAA344C63A1B75632F912A1C0DA3885DA4AF7E243
+E4A4C6493D6595BB6D56B0359106957259E59E336BAAF35BD1CEC5CDE735272EBCCAE8D4904AEBD2
+B32610C6FEA2B69941D6542ECB44D71092A3CF067708A3D087AE99FF29671AB7DD8758759B971A08
+AE1BAD78270D2FBEE37AA2DCB119D72F6C7B0C8509018A70D0B0BE2C6830EF8E0B24B1CE1141EF87
+3A4D7DCC501F808BFD94E4DC0F2915AA023076BCC8006490A43685EA25AAFC187302EBDE7FE1965A
+04A5A398985D29F08E085127B56B057334D88EB638A4DDE64AFD204974C3939536B1B66A54B4DB81
+151853915718F70813F096CC1B0EA25E363B49264C2AD17158A4489F91453FBEDBDE15D7B74D7F98
+E81DF23251785D58295BA297F295AA6248A912CDD4F1111E6B628EECBB5139709E76EA4AB743CEC8
+26621D08E6BC64691CC90B3C3C1778931A28D3D5B1E20E96C643316613FC487C9B604C43463FA453
+3BCA1236286E6F5A6EEB2F1D9C34BDDE4595495A365F88055D9268541CF1654ACF478D384A5496A8
+772EA1402751A093582A6625A0A44816B5FDBE166835D598644296249B92CC90AA3FD6445C9A19BF
+27F59CB0616C7306070F33C7DF4E1DE64AC8C5BB2FFAC1EF2B1B30E5A0275E6004CF64BBE2C6710E
+DCFC3AA4ADD60106334708862FFA6652825BC84842736E47AE6917180365C75B27505EED3C6108E9
+898A780E20C3F606A860229AC46D0471ACA0187D6D539A1B8820F620F72B41AD1D3BF3834BF48CA2
+AFEA8BF535AF74C4562DEADCB63D2F5C7585722B77C989342D190FF926C8A5263B4F25286F99CF6F
+C62EE6E2AD61C82B29D82468AC10FD27764278E5558CE8B41BA111CB2F040914451A480C93084237
+CAC8F66BB7C6689F340B8ABF0150E06D5B1177278A4C08742FE22F42C28680F190900344ADFA486D
+59718C25D37275BCE4DF981AAC35D2C7E85C72A0188B8953CFA516FD545AEE0BF4B8BA301CFDE214
+4241FBDF3D204E3D2823301572E23F204C97305A82401660E12926EE7BA6EA1A81FF5C007933AFC7
+3266FAC4C134ED818A48E7DA01C71A46335C845F9DA5E960B25339D551582B375814148D94CFB781
+FC56093827B78578A73D4FF67B6B87F40CFA5E3F4325D9108CDB64BD06427B88C84105187316FA29
+90B4E3E8EDB6C78ABF164F4A9717D523794B2FE772A04DABBE688CCA977090979B5F47CEB90A1DBC
+167D305EAB231C9F4260C4AD10889CB785169902FC0BED78DA15B8417453BB65856EA0BEA5245BA0
+573F623D215F6C0CF801851C305B355D26B52B0B343645FE25C78A3526841EDA480919A1BBE5F56F
+C10ABEAA3E1FCCA7C43EE560F067F1AA2AFD642F769D1ACE8E2AAAF38850F0D757CD808C921D716E
+96FBC07DA7860DFA70CEAE2888C0ED3CBF9586443532B68DAED9A926655C157A416C383A53D8F283
+2A4E67468112A09ADC837ED8EC95F70852921F50D4417239FC42EE3624CA97F682745CC5E76CC7C6
+7BD99F2180F8C0B7FB49539C8CC474C25C0DDE491671FF329E51BCFA779346D4686835A3AD6633FC
+B5E0F67E0CA9CED8F215BEF4D240453EB2EDD6ADB22278AA5B985FA140C9834D38753DF2014F8C0E
+E6DAD19E8FC54C03C1F6CB0F858986691D99592562CAD95FA0A5B2ABE4A8B54B457D42E8C33A2D19
+51C0419A72FB94FDA78ECD92BD2A1416459E9DECA9469F35E4C47DB531726DEE8F203D7042EDB32F
+025DF3D582547BB1D45F7A5B70D317DF4EBB16E36B0D798E0932FD2A85B04FD67143E4B287A50416
+2C1F5A037CCD780088C5476385AF8168E12D97D44B0630621759173C8F1E3006B5B1C6D7138B7EEF
+C3CC5F54E24B2C3CA7B41AACFD25E554880AAF406EA4C3C6E21D3B550B040FB1952598A7E8E6488F
+E38288B2AEB6C4718338598A2BFE4D2B9D14C65732DA304C16FF3E1F8F03046EF095B65FD609DA87
+EC24A69278BFE65C905CD0329F6A486B8525B7EEA4F7AE56C2633CD83543269E8ACD6D71F500D82F
+DFBDE7F7F7B1AEE67328549232E26CA55085B6E84D9E2E7F74068F93A90C4654F2F396E57C5F76F7
+E61CBBE523DBFBA6E76638BBA3064DA025A79E3A294FE7F1CC28A3B4C57DD6FDC48E541A85534B25
+E1BC11B4F78019457239EAEFD4BE9007D205F1D985F389DB22400B279C10948551A6B4A17FBDA0FF
+C9428B18B43DC76EFB15FC2182216F1B60B4E344A03AD6C00F141EF99F89F24C819C3E32877A927D
+84C2D006940F39CA8B71E5951673EA9BFD1749923219DE38929ECAA9CE43B06CFA7DA1BBEDFDA56C
+61FF6C24F40E59B13870D5FDEB82D981154FAE5D6D5152DE69339359461A41A9713B6BBE47E868C9
+33CD74C75DB71D13BAE4DEC85E02FAA14EAD6C0A253B16C79514657B15E68CCFF9EE6AA385CFF9E2
+C53D9AE40F85C793E4E8FF50B2B7420F4FE69807BC5F37C3E300E6B3C3549D1D3246A2E70F091054
+1135BDF805E0A698E236B6496702D061241687B7B8D1A0E517DF0476DA09D89667A7AB375FD2672D
+CBAB8124E511502DDBD08BA04D941DF1CEBDCCF7ED48405CBCC33774A68C5212FC6F132641FF413C
+984F8B43BDFD7B1A2A3435F15AF07EF4970D3E4A0BB947C181E9CA27CC14A35BD1BD096875B45873
+8CA244F88C28728B74E25CB8C4FC1095A56CA75E4569AD3082EF194ADD11350DB3B74B96761D4538
+596FF7243B1E1B724716A144106E080D42036444FD472998460CE9ABBD05B42AF9389AC452BDBBA3
+A13A96890025789F16B9D92251FD3B3BEB2C61EDDB370A20456E3BFE5F4039E2557C451C524F8087
+015BAF3FF05F51869FB97512968BDB2B49589C1C7AF1E085250A47657465F480B7023E24C76731AC
+0EAB6704123D77977D3A2C4C56B691346EBE589C619C04515D34F81FC6A17527D5D8319013C5D4FF
+27CC3925E24C99231AC7FB9EAF0BBA482D3B75807AC85D03CD09DE5D9AE0B07B7A813F0449786500
+0AE8A7E00080300F0AB8C399057EDDBA273DD2E1B2A0DCEFAD3B332E6D4AC1FFAD846167DFD70E03
+46DAF84AF292D4F424256ED5AC4E104F80697050D50844A708EAC9E7F7784FD01646F3BD0C595CA5
+1EE6BD607D254E78ADDC5E15C3B6AC4940EC865A5C23105B6BE09EA09F2C05D6D76960A843B81EE4
+33977FAAC3CBDA85CDD2F4DB7C28293A77825635992AF8F3B38B4480D9A139B1662345A8ABE1634A
+77496C3F57597D2985E9E54717AB2E99CA35789441BCDDEDE9A9E2106B401D9684ADBEFE40D607F0
+75C179E9CC03E59E65430DB70B441D43DF03F2AA6FF06F224B6E455B01C64FB89EEC9103E48453A9
+749B4D602808C7E408A8903091D85E06AAF635D0D529C3CDD1B8479AC0F4208C284BB678A547F2BD
+77BB17C86D4560434F7AD1937760A6AA55B614CFA9FF8C9C96561AE6C8F2121C4E20237428BC51DF
+2099B6C49E3EFA18E6D439E6E6981E746EBB1DC461259D8EA0F8099C47CCA27B2D982B72C9A07CF2
+1B3C05D6E26E6E286E348B8944078E24809F9C5F3D014B4CBA02533F5621BFBA1F0EDB776C634746
+703C9F73BA89B1960A496420C68F54E5B901A6D733D7ACC79F275FFFB253F389AA480084468BB34D
+A1E797E43B7F6E8CAF5E8C93069A3A2730E57EC39B677BB73E3F07C2055599F7062E53B37A5F0099
+907D2ED87FF7A82C95FBAEB888033BDFD67BA3A6031A4CDC56CB1E4CF5B06B46E16D988BECCEFACB
+9E1C037023D7BF5CCF5D65AA66A17AB361BE7981F132A578F3ABFB97960A6034F052D9D5AFDC0679
+782EC90F240F943A5F9A3D969ED7399254FF67D89DF668F7C56FCEA1FFDCF20481474AC8495D3AF4
+B6D7EE093E369C057F0B70858220693B398ACF8E8143558132E4391405E30A73937C53402E459F4A
+A3539CF7A99A3F51C0307D045DF8B77757E92EA2F51BF0BB4F77D3904DD355665870C2B59F1ED7F8
+4FC71FDD7F0B6C5D3182DB77827CA6A2060D2B8C83C4EA4A432EF43A4D0A952CC6CBBE52A9F0CD66
+1A538973DE41FFE9C5CF55F2506B9EFEE51FBAE5E63BDCF5528499A47C031163C88D3022606784DE
+2F46A9C9235AEE3D4F71D4959B0CFDC5B7E78C8C0A8F9DC99440C2263DBACB343C5C648577F5610B
+50EAB1CF7FD02419EF3941C7CA0B0E64EBAD4B2CB05A0793DBC38F1946D44767BD287F5E9779C611
+CA0DAAA1E7393DBE0683C8D3455CDFEBC0E64B54B737E298DDA605227C0C4BBA87AA3EC7FA6EBAEC
+39E6EF2537D5974391D31739D9FC42983D81AEE44711C823F35F8E2321AC74943871739D2DBE9748
+FE68592263E7713F27E0D49B9B5CB7A4E55DE54E6B800D15856450FFD3AE5F287B12AE4F438B20AE
+9E27E6CAA00F3EAEADBE08432684FDF9931E925544A680182602A3C1997DE5D0630BD5A010535E66
+E1C123013D23966B3545C7431C39B97295BFA4099D14461004C42C85095EEACB9B47C593BC6DB863
+533A8619BAE09095DE8ECA432D4DDD49AA600D277E75DC3F5C6631E2A05382CB007825FADB77438D
+CFA78E252D79B6A196D5164C2FEB85D75ECA25FF80B1D97FE10E87960CA0FC47C41D3A213BF141B4
+8BC3AAA93FA86245064668394665BFD52D12C3BE4CE39EFD8111754398A944C3FD1AFA98EC337BAA
+AF899D35E804CF416AD7FE45FFF13FC6354007501043F98FE8428DE8013901BA6A28711A2CA85A27
+0BB135B72F1D5026E8217581860729E94F2F1878A0E96C59E9F62714FB5F8F25003DFC7347E99007
+8A9A331CB3A6A535BC61866F02513DEB982C4A13ADBFBAC3FF70A7335F40D5489E48E5EDEDEF1619
+1973D932479C62183B0E25EE8C4F76D4F1AE45DAEA4A12AEDD9EF81D248E8D19F8C8A5BECDD1EA1E
+98783EB7A38149170851B1942C96C53DE06DEF80913BFC04E539EC67C110498D15B78268853E5C72
+F485F8A27B768569E54241F6115875E2973292CF48FF91D45EBED627AE9F0766D22201B20AFDD40E
+5B17CF337F2999E0BD15B86E46EB3C18FC12B7DCADCF9DD50C6C7E3F37E615A892DB3F57E250A072
+A49F7277DD6A2C8042698233D35A699B17ECA5DBDA6D250ED4A16FCC893BF0DC2E33FB1EBD7DEDEA
+3C1C39603C8B7E1A5A833A8FCDD5570BD088749BB232615366687962C7E56ED089CD7B092505CAFA
+5A80F503C4CF337F07ADF0D106937E25670839D491F7BFF7A523DB609D126328C16113ECBCBF9C40
+04904427A108618AE5D4ED809F8CCAF72251104C94EC5BEE21F91B179D31DBA79CEEE5EC7FF698EB
+84AB1D2D1A624F58B3622A78844CE51498B2CEF38EAFE259D22C7BA61104651A862008BC1DDDA58C
+C45F663EB26428DAA85E7785363A69D2790996EF5D9621D53042F42F794962FEA46E46F37B8AD1FB
+76FC8D5CF2146843F8CC625139C75FB42DDA71A752BAC48F294E4C0C8289FC46DA5EFD9C91BDA6D0
+27518B7E81E8B21F755A9615627D5812ACA674D1527A1185EED4E3C628196E7D0759B1CAE6B9B7E9
+01E9599A65230F1EE469CD33B9BD9C104C44E3C1AB966C9678BD0AD78111A4E0F2D07A01A038CEDE
+7036D0534D684A1562A17AD64A00F279200C0371B1CBA61747671D2A21D3F9646CA290F6B82418A9
+6FA177C6278277504B7FBA936325F5FA124AB018A15DC18D2C5E8F93CDEEA52BEEDB78A57828D81A
+3E6C38B9FAF3DC4EB7273ECE3EA4482A1C6242A335862C2C3717F9C9ED95F77B140C4E1569B2192F
+C7DCF702D0BC9A50428EC406F8BD0CAF886B4D979320D3E429816D88F7C7146D960AC12E70F2CB7A
+9F4E3E366665AB3F1B4B6440F55EEA26DC9EE0096BB7763731740A537766490C8C174723BF0EB40C
+53701AAD12B21D436ADCE22203C1053A9DC4E9F17AE617888C4B4E6F3A720E4E6366BA628221A387
+D8AB15E04AD69387C310D3528BD2FAA5B22BFF3FA494F5FBFAC4F771C9C7402B95580C5AC4BB3AF6
+92A70CB2C851FA5CF1173EEC3EC29B5A05A0B728BBBB51D3B7AD8B0AF17A1563E82FAFD93F8B7118
+1FB7AFE352874F4EC6D334AB6747519AB8E847B7BCED33EB5458A828E074E74BA621BDCD03FEA604
+7F7B6ABDA01FC7514BA1AFF0D4D0C0CB8F4E42D5A87E395D9ACDD02CCC220C157153422018725846
+009A3ACD8C8CDDB66BC6836B4026FD9F526AA275D06C813179E5924F26A25094E7BDA8BD26AFC4CE
+B41D8964D4FC4AF1DFB0595BC5D6714C32F15DC7194E9A3A73013C45D8FA55CC0550A12D9AAE8E9F
+F199FA28EFC2426D8D1DEFB93A65717AF3EA8E2D5B4AA8EF0EF38E9600F7D4E7D9F1D67A2E63ECE4
+789FA74B159BFE2F91C19B0378BA52E93DF12830D99553B6618645E26126842AB70262D96E35E5E7
+50ECA0CE3458B3E51BEE2F21191136DFDBCA39BDC07939E521E4F492F392DEBD029C1EA237BD89AF
+76BC89F618D530160AB16269FA6B693CF14BDC4EC7C630025703C5337F61458FA09104EB15C7CB20
+AA4C9BDB7CEF3A09F25BC7F3149951A7CD75372993B80CD2112F7674CEFD6AFA764AA3486730D2C1
+897A264D82A91709FEC4A21E30D812F558451804EE6F3DEE2C4C437846BCBDA07C5B6CBA1D94AF02
+9163B7383CAC6E088AB1DC14ED3743EE77E26EA7AD3119A76C0B5F925C4DE305CD7BB3A09A453947
+5B9BD79BE28FC462D8718CE05F9D94CAF3387BA55E6E447BF81A9EDDD3A34E17BE66BC52B0C0BB6F
+86F6F008829173816D205182ED2ECED319864A796AB65D4E3950288BADA94FA32B6F453AFDFC6C39
+A4FCFE60353A64627E2057D4B379D3240012B3BB0ED0C7876CB83C1BA5EFB6E2A03F340C2B576731
+F848F762A7E1CCAF267EE06D621BC33FC245D0E1547ADC12CC0EB58B26BABDB8EAE9CBFBAB93836F
+FF22BDA1831DD01B7346AD377AA298D84628BF1C07433284B0A90FC89F5AEB2651BA2CEA405D4F52
+DDC0E74B871D43F71EB4ACE0D2B401F9348EAC3A2EF0AD295036BF6CF6F870D58E00B619D50EA7DD
+77BC28DEF91D805CD527DCBCFDC16C042BF9B874E3B1567EBA4C1E70744B9E7E5BD1FDA6A5FF6E10
+1613FBE58DC46CFAC1A65ADAF65E49757E9304E2AC9A91E0588600C709A61D4231730073A36D473F
+518A145E141D0A5A494441B9EA99AC23F60F54F8127B477E1CE698BB4129B4B1DFEEDF10D9E665C2
+47A62F112F5CA30B0AE5DBF3E495FF06EB28EB438CE8AAAD84D5F50FB56A3AF002C23BCF66ABC270
+7AC233FC0F2723DB99D2CFE7D3B3667732A531F5DC315CE74EDB9050BF75D29E6430F57CB6778B2A
+CBD57DFCEF896E6766C8FC5C9F9FBD701CD62CACF33EE0FC95E78DADD205B5F42CC63024624BAA0A
+B4DD447832B4E1DBA77BDFADD223989F8E958C8D759AAA37930664C6EFEC708116248A2A7AF3D656
+DDEAFD009B7F5333854608E67E5E588A857167ADF9225CF6C641F5E19C3E08678A281199EDDAC831
+B57223B1BEEADFDCBC8F6F25D32FCA2336C808162E8F381656E847FB6CB13969572425AA05AC830C
+33DE6E030F86A3A85D2A66A77F103C7042C97205526DC882EA9A00EB8BD5519847EB424C15F808A9
+1652A6CC89B66A5731126DEBADE123C63D88A2E550FACDEB3886FF98646000C64B3A91078012CA30
+904B71737CEF6BECABD43DD702880538F5A70085E6CC6015D2163681067C3D513A8C66032C34A0FE
+17A58AD4BC97CA69BF41F11D5E910FDFE9729652D3EA21F8DD8CC19160A8FC77573B1E9CEF4E790A
+79D8AD6723B6804E9616466C935303E063DEE29CAA6C3BAEBF278B818C2EC2F13ED645AB452397BF
+00DB8B26E115026E256746CD0C78A959364FDE6DEDDCD0F441A61A1EBA32C7BC172BB09512148D1E
+BAC9E791B7D51B71CAD2DC9B83B2F99B3726607D9CBE58B499A13753CE87FCDCE21C0AD0528ED0EF
+B9B2C927F57C78C626248AA2B835A0791244C5896686A66173EC9F802C4C633A42B086334D2A4878
+0E53D00809247BE64E529F96AD2F8B3922A6097D414DDE1EC76F9552F9B8D58B8E34F359AD792B2B
+E50C26DB05035E7497162E7C49C38D3CD9B98D620AA67492BE5AFCA3A81A7080185C7F0B5105223F
+1FA77805502A2E8C5FEEA27699858D84A95842C5F2FB68686D59FE24091FCDDE139B6463BC6C7B1E
+0E90D20A83651AF00C85797BB9F53ECEC1675C7EE636D0D9E77DBD8F89670F855EE4D4800FF3F695
+0EFF09BBF8A0DAF6B8242840CFA5BA73BEB95115F4A78BCC02D85ECCE0C0F2EF6F328AD1DD6CC049
+5A3315B414A4D61DA50DA46D7ACCEFF6EE56451805D26B0359AF193531F95F6589CEAD6FA041AF15
+3067F88A0A2FECD135C56682DB2B45A71D1FA737C064EE9A4F404BB72A70B3AF0330359393247EC7
+81512482579865240A23CD8479F21C2C44A119EBC4E81B308DD8AA86E60C3DD8ADA50E0DFE8308EB
+1A7F201EDE8DCFDA405AEFB47E0E6CA7DDB376DCB21D37F7ACC4D3E9F26B03A8DE0E8940CA3A9E75
+963A389DF8038D2C486072F61C0CEAF500753C7A6352B1CD0338D9212B42A4D3DA23D5BDF44C27C9
+4B88A415A3242FFE2E1B332477A21D2B9CE075EE479C6E657A4D8874A8C53964229310E01ED4F3C6
+86FEF5258EDF3B464DD6FFD7F1CAF473BBE722D60FB14AB4918E93878A8AE4773930B8CEE110F476
+7F42A52D9304C55BE12846C911A10AB9B2E036BF9DFD597F5348D42233315FA80D0F563C388BC253
+2103F05E90DBF1923F229F980A2F4585C7A373511372D07DCBACA583099EA972C03E5AA67E663882
+6DB134564DB993CEEB6E7A6659C7C5C05C310267D5F8A24EEC2D5CC3E3F3C808E6D6068D1A57646B
+37FABD98ECB7BAF99E7D9AC4414A491A73CA34C52F394352F6B5A15F0FC4D88622DAC694699C2464
+84ADAC3B1D366AFEDE2A2CD2042C90516A666A19A91C80248B11224BEDDF1A320E230739E755D098
+B6A67315535F4C187CFA67ED817A035056353FC859BF286317996FFFB478A2248B908FF12ABDE705
+402224A3EE5F463DD3D243875C84E02DB968ECA1CC52C75171EA50D6A88CA91327A7AA5795019F36
+C0A19C093A1C9D3723C7568F9D41F2E4FFB712FD47F897703D7A620B586B81936C84AAED61D84332
+B3BEBC4F95B796B93EF7A1F565C494F8A65EDB21E2EE18DC025522EF8E599887CA2836069CDDD889
+88E5862977B7472584303198CCE97EF9F9E1446D1F1F5ED1CFC666A8A0C3A03E1792EFB60A9B4065
+49E0DEDF6ACCDBD98742568B4735A747D8E5DE21E630125AE0C691D054E42199C15B1F80CAFA6E7B
+B2005F374A9A5F9900ABB7409CCD50C3AFCCAB1214E6A856F7C7EBA89BC3291801E1343DA9DAD2C6
+ED075C8ECA1423B43E587AEC67E6145272814B3F191B3C285639F9E2D6E148A02DC2CBC0E054D629
+5CD05DBAC1950400A9189316F0265B86A732D302C5BEE8ED233768F237C62600CBAAFF3A110D5EFB
+6CC7CA3B92D965CA7C5E8D3E64ECF239FE2507FC797FDBE54C1112B28D4DA44C60AB09D994C5BA78
+D663A2591934CC052BC70CD1DCA3325C66C9CB982E2039F5DB70C848D3DCEF655B1C2CD0CEC8865F
+E8E1C0A267BE4F707ECE6F5A3DFCA3CC1EDF92C760439F51AA69A4C1801E96CA4D6EA4AD980258F3
+D15C893913ABCE09101984C61B91D603053E49A97CB82FBA707DAE8AF1D579FD69C8481CB7B712CB
+CDDB4D287BE995E32C02B399602A08B9DD849039B5673F1930BEC7BF366EB082D2CA5DB2385C8CC4
+5BE3FC0E31820191A814EBA7C4F23B1938E6C4D800732787CD2CB97F762DFC85D4B798809B5F2254
+D826CA42B32695428D120298B44CF38494E56240B75DF1E41E46E53C44DC505452256DFEC819408D
+605FF14D6C1F3F152F2FEA96EA0AB3B472D8704E06BE9F8C3E8395CAADD06D6DA033E81ADE5DC3B8
+3DAFF743C6E9E48716003D358DF63CD7FD3E2F727D1F2D0C29962F76D5C95ED44B6F08D052025A66
+5785F264A3D5F5593677B630E628B5EA81FB37CFFD7A30B7FAD226B6FDC82B0878AF4C0EC4F4243A
+807B9839EA62BCBDF7C2E9B30A623876E632E084EBF4A21EDA04FC88A1C07021D0C72EC3E969D449
+FEB08E5826EC20E55B21EA71EA59F6E3B0710B0DDAB3261B4A2029ECAB68C19ADD5174E55D5E984A
+4E5F38F592A302FEE6ECE732DDE841A28672C620CC5D687455A5C06FA9FE688394A04F96312ED025
+B7AA6FBCE2925F3AE559CC1886BEECDB70822E2E5CA3F732A87404B1536AAC469989E9610CFA440A
+CE43875A70CA51F36CB6F629D9424C1E35A88F92D5DA3CD8CBAE6E8425A36968E21F4F30349749E0
+205BFF8D552837D6FC39532525370BBAC833F75F1854C93FC533A4AA53ADF7008173A70D94A4EBF5
+38EA9E62BCDA7C20E0A073BEE2EFAC34D2EF1D03BABD5147659E50B557045B2EB89DB303749B04D3
+F54B43FED612FCC68206E001A7AFE90230D9C12F74A32C7EDB5D0241DC3A5D51481FD7C8FAE08FEE
+263FBCED7C7D911B3A303C835AF5FADFD218F61A9D6DE80485ABCA88200047B094441F7767B97A24
+E8C612590FA2407BAB1E8B56C71914EEF2355DD97CFAFCC192BC06FCE063D3D9D1A629AADC75E3BF
+207234C208E7E30663EDD691043065C9CBC473D97C6D4DD3DFF59D6A9ABCDD4412C3128F603160AA
+D8F81C6E7A4DCAF35F3A99B4EA10A34375B477C2BF846521A7EABD4D28078E9340452A198F3F5ACC
+3DB7E3908939FF6E3709C6A3FD9889439A4AE3E10B618CC92E14B68429A3AD2C80940A1079452EC2
+66F254657BE7D79A2A24084AF73F6DF71FBCD32BF6913A3FAB25F977787F7BB0C3A3E8BAB38D7A2D
+B0B4826950643DD1E03BD7DD1FB149A33862A89226B7CB454DAF613128C2075470E42E70A9444A8E
+6ECA526345AB48E6F5160BA23B5BDDFDA6049EC44ED1461C7E0DD514B16E2FB285F72039DE3C7982
+EFD40D7F6C8E8F4CF35AC71B467BFC578002E8D2239A2FD2C4BCCDD8AF3D7DB1F4AE7F2D2E0811DF
+9D0155BA6EDE50B5F052F14F6AB884FFF244D8806C07EBCB49ED22D85DF696995991A954AA97A1EC
+D86ACD76E061B7541E87997FEF0657A826BD88EF3A4A5920462C6595E7A156F453291CA044CED810
+860C3B0149BCE73BECA713040664AD0591304106129600AF71317B0D2907839CEAC99515D357E980
+B1937B6E1200AACADA205421001F1B2F91753E80D2263C56AA164A74701A8D5FD28E46480B0DD963
+A683A1F355D7FB4463C7347C94EA5E2CA40B60B56297CB22D972C5BB10E56715A955605256C1541D
+9F3BC5768A6F355CD3B863F0FA1A781EDB49368F51B29481CBB41D4AEB07AF9DBE8F52C5D0FF75F7
+FB6431D37D6AED84D78C778871CB0F715B4F07580F23B586C969C81B471FF6A6C7276F7E141E02A8
+584D4B9AB00E7BD643D2C3FAAA299B1F1E25048461952EA42D4882768A70DE46B213A287F8D31AC4
+6D5436F22A796C05D1FE50A9BC2A928066627A0D87DD57A3AD91DB446404B41557D1457873482005
+EA20916BBE46C613F456C849D46BA79D20627B446B2F49E3FA309AE14F8C420CFD94922CBC0FB9D3
+5A0F7DBEF577F1849A1A80E0011DA8AC082A8C6F61658E65AD177ABDF23EE17C8CF0D26B9FA3A6E9
+4837EB9E930336889767A8D7EA3CE980A8EA95528B004957BE6067CD9BD8E02A0F23CC1762CCA656
+D33412FF45E917FD4A03EB6E8C1F43FDB0A8965A33B4FD26BC24A20B304CA817E88495BA9B361A3E
+933717FFB0271F7F70C5D3CBA1E86D0F51BF3ABA194DAF32C35C796627D00C7B2271ACE2463E37E9
+7B3C826CF3DB60028F240F9452CBE08F7EBCC5FDB1BCBB3C327A9F450B9E5671916101D6E3E5E458
+CA31F04D12F592F83BADA2C3683D3886AA3B403963AB5DBE220FEC00037A745839F67A3635DFD3BF
+F08F367482962DED88ECF6322852D643A54D5D303EB04BFDDEE9BBA1EBCCBA7C653B3A613A8E719A
+DEBE3CE1BD7E754E5F4977E863E3C2D388A65227B451D4F3A4F94E06513CBA4AC1F2F511613FF035
+611684CCC461599000E546E4D972CA6960E095A526E4735A23421A4C9B597ECE08AFA2753592BD16
+DED93255A1E33DEECE3C5EB77B94670E8137F2A4A4B98AC193258E7DEA5DB8408A806188F2D1DDC4
+40CCF0E9A6E2F0C78FDBD7B68DD4939D2458C1965BF8BED4564B32462FFF3EC892C03B11D3EA813F
+AB4CFBE8D3016329C5B7E3DFED0F08284D44AA0B7A2F6BC96EA4503E8EF52A64C22BED6B452581AE
+8FF8917D53976471941A9116A2D878FB2541B561767ABD4E31CCD8A590CA03494C62AFFD64EA0A1B
+C779173DAD84999C7A8D844EB1259DE7BB5B25CD023537A474A524EBE4660B22568949E624D8FEA0
+AD37F4CE1EC75955EEFA49C6BF1803BE87E9C9865FF3F6B8525B8C15FE8835CA153D27E6C0FF0CA5
+1029A7A9185D25F0F14D86FC797DCC1F99EE97E2054B9C2A2E06FDBEB8DEF6CDD368BF23A858D9F8
+C1DEFDCEAF1B4A8DE5EAFC604CECCF0D285BE00AA912EAB66EFF4D37AD2EFE34853BBFD87CE09B18
+749B489943EECAE7887B006FB827D10191DAD18466CD1F86505879310A8B171F902EA0C26A388E13
+B53C700272CEE2BFB47ACB58247C13449C6BB9D01232C32517358F1A3DE064D43C18F8827D53789C
+CF3CE2EBE78949A6ABFA1A6B8414CE360A5E22AFB7D1DCE6F5A06182C3B984B4F9BB1A905A9D5A14
+83750A1DE0A857CD5C06945EB7D4A2A6BF1237F32A154FDC06D51A703D44FE052FD3C53E9E8F417B
+35D1C851F9203A8997521529F21AD8498F96930AA77EBAF82EE02A57BC77C792D9F220294B45F48E
+A8FD94E01CD25645D36D168923562F3FDC93CB79DD4760DA0C103C2675722D7A1B79FCB4245ED12F
+A0DB52492C9CCE58B333CFEE822812F7DCA68E802C451B5CFAEBAC608B950386B6C58239D1C62D62
+4DD5D15782FC552222CCA06DDF387B373E32C3C2864C63C768350C37283760F3515A5B0AFD66C48A
+B522EB3E808C061F5CD6BD96CD18C9839D30508E7D4EDB88E8F11E31E10919B16B7971F06D7877A0
+58D8A4944C84FC6CAEDF3341B48B6E0D3C7B85D710E0C35F5B5053CF4B4798B3778CC28B2DC7AE0D
+F3A49F9F3BCD8E95D746C35C3F47D68B8AA35D97AA08E711B5FBE70D1A623C82541EBDC51A827D0A
+69E6C049087AD26F256EB7577F58CCFFBCCBA5A95D093DC29464C9A38DE95BC6B1853963B2DEB0B5
+7AD1248D6F1625E115EEB9510B5772AAE4E3C866657DB0B3BF0E0AC345E116F8D4976B770876FFE3
+748C36165522991F46A36F193DD1A1C94713673C7E4C81582391B636C72DE94CE6254374F99B623E
+5686C13D8A8322E83E11BB0B0A896C6A8C2C4F756C5385CD7017F26D23F7C3EE97372C868C8C9155
+81723BB6B76B4C3CE8998E4FA6CA40B633DFDAA59BA902A4952DA90EC4FC3CF0F2676ACFA7F76F78
+236FA2DE10FD3545357215246BB7E527F277C28B353CC6D79DCEF21BCC8F77603CDD58A2CCDDBE3A
+9802F941CED8E035313875319548C41992A2BE939A17CC109426E33825AE59BCD17CB19F50D972FF
+CBE7D9B4B0BB095303D9DC9D406696C2508D6CE99E11CF00F6461147E97449ED5F486D480A86D3A7
+ACECB7E9A945984724EFC21C5079B1FD03ED803C2DEAFCE3327D2D7827715FD65D9506216C88B0FA
+26935E95C64114A51919D419038B1A7E9C1E829FBFB53275093752DF19891A97F3CBF7719C1FD6CB
+17019A6D2D25360ECA804C4B35172662CC4769D2B785C6C87E5A4ECCE31704E59F71263B7C3CAEC8
+ACB4C7426EC25F11A0042323EE6C3EEB04284DBAE2C770BC419DCE79BD4560AEA41571C3B595F525
+60191DC7A8FBF63D413A77A0905E517441B16C2B501EA2F9E99CC38D052679F288FDF1894542E3A6
+6989A0090185EB2E75134BFA3D9147C3DB8A621D9D35E37786853779E157B47F71626D6B3E633005
+9159C17596C1B87FE2B4FF47ED9D78FA4C2160077276C8B58CEF5DC030B4A5D83CF257096C047FE6
+4DE307C598B815058E72D5F57DF5C369E664E137DE29349E2F9DCD8C9F4EBA6E765B6327D7A20DFC
+B20711273FD8091CBA605C4C494248076F7E03DF65A6A50164980BBBB708741E5BF6056E6F996DC0
+7FFF408C5B8EAB8DCEC315E92873228C805D4440A6470E3EE3983758DD211C9CECDBFAA4C9300CBA
+00608A4B2404A3C7AF017A3B7E67F39F0B51ACF950D3E75CC7BC2B8D3480202FA958E8EE0B240501
+5232EE0D264C7CA02C18CA45CB3C2DE322D3EB7F00F9455DB6C5B1F4E59C3E95520EC36D7D903CBB
+625D70B54BF6F8255E412604BBB29FEE026CC660577F91DB1DB4A613EEEFB20CF7AE3CD89D565AC8
+38416B01B5DE4FFA5550D17FB51FBBEBE21CF1D56038863EE931B90DEC2E211ED42BA92EC244D4CE
+2C4EC5CA87A026992772DC2AF754FC982B94F36EA7B7BF75E0ECE90CBB2A6AA1A012E8898BD679C2
+3CB3827C35D5D02F0569C7AA82615D4AA67518ECF668D3B57D6EF1A8013424AC2268BA0D9A74D588
+79EDCF6382A89D397864940303EAEC45A38304BA8B1CB198967AE23EB81054BE74B16909A405E8A7
+799CEE3C270FE2A6DC50BD7370B6B2C8FDB9A87D88D5D40348D3984E39C693B6F4486D994778607A
+80A3122872DD65E40492107C71C3CF708A9717E9EEFAFBDDC239C53AA9645B711038E59C8B861B37
+411AB2039BEDF9CFD00F08D9C5D76154427FF5DD39878CECC5D7BFB3F1F035087185C0981F3C2139
+BE84872FFAD3408531C4EA9387B89F5E3EC779E8850D50992DFDCF9132BC551E985943B07618AC10
+D1150451F0844C0DC41D6E17EB508DC8689EC726400D5A7F6FEB3CC7BCE05F09228B7CB2C5393664
+D8DD9A4B96B1020EF25D70AA2D91CAE93AFB5F2BF0AA18CA5C599FA1A708EF35BF8F7FFEC9AFC1F2
+42870D028B2B1459063B493943EF1283829783E1010242E5CF4DA39D93D506F3892936E7D6CF1124
+70A521D397438733D053944CFF12D6FFAE8246F20618684F263715AA98E15D72A526383E05C23214
+B78338E5B476F0981D90056E6E5D0DB66B1DF2298E597B2ABE1D817E18BEB056E65EDB4234342D96
+00470B1420C9210419D834E431B82F58608C87AC361A02D0F1FE4B470A3D71E0D21BB87E1023D428
+E23D596CB9E1A2184403A16E36E644BCCF9BBDE27290485057E62827283E7380AF786BF395B3961B
+A5EA469C315763FA59E0F176EF81985F38B882DE56A74D128E256D1B89939728E55A92ABA21A6B78
+44FAC1BA7BBDD8B34A18194A2984B000380FE9F672E83EFDBF276FE797A325815B0F25CC95C97A9D
+ACF56D583486305D7C9E51A7E337D14E3B900333EB38FD93A99587DA2341B10C059C71CE080FE753
+3C0F059FA40E560AF9C4A41A4BE6FB45846FF8F78165E10B4AD40F264BCF5596A1E8EF8CB6EA4B1A
+3A5C69059AB1563843679ECB2511A90E8898F54295649CB73D277760D8D04ABACC7BCC6E777A0530
+E2067CCBC08673F9C8C178F9D672AC8A15E5367F0C5651B53E75E0CFA57C931746AE1A679C246D7C
+9417F1CD89DDDBD1173C2F880B7B3847CBCCEBF99F7122E832D7C9BAFE2B54CBAA1ED48158DE3F36
+238B76B0E67644A28AEA996DDC006F6AC0242E4B667639E7523CBC90A0561193C1AF34481C2EF402
+EE43A82E1EBF4E3D601BB36B2D95CD93550D61CEE7A94E72F6D30C32C8F91A61E964B1F66ACFC398
+7F95D4028F116E9A9A8474AA29C1C1A984BE0E393BDC41DCEF6A6F1018DB60D52024899D8EB5D55D
+324D73F39BFA47377B9E15B3B06A7585589FCF52A54684173E5183367E7B0952DC4BC2767C4C6247
+B1D6103E52BC7B7EA6298F454C5D97AC575F19C10ACDFF4E10C7D3755CFAB4200CAC545269FF1D8D
+B0D607C7AD47F40DDF257AB4E7D0750577003C13E4941960C3DD7B0774DDAC18E8ABAF8F53E03CBE
+F6D57B44F24CF821014C064278FD51B3427593D17694B4ABCE81F49CBB984C5878CDF0C38D1ED7FD
+99B0B9A3BD8D8FF6219588B3B8FA59D0CDD1D9B2F65122AB45E48F1757467B9204926140E3C350C5
+A927A2E700173053EC35D3F1DA2D7258714C97FAA857F0898917BD94625C6D1E2D77138EFCAAAF51
+7B17FE187A2212C24A881A2C6A647DEF6376ED80AE4175C5EE80921F001995B44E49F0D33DD9075A
+CF33BB03671C0BCC34AD5784AD1CDFED3A6D9BA103B3DDC1CC2DE74DBB576A0277715275218CD19C
+A8899209125266D8BF1286F881DCC2C383749D1E768D670F4099F7DE959EDFE852583183C9111601
+2881A56A24AAF020EA45CD5F39660DEBCE30AC1C7B8CFC60387B1B0C3E361BE612FDFA9F01B7E4B4
+A18839A2C7E0E393EBC5AD9A8A4EBC316A740C1C295D9EF5F4DFFA0667F9582C0BB837B142C4CFC6
+B1798E9476D0631111033B8BA75A10FDC800E2AB1E0E829632F869CFE4737BE9E2800759EE0831DC
+7D1195EAF80555771981DD6DC6606812D92CB8EF86447F5F6C6F626D0E265C67E52A6319189EE349
+D48E49DFE6A9E98F76C414A1E3217AE0A215A17E54AA498F4ECDC50242ACC7E2322F63BB2FF2189D
+057E7354E32A3ED1803116176B9B9D0129930F919E2FEC280B2C8924E49E7BB75768A2EE1DA8ADBE
+D4E3589906DF1B923AEF84C1BD327438B731012E69BB0D43A1842CB88BB54EA4516477F704CFEB28
+6E3EA483445AD4D74586FCF32E96D366901084365F693A53C5FB532FBFE7BC0CADC404C4985042D6
+8DBB90A6DCDA3531EE324D558A214F935CD9FCC9A0CEBE9B5FB0323F4B3820529599EF48EE068B5A
+CE85004FEA2984F0A86F5AC9D56163BBFE1142B774148F1EB0A4DC89C3349052533A7DE66729DB24
+41B82F8F7360111DACF69293C9B281A0534F3E9E9224A75C49A832F28B2E497262475507B6DDFA9F
+01CA0A6696E3F5AC7EA68595EBA0C2EB8A47813FF936D84AC1B23ECA7AA2862B793CCBB0DF9FDD49
+31BEF354CEC12FBF478559FEC29F81ADF4452E83963E56541D31F3691C93A50F0BBA5E9552C4F2A2
+3A6E53060729854A3DD71CC4308B91957DB19E66AAA18FA67055A950F1C2CFF78A03BC1A588CF624
+696068068719AFB1001C4581EE072113882D9052B21E355D401ED8CD24D067B99E616BDA5A0A5A93
+36FC499632B79FF2FD0DEFB096EF46B75E2D4E0F48DAEA239719FEC4D9A29818F5875FC5041A9EDB
+D26CAF0ACE14CC80BA49BBA59E918EB3D8F1E541AA16026585A2F72DF7D83541816DE46981FB3EFD
+0C30E458CFAD04C79421AB7C4925E23AEA07F9F018431C790002596D26BD9663B51B699DF53E4882
+CBC34EDE88EB55045B889B6062E35FD1E018BCE785157B85EC3B9CA6C85D4B16238275385B8285DB
+012D8FB7C9F5B946A41D7A0FB878FF72C39683144D8A007CFF631B43748F2D5FC690300F9BC0C837
+006B92ECEBE0605E8C3A4A400E18AE8997D1B45FEE10068E247C647CF82C6DFBE5E881D511FFA687
+B7AEB78546BFD07D5F7EC242DCEF4930D8AAAD8C6152B6642AAC325963FD147F236BB850A9966573
+9D06CDBD7CA79A527DCF461E33F22BC9C5DB00DA2BD3DDDD8C99D99793BC98282AA8872FF96C3942
+85D82D9419EB78B6AE37A5F519397700F75D624A09BD255B576E955A323E784E8FC31131F003B0E3
+024A4F58FEF2A6C043796201FC425482E1155E229D1B2D43EF7B0D22322B22EF5C9A1BE026A1C3D3
+75EDAFF99597E1E5477952A4E8D2ACF5D014BC00DC2A272FA62B6983E27D228881E2EF2B8B95A681
+CBE90C5FDE16331C85222FE2A16F0A3C3000A63E2E21666C0C119F8AF89A543D37977069A5ACF155
+6324F05204CE8CAD50FF4FB630D9CBBFC324DEDA584AA56A99D3A76FF55BDC2C2EA3A021361CCD4A
+83C7A5E2768D210FA6DE889FD48A39D679C94EC3C99A8D33FF11377DA7F6F1B71A2A05B302ECDE95
+4F26773F39AC881542F0D0969C3995C3519A8EF70B4220D86BF01BEECC6462855E7B686E1AFF1CA9
+1FB8FD8B4A69E10EE0C2AD94ADD44449506F9B6EF43641F2026EFF6E605C670560C2B74706FB949A
+A7E8CC6A2D0D6207E457E7FD87EC1B9092DC68B9143947CC8ED14AFDDCBF8FDDA228A76847F96802
+E561F67CEEFDE45AE587673983FC04C96744DBAA83F2DC838D633943C75DCB9E6410474EB27B348F
+26E505F0AB90878940E846C5E9F3C5FE8C3558C3236B1B88C405716949B8506841CABE1717474BB7
+C30DB91CDEE33B0F844811762FAEC535BDCF84C1C747CEF9B1FA61D2AFB5A81335BC42C06A94D7D5
+9B7EDE55BCF6F9867AEE107555CDD084B7684C2C87087475A39A9DA6347BE281CE5635A4D07865BA
+98CE26C1465B1AB0343F49FF37B4D0CA9F3BB693D78DC3B21925CB996A038DCC172527FE57C07460
+EF39C07D4396E7FA970D9F22ABD21A9C794B64AD96762C7428F59A8757C36D6C4FFB23216195A04C
+2A2C2E7B10EF7193931544D782FEE4B91E01119C5553BBC6252270A8D8C56DD62D448F5AD8DC69CC
+B45E1F17F0AA1E445129DD00F000005B23D38DE93A3BE55A4C041947F36B4E4536E307D0180553F9
+2E46B743881CB5D5386C48C7D5F84C2BCD06B9C501F78C7EE61FA23516791FCF4DB278AF688A2E60
+10A56692AD92008497487EDFE4BD5FA083FA544138B20D6940020887E35D46E093B71F7A04A67460
+DC8116B4D4839625D7CA6959D6831CD93F81AC4EA2709036DD738364FDE71113BF22EBF13DFE1642
+E564701E6F0FFE7511EDF03FE448C2B28C64FB7D54B94CA576E481FA56B2B18AF10C71F699B6BFD4
+7459CDE1869D0FD306BF489A6F42E5B2F05CCF55BB6B9526973D19CB134CA7F13F1DB3716F8CC217
+73A832568C16250B5CDB16DF24BF81D49F5B37018BD310262EA7078107868AB0216CEC83CEFCAB1E
+9F2C665A31585CA04DC01879CAA79AAA5AB201B516F7052B01B16BEE5606098393B0E5D9F9E5E3F4
+EB20F63C958E796DF41CF28839F5C62A0431648745D7837B519F3AA36BC6C08EF040CCF53D9B6D8C
+0C7D1A84D707EC57A3C6AC9A62AB37251A01A5ED40FDEC6F5BE6E34C6A91D058319439778A2EE5D0
+363E2E1F33463C33327D05FFC0CBF08D5BC457C7230448972FB9B4D0D782BA7DBF10D3FFEF8BF523
+6EC16D4DD6D0D870D9D5EB5C64C9A46A4F583D4F831FEE74B0E5B33A09ABFD4444929BD8F638CD72
+EAB99CF2E9551DF427683964A592E49D186F285258C5D5F62196A98532421D73E3495F82695FEEC6
+E1952C562D546B28618FFAEEBEFF03A57F4D855021F85B0C7BC37FCC6DA9AECA099B646B99D41896
+09D3FF2D56422F8C37E97640293EC7C90E3380887836F4938FBF495CAC14FBA5648D89282D8D49D9
+1AF73ED36581139D8BD42551E263E830EA3C6EB381D85C42D74C50DB0CCAEC03F535ADE92128A016
+0E811C34748309AF7604919B66CD43EB5CA975302DCB6076FEB6BDD6FF55976FE990FB0CE9ABB11B
+195403FB26E3D6C6A0DE1C5BE79E171A61E21F79EE8DBE7A832519813EF6B33EA098C2C32ADEA219
+AB2AAC8B093F40000995539D1276D5F2EF84CCD099B71FE4269BDBDB6A8D59C86F7D2E3FBCCF8773
+D0FAE97640BC1AD43CB4B992BFADFB09DBD0CAAEB8CD9DA264187C4F97300E9A6C9DEED5525479E6
+05C65AE336CBBDF4E5D7F79AD098F977285E065579B748FEAA97F2A753E1F962FCAB68D72BAA8EE4
+FF6691C23E31BC0F3E981A96FB440404856AE1AB32A7205B17D411D8F21C8C93B704D07EC594422A
+BC368CDA2B1610CE6A973F4474E12B78B532666797F5755D269772C9F5400B3BFC6C58395D38527E
+2CCCF29B56123F7DCEF3BDE5DC1DFC5B0293BB125085B1D2D929BC3EE84F4FAD571A4991C3DEE03F
+2DB3A3097E52B1A7D5C73CCB6148EAC62E8E36DE9A71C57638C6E4D5D9DED18174E8C390E50B4A5B
+913C074EEAEBE390B214B3A68F02862B9A296DB4B409769649E51D738CBBDFB7702E15C73C2AFC6B
+C37CE15171F4E822CF20EFE55D9F061AA43E648989628FF79E65932390CBB15D8E621333B18B11C3
+BDF96F841D7434E01AD501FEA964A75B248A35CD9DF9A37E48A1E5A09C624B93CE44F0042FA00D7F
+9EE89B9F7AB785E9C718CF6E7228F743271C2C9BBA17E5208B920E44E765D99D86650EB454B0FAAA
+112753AA1BD3A24239E9C5FC47EEB1547AC9D23731B8DC48B9707830DAEC60C8D3790BBA1120F776
+4EFAC542CFFBCD5C05F9510B27B2534B704ECD36C8B041FD49A96881302FFF5B0163A2DD09C751D6
+D6AFEA9170A4F4C4AB8D46E62F763FE1BDA51DD1CE4A27E772F3A2869155F762FF26B7AA6FCFA4F1
+292E56F03AAB6322BF867E7710C34D43B5D85B45AA68014AD7879EED051B1933E491496E3E26D9AA
+8B80A07BF2B94F1077E84A9726F08199887D66DE7A307BF33C30DD9CF3DA188088C03B2BAD09A217
+6B110DB2C868B53DA9A66C85737BA66C93C58A259860E294AD0191E3A72C73F40B0BD98699AA08DA
+F03587B78F391F3A4313C58D9F29B53C70785637BD0C58310109C54091AB0A34CBB0C478613A7AC0
+FB8F0A8B4645AC966395D8BA775262CD291136AFFDDF01C1D83DD4EB3B59CCAD18057FE7D92A8CD4
+A58F22508D9FD7CF356571F701BBB23E749BDDCBF8A317FDA0AEFD952BB18545610FFAD3AC143D35
+1B8DB3F66293375E0E50235F0D0466932181D377EDD32A5F0FFA4E22B5A0CB4F343D9A7E4A342E9D
+09DFF6C697630CD3971802C277A5590B8CA94BDE6B38446C794D072BBCCB724D5BC208EEF1B018D7
+39373BB910D668882CAA779C2D686081DE6A2606417B54D7C20E0E7F722648D893E4EDBAE8F00D6A
+6DA3712F91AE860C756D1127D133AB828E9D80023B50B162C5A1C5CDF70CCB3FDD7EA060ED20838B
+E1E50C4094C9E79E1A0187CDF780CAF45A725964F004253E034C5BE46BBF89D94631F1A33BAA35B8
+4FA2A9D08481C6674126CD96ED05DCE48BDA069D902D6836D5DFBA701DC0F98A863E64F0E312145D
+8DC0B77F25B43AEC729A1243B45B08CA228DD6101CAA2AC5ADCC8EFF84A4CA3F254176C2CC711EE6
+C273835D0FD3528ECA2A976B88E51FE347FDB60F32370B66D338931D6581630ED586F349C638960C
+31AE4204E89521A96E1219E696B913DEB2AAB7A3B022D06F34FDFCB810A04E60A4FEBE284C2F063E
+0AE9EDF87704921CCFA193BDC912B747E13570066223A49F1F6E2AF0D4D65DA04CA876FF7A462FFC
+9C0BA2CC545C3BD36DBE762F32B2D6BE5867C59F479195C92440DC165098B74EA5C3AD93CDF2D410
+B04C16BC7801E7956F4E5107450787AA592493171C3628E6B8F49D4F8429EB98DC52EF025F001387
+BC1A7093F7A99F10B5D2D7DD8BBB393BF6E56F08F4F7FA1A343F220D5A1EAE7168C74D41BE1DC1A8
+3BD65B72B982F4F7B34F24F97F9EC9A91011064031FACFF2A14921A32024385F4E061CD07D152E74
+1BF97156D951A342488FA7F5EF934CCAD13E2753A0AB7A1F565C2F7F6B349DF03BBC25BBD972A9AD
+F809BB5C5048A8CCEF9297B2ED3324D18867F293CC66E88B3A39D107B610DFE79A3B4E83A96D3D52
+A17FE8A62C9FDD271130148366942C9CE57558D023DA5F7501319EBFA33DE9E6D1E76D7C20DB8A09
+B657839DA99F3D8143F1EE6253A3295C9651FA4366547893C2DC7ABCBF4BB7609DE5D001E0A36D9F
+FBE01F7D0903B3208AE8547E2E5F14EC1AF4C2535CA8F4EA37E3F3CE172C7A1E8308995B1CC23E6E
+81190246BCAB6E755BF868D449BB02A2AA87C44C9CC0F571ADC72547CEECBE104BB274B8AC16DCB7
+5D5F458D356466B921ACDEEAE384E2EB1DF6EF393B41B9747F0A4FAEB4AF1928D9AD6FB7E06FDC62
+1E4C6FC98CFB43F88584BD55D9B97CC9549093EDE586912161931162B1B1D52D0443260DABA02AF2
+B4432100D5506546013DA703573FA8013685CC798CE501960093DED713FFCCF89CA2B9106390198C
+29A00864108CDCC1984A8BAB53919028C01B26ECC7925E38CBE6CCA8978EE21C2B06E7B3E48FBA97
+8E2A7D186E563C088F84AA23178B60E4729EE87D67B1091F3B6973676C1CBFE6530EB773C62E2C24
+97014AB0E8B71A1F4E86A378AA26591511BEE3CF3D64C94848582E1354E1605B6457823F2C5E640A
+D3802946BB2E7E8E594E8C04B430C2385DD40746CE8534F50842E74D7115F3DB0C72D1C9C607C657
+3B094AEB73B7A79876CFFC3E2F8C9FEAAA07D3BFCE05B61F7749A8793BE90CCCECA2D7077F25E899
+D3331FE161A7E86C842495D584C6E4A0880B2951D8A13B88C4672080A0B1BE36BF47C3ACE7288CFE
+41A8C1BAA6F0814A947FBD6B3AA72B6C73A8C578CA51CCC96F2352316C467BB960E981F2B6485BFB
+44B577E71EFDA16E7405954BC7C9F0759F5A9F1EBCD2FA9CC9648D5831A68887F41B15081A204C24
+B4B992A231DEF9E698D4C3A25B6F5474F5BE6A601F2D337A58A0D21FF37FD91EB86D1D738893A03A
+69F0CD743F611CDFFE69DB2C6ED0E4611D56F803BB0DC06E7FE85A303839612707647B1BE9FAF8D6
+84122CA9E5CB8BDE2936D3F4FF254D31529D7538BBD4D35539489F9E7316F24214B996BCDCF1818E
+749A71CF0E8845AA1E2A58AA62A48E02BA4564625D20AA220EE719608521D7D7A7FCA0BD8904A401
+9819D371F3F59D46C1354E5FC1A6E5F79B20CF4ACA2BF0F2DE73DA193A6F9ACBFE0B4731C4BCEBE6
+D96FE822965DE965232282A3A130361F188B3AABDA95A8A2790D9240BE008B6A6DE4BBFCADA05B67
+86B9BB8E0DFA0C30043A3B07ED46277E07B9808422C8ED16758B9C396F4EA929D769785B2C9568E5
+70A83B989B25CE200F1727D41E2B702E7F88F1784F4C83FA60A74EB26B2DA95126E508ED519A61CC
+151DB6804F61826C5F86D8FA89D06E526FED97A0DB88EDB432FF32C1ACC9B622EEDF601081AF7B96
+3C9CFC1D13E4A9C74FEA0A1C8E3D8653CD92A944D4CA6B0D306619AFD503506D77732D6514F604BE
+4610C2560931BDE0B40939BC1D126B0E97F72AE1B4A9252123B54F7A27E0CFA4425B4546526FD741
+CA77952B10D13E0AC2E32006A903808FF0CD013F936238C74CC75FD915244C56A8412F37F0134840
+347699508D6F3D7F3203A25B7C70100719582CD588590EE34B3AB13E255B613A6D00386A0104CC5E
+D2C646F09A88888D3751651D5646C5227A3C80E8DA1B0A331121DD2429F1F4775D30564DFF47D01B
+BE2C6C72CE4D1FD9A2077C04D2B0274B8916F6A9D1A4A6964A534F47CF241D5A8E34B23F85BE9ACF
+FC2FEA961F277539F215F8728D6788F67BEAF45502839BCF23D8763C3949352F00C579A9A4FC408E
+C625E310DAE61512DFE6844E82D36A2F81709E1F05B38AE9C222ED62C961EE63593CED7AAF73CE2E
+D3667740C77B309B93EEFE1B4BA65D48575A66BE86743DC9E5D3C2FF418D11F7F211B86E827EE1DF
+C3613E7498030F07050524536D1F8A94DDB6698BE7B963C55CB3F74B676CD815A7B3DF4B1A0EA2BE
+1B0B9A11FFBFD5B1FA49668AEE14629316AF436A0821C20BEEF7B3480847934A99F6D85B68F4DDF8
+859A754E009428AF89A90D1852C220A607FF0806E8080726EDC94D691D214B4521C147C4273AEBDD
+BB4A697EF16448CD9B2FC95293305858DECFD406B89B9F3FDAE2AC579E80CF321EBAE5701FB2F7CA
+D8ED04B4A63115886D45D6120F69AEF1A21D80AD3C2D35D2899F1902242B96CD349E0AAADA40F7A1
+1282B6B52BDD97708E58DC5E2D22D1153E5FA3F3B300BCDFAF98DEC2F4E3C82A1C85F985735F3987
+4F557579F422664E07CBE19DA680EFB0FC82C323EC5C4644C51709AC8D674608A8043C91E6C7988D
+430F10BA6CE1FC7FC0604FCD8F723895250AEC36CC35B3FA14FE2A0D24095DCC30B2093F2298F5F0
+A97676A0BE66C3DC9ADACFE2FC0F721A20E945AFC1096A619075D5E9A264C796EC6C90EF1AEEA8DC
+089B44FFC13D27CB2370070A52D4416C53F364393E46EDD7EDE00799960CE6E0D57E4909E88ADD64
+BDD2B0EBE2D73FA6ACF8B40280DAA0637E705C65AABD523B8815F22F23E9FF81E7829C7E4BC980C9
+143AEBE1A04DC0D253396BBB7268BD5AEEA356B610D5DCEE03135E00AE34388251F31714A1C40E18
+2652C48CDA2211A22CB6F02490E69A44CECB169754C53B16028D352E0119F5D5FAE0BD7EA1CDA647
+12A6147374B64244E21E9EC9F0D1381AD22D5B6212B26C3F9AA5F6045F25DD9F5EB4489EA39B1945
+331AC70510C5752557DE21D0A6CFC1EB10A98FA867B76DA6E4249469F591FD154D39E89364A43DB0
+07AA0D7A911CFAE6CE2B557997FBC44F55A27F622BD7B8B10EC9F5D10F2649A646FD964AE1B111B3
+5B46A252C4DEE44E7426EB5739F24E8A390694597DB3A1FE7800C97E59558322F0E49A0CCE2AD94B
+1E2D1026AFA771723E3F523916F55ED866C9FB4A2F759651C613A2CFF362028CDF9D38F05D4C7C60
+24C533E930B64B099FB1AF04B01F5FB9CA6867E6EFF55A772C5391831059987E10CBF987E3F378E0
+1329F73D54DC0484177D3C3C06F67397955FF1CA4EF8AD1606B70455255D631A7D6EB92BFDBA14A0
+FF28B2ACE7E81AD666EA9B3A0F5A6BA3B5DFE35044FA4B3D8ED956009C60E98CC132F2E84967F4A9
+8A67B336D5EE7CAF7DD1F74D1FA08619941361FA7312CF225D89CEF97E864C8369EAFAB94D97F056
+5505D825972B754F6729596EEA91210B75DD8F645382ACE36DE60819A02B3B48DD00F5485F9264F9
+FA926D732E2C267B0BE8CA98526F124F97EFDB86132C5EF16B103908172FC51F286FFE45FF253512
+E0033F037FF182BA536A9EB2DF2D1DB257D9C86C46E1B002FB32AC70CA9462E6EB48994752CEBCE3
+9F08ABD4F4B0889283E55500702185A841E328
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+cleartomark
+%%EndResource
+%%BeginResource: font NimbusMonL-ReguObli
+%!PS-AdobeFont-1.0: NimbusMonL-ReguObli 1.05
+%%CreationDate: Wed Dec 22 1999
+% Copyright (URW)++,Copyright 1999 by (URW)++ Design & Development
+% (URW)++,Copyright 1999 by (URW)++ Design & Development
+% See the file PUBLIC (Aladdin Free Public License) for license conditions.
+% As a special exception, permission is granted to include this font
+% program in a Postscript or PDF file that consists of a document that
+% contains text to be displayed or printed using this font, regardless
+% of the conditions or license applying to the document itself.
+12 dict begin
+/FontInfo 10 dict dup begin
+/version (1.05) readonly def
+/Notice ((URW)++,Copyright 1999 by (URW)++ Design & Development. See the file PUBLIC (Aladdin Free Public License) for license conditions. As a special exception, permission is granted to include this font program in a Postscript or PDF file that consists of a document that contains text to be displayed or printed using this font, regardless of the conditions or license applying to the document itself.) readonly def
+/Copyright (Copyright (URW)++,Copyright 1999 by (URW)++ Design & Development) readonly def
+/FullName (Nimbus Mono L Regular Oblique) readonly def
+/FamilyName (Nimbus Mono L) readonly def
+/Weight (Regular) readonly def
+/ItalicAngle -12.0 def
+/isFixedPitch false def
+/UnderlinePosition -100 def
+/UnderlineThickness 50 def
+end readonly def
+/FontName /NimbusMonL-ReguObli def
+/PaintType 0 def
+/WMode 0 def
+/FontBBox {-61 -237 774 811} readonly def
+/FontType 1 def
+/FontMatrix [0.001 0.0 0.0 0.001 0.0 0.0] readonly def
+/Encoding StandardEncoding def
+/UniqueID 5020947 def
+currentdict end
+currentfile eexec
+E98D09D760A3C22CF119F9DC699A22C35B5B35ED6AA23593C76D54CABB5E942BF7D6DD84F1664B89
+699C74B472DE9F8E6DF925F6C4F204E9F1C639B4DBA988ED2AC419FF2B2BDE605B8EE3264EDD6641
+2D4F21C64AC522BDFC7C5502F9C3F3E5592B3B2093D33C9BFAEDD2D49E89AABAA832E23F062E91A2
+5032519D1868816E44B4E0747795003D7930299D6E1E2A5BFE0D595DC97E140989CE81D8D7F852FF
+9CDC7A1B1B598C69131DEE005B415805A16D8A123E6A208511C6D0C255B9A5BB2FDEDB4D399C6CF1
+94FFAC236883767C0F68F4EF84EE696B677DE704EC3B097384F2E673A1F51692B7B260693738C211
+9F7D90FFDB21EB715FD5B8134FC87DBA320EE54C2CEC6A4D6BB350555EAFF2EC4F84365CCC0802DB
+B3BD0E3F0D9F858647DD637725C2CAF9557FDF842A0DA6A0CA0F1B442EF8EE6CBF2B03858468A466
+AC5883CBBD3815B283343B39205803C02C917D06825C09E2BB14609FA32C28D720C0E14A4B12D4F1
+25FF6281FF324DA33A56FC49987AC7D3AA206540F8127273FFE9A3DACFFE2B1C269D3DB9A811578A
+C7D532C2EFC18376F473FBB2B32EF642B19CDEC1D6DE83643723E3C6DFC87F97A7007B6081894BBC
+45C955B7001EB36211B26AD7A3D07459CFB33F9C54A40A360CB802FD202C8E93D4DB888B325CE246
+D02D1220ABF55CE646DFB45F07CB848406E470362F80CE4C02D98DD845189877732744CC16C7F566
+9F77EF096EA55AFF98AA103EEAEFB971731EBF3782E6AB725D4E9E35B2968689E8007C038CF25B6A
+E69451A4731E79AC22BD268F56942A233E52D71873E83E00A1874E04D3B22E72FB2D0671AF81C698
+53C389B51F4A257373AEBF4DE2DA1E4DA5E2CA88941F81EAE0E32D982064C8AFDD7A9A600D56D736
+05B9463C6240606B3361BAF22AF74EF89AC804A5793BD512DA2D13F4BB1B73EFCA1E621ED2A65D66
+5AAD0AD228B3B7E3D90DBDB6061E172B686E92355A7C7459D83199040A368B5697DDC3B81DDAD341
+6FF4405E1096B1240EDC18A0E9985CA55A0D697972BB11E9F1BC30765D6775BB68C69704BE200EEF
+4E11B78ADDB6229D8FA49A6B1525ADADF17122C0FFF51A08AA7AED158724AC4352EBB91ED0C157E2
+4281BDC1FD610195F495E87062A8C38E0D046DA4067EE16E81BC5F87E583315B973184E474064482
+9B2A52E0D37E249BAB31988B906F891AC904D1BB8901F0673AECE60ACEDE97B8DB7935C6488ADE8D
+FD898027424AA85A11A3DA494498B084133B857017A6D507D70A3421235486EB3CF7613C59139FD4
+DCB92EADC60BB6225D9CD0599779217BDAF4813A453989B2E56903F4DBB83D83DF4837C86BB4C3D3
+CCF98F07A23EBBF7AB5687C3E1E6792E40F92A7A466DE352294064537505EEF3F9C308C9EB94506D
+B02CFAE289F10005A6E42D2DCE43731A7AE368564B2983038DAD6987F67062199018395BC0FCAF28
+7A2B040C71F7325FA1E9A9808979B2FEF19096B98B8A0A728EB98F2BA3D33B49E3C20BE992822C7A
+1BCCA5B4E4D1099D456D8D7D83C57ECBA0FF21428024F7572A1470317CB8CBC8679A974E13D88C68
+1338C68C9AC9557F97784F4E1C8C2E61F26023ACF46232CBBDF3C0BCC5583B935FE9FA09A562129A
+8927AE73988DB0F7E733C6561CA7C9716DCA9B88208A715166F2FAE6D5EFF289A9B2EDCE813403A4
+16F243F1B57EEDE7D81E10C2DA4065A3082BC92A38B2457368EEC9C3C17296CB09819E9E642D7365
+F9A6EF430FC7DD611EA5FDBDEDFA72634AB599EB666A5DC178B0A0BD1FAB042792115EF3B6222C12
+41DCE36CB38B738F68B1B3CB489FED9E53315553F3C5C3BBCE40451E47B7EA53FD3D3ABA6CE0AD22
+5DAEE734BDFA3BF1D81C1B42C6D856A05D0924E03F7627C5EB24D7FBEA3BD85716207F961B56803D
+BE046E81ED5FDC378F9CA52C14FD8544CA7C539201BEE06487EBDC30FF3B28E8264EC7FD5DA7E080
+65B0A9147344CE28DA5182335875E9F8B2347A44E33DFAA167232A5C3E69E8C5B58B7C7216537827
+C936F5741B87FC68753EB0D4A466961D0050DB59DF3195BD3379F5647F8CFED35DA952D7CF2DED45
+EB442DBFE992711D22EB228BDDF36B8D7DBA27062D60D2271EA8E8412F4290B58F5BE26FF06F0559
+872F9DE4DEAABA015EAB4904BA1F509F6D517C6E897312DDD571D769BC474FD378AF4360E8B1F103
+AA75F48721B9E0BA589319E15D74AC0B03D730C3EF708C7C504787483F134EA6297097B46D2680FF
+8AA50B7A255563C88D594B912F5574564A1371463674793E4834AF11D14C7991E7FDB3A6ABF8529E
+1A4F10CAE79C60D37429579093DBD041ECAF03824DF9C007E96F45595A524B27EF8774A83AEEBD3A
+7134AB4435C80944DEFF5C1CBA921B0A41B9651968581DA4834B3C0E6D4DE13C1E792FCEED26A72A
+DC4D9E3903661D8803DDB58EB2B929CE31FC9F50A694116B00AC9F3EEF53FFDB1ACA3394BF111610
+38F39917B022394C75A0D467D64B89A44E5505DED7D9C6B8BA6BA098F140C9C00E09200EB4828356
+A2D6BE9EC1D5524B09C06D9C6FCB5E2808050A339B5E5FD4DD6C2035A48FE9674520901EDCAD107F
+67AC8C8E508E6003011978D77ED225F361BC0F86A98B6120EEAFB73F7377DB1E7213E02D12C330F5
+492511B4DDE08558D75D5B8AA2D56A3111DCCD257EE96E3446EF1C76F000C8916C4CE261425ED9D1
+5B58CED128DAA6C1300466E7B152BCFB5E6FAAB2519B8A98F26B29F98133AF886A0AA7E586A090BD
+A1DC6120DBB5640885C609A8BDADEEFE5DE0DA5B75A8A29E92515E86E7E66BB29581E5AFF8CB6551
+D8D1103DF60D558E7987E6F56126A13DB2C9A04886C655064E68A0A20D1B7DE24DAD22BBFEE1B7C3
+C208D4FD6A58DE78D6A0A6126EFDEE3B1A9713DEE94069A9F0A2B392A2F391C4C75327803B53F252
+CC9EF0323F84929BA4716C50385681FF5B4ED54929821594F9026B7C1297941B178C3F8A704CE097
+60533DBC6CF4B18AFBCBAD039ECB2EBDC7838A9410E7B227924BED7123944675A5DBCA388B710F8A
+F6048B03DFB713F881EA0F3B191A5CD989EA150B979059C8AADE403855815D8F7980CE6288F47EAA
+37C1097D33F13776F08779063C5217D7408D9835AACBE5C071EA40C9AE6DF685F4A9827B828815D8
+F3A672E73A418E5CB15684EB6C6FE0998A386E124D76620446907F993BE16FE5AFCEC681F585601E
+18182EDCFD3024062A3082AF97E803C47D32229D0A24596CF7E03F18229FA631175699E2F0D60FC0
+9C4F1954C5D12D03BFB4395F0E5EB6C6877083807D91D93CA4177A6B5A8D2AA500131FCB670E7118
+73F8A3C77575EC93A3ACBA37EA117DB268CF10D04AD0F079484DB124F6DC14A50AD3B0294F7157D0
+837D8F9A6060FBCB385606066401708C041594E0396A0BE4B8B66FEA141CCE4BD29366A986ADB98D
+9A6935C49C57F8CD415E93FF8AE0DF75E463E02AAC68DF064C1B789B685F84E15E512404E065A39E
+9E8F5568A7D97671AE1602605FC7E4933975189837586FB1A55007FBB0E91382A629277C36A190BC
+85AF49EF3F0F38D4ADD2B5DEE09916B79690EC83473C63E92CF617617A66DF472A49641DA10654E3
+AD3880D060B02A4A6C75B51E4E9917A2B6D8EFDA12D59DE5A8E222DC7E82F02F23A9D3DBF637154F
+719B14114DBB102BE5EB76B441D7E9990EF6420C2E80942C8AED5A1D0B19BCE115B5929AB9E145F1
+496753DD6B1798324F5EC1D0C7F26FC3045D7BB46A14110C99BA07A45EC16002CB754C0BAE7A1A88
+EB387BB345FA70B0A38AB4D532C2DE49274D4F86F2582728A2CC54B4C09D26C0CDEB8FEE6A42885C
+6207D74953CFCC583ED82DD7C0F29D35BDAE5BB251B8A2D4B1DC97E2264DCE035E359DFBADDE84F7
+37EA6A59C23D1A64D963E635769233624F7682EA34636B595CCD064AAFF3887D916867475731BFCB
+F7F96D5E5E1FBE6AABF454C2F504EA4E8EB382911560195295C87793D5F7739AD7EC7176E126413C
+D4D1058EBD7D6EBEE14BB94A1ECF28B686411D91E07373E891F78C4C0A05D2E8D90A8AE2614F7FC2
+63A762D0F43485473A54C31726F8547701D4A38D20565ED1707847AED9C805780F062B847E668E15
+565CBA07A72B0BA99F03FB57D26FA26FF579C30EED0AAB6FEC1B5DBEA81AA88F16F0C9BE869505BE
+18C1CB79657D91D6706E2A3F0BE9920655B93EBBAE2B4D0B5DF6BE622C951F2CFA42AEDBF7AE649E
+2150FE87CDBF5C2685EF36051080BF39D864573A45AE2648AD97662B1F69787031B9BC43511FB841
+55ECDC3D91E2475D072BDE6A5207ACEA1E0D2ECB1DA8A1BC4BEEC335A5C7102963E84B97BE741C44
+58ACC3D72A7E53B1F08C955F33EDC3A0DC3E7308270C0F7FF814B111459985733C62E8863625A551
+837952F3CBF32ADCFD9F345E14B585B23ECC440775310654DAF7F41E56FF45F89701292019A94BF3
+0EB2D65E14B1A1D6BF89D4CC43187ADADF3F6E03A90ED01E5D876BD3AA56E5EE84DBAA4DAD9824DE
+9984BD45AF96FB8A56C010B3C3A3C6139D58E9D69D9109DB18561B55EAD6452497840B9AE90C749C
+155B6329716F0152A7AD52DBD0B8A25B9995E1416681F38FDBDFA443879B5C4C25AA29E0DCC07DE8
+BB161C36D76EF286EC88D57C74BF44DBCB4FEFF771D3BD82C8F4E233357C48E516EFE3DB9E60EF16
+8E2C45B54651DF9A5ACB5F1790F7929BCB16CE5E9F6A43919AD287DBC8E12D9F9E97E5DBAA592879
+1A5A02D39D259F3CE273A870906A643CC18D86E23F115D2A35DE6926053D8C84B940B362E7DB183C
+4905060316B269223DAD309EB5AC96DEBA757BEA45FA3100F77F4765334EDF3D659E09BD1A5552DA
+492BE9174DD406F8353A059ECFEE3709422940A8C369919EE1F22F7C02412C995FE93DC4559D32A3
+155DD22D3526D89B16D9ADDC30CB7ADA6E52D62C5F2DFD142D4D7B6E066671EBAD08F54917E31704
+1F410CFD8A3243F8B39459C418B7B7C6494551C6F6753A94072D09E0D812351D62916383C6E061F3
+5ED864923002007E626089772D269B298DCA2CC1F25D9BE43FD8AD62D554C16AFEB7EF6E5DDA66D0
+5A810F003CDDCFD2C02FFF02BB61344968091F67D3862C1499409ECCA137B9A2A9BE314995B818AC
+CDAE27ED4AD583BE29DDE4E8C2400C5F8152C85709AD2A4737BAC768FEB70CE81A92C9657DDDB2D0
+BCF9169D272A063C75C150ADDFCBC2F5F2503DE3D13231AA8CFB396DB38E80197A605F6BC20EFA1E
+DE40CF424CF221218D51BEACE64A3DC88377E4F3EFE43DB4F4FC0803BF61764104CFF0B618C90311
+98B094E20B0FACFB94240B438B67BA298E31D3F4E31FD190E48BFCE27B1BE29D36E765E7D295E96E
+DCE09094FAC43B87E294818FDE9363FC7DC5EA36A1497EE25762D02DFA00A9BE53F87ABE62E52ED6
+F59818FDFCA643042EC13D670DED1980413950EE43372D31AE2694B83DDA42E1FBB049F7E7B7E69C
+93FFA3195A2462423DD2C022E5141783FFA07E192AEBC5070F08B23AEC9142EED56DA74F93BDB504
+78DA55DDD0A9987FEA131E4CCA0EFC51064E4B37632728261369C3FEDACA100F1AA78FB718ECE7A9
+F56296C5FB43781E63F36B0E1D34BB748EFF35E1953941F94D1A9B0FA474FD68B47183F2AC53A63F
+9F1D30B9B89C5FE54C3765B43DB403D57994701C133E42B950D9BB1CA202F15B5E590EE75598FAE4
+3D5CF1546572770BBA9A6373F100CDC61DB4E5EBBE0A93E0E51C86005E333F69110B1C8E492F2BF2
+52CADD5B73E7D3EBB53E759353F1EF3C9B8B39C230D13AB7158A5D92EE4C452F81F6DFC18803280A
+A023832FD0DCB482CE5AF615C952BC3F7E58F6417D69775FC7C0D5B405AAC632857736ACF32B2EE0
+F2A2C0F3B3CAD483C614505BE94706322F2A2830FC5AB592907D0291ED1873377E7A6158140C2CDB
+1B0E27EEC9CA50176102200992308045CCB5A169B61EA0546778B8D280737319046716604945A21F
+2A1CB9E15E3A5DB31E0FB5A3B0AFDFDF6F3424B7536D473F9756CA3694DEE4301FB1AB1AE47128F8
+D2B461C051C1B999DBB010E78DD13AFCBBA6F7D5226D540527F17881A18F551B3EEF76A7E28B4FDD
+879381A2217EF2FF9F9982E9EA70AD2003B862D7C36D57C5FF9FBEAAB56040FEE973EFC3B34D8319
+1960010110BA10694C17B7635AE03CC1CD087C0B05522A7A791F0CA34022A3F5860B536D9551BDFD
+BF560A07F63AA4E687407E5E48584E689591F1B52671213E430A708C06A34D2E1D51CFA6B328A122
+007C81B5EB263B967746961BCFC8772F8502DD95898724ABF369B0877F3313A167F3F714023C229C
+5757D4D46FCD9B4AFECD093DCABE52B78132CE9AB6225C9A344C4BF8D96F2C50C4272CB9AA0D606F
+013B2642F8C880E08EA2822C8CF5097D2CDB64932FE195ABD5FDF36D3BE123AEDD8BA2F82A8A628D
+BE3ED6129DC0FDC4BE50D5574AE4FECC65062E70F4703BFECB35EADE196294FE173EA57938679DBA
+6D15448FF44C0D1A903B202439DA93C0B0E612110068F8079219AA89F435E44D0464F54833BEB338
+670BD820D941DF4B31F51B895BEDF833F9C43CB7616DB80F988CE72FD3C12C7D49F740CF85B4766C
+0ED398EB837695D102DEC16E24B7475A0F5DDE88FBF2D6B94F126417C811E8362B9CCC52D8891C13
+C10937AACC228D621D4712CB9DE0BAB60EDE2A97E9292BE04E42E6D3425594DF56931A61E1F96172
+6AF6E6891D63B240E6E79E5BF30C052091D681BA1102409874CFD8EDC3EE2BE331676E31AC00F807
+91D1019BB789CA4F5907F4823B002AF3581448C352BB67D80FDFFCD1C5BEEF60523330AA2C045600
+8F62DEB55E69AC2F86369FAB1ECC90D2487954E61117A90D9269A65DFBDF297EBD29C3DD1F62755F
+8F289C42A534F59650685F8576EA2FC5D26B99B8E3DCD3F1FEEC73131000F99AA9868EA9BAC0B56D
+AE2CF46DA6CC1D18C0AB8D77BECFF7B89992175CBA2E22779C13DB9DF53FF5B1C8FE95E164997D94
+202C37175E562C8622989B075CDCDE173452C064274354D5DB8F7D5A78D48AD4A103B9E47500D08E
+DC7C51C1F3CFA7F43C3686A3C24A7EB5018B0F419961564F87E212CE0A0741AC68D6822C7AB9FD68
+85F5D0B2AC249CB7F50E2353CC4B0A6A24562F564FBBC7090C3FDF1284AB0EC615E0B3FBE132F315
+70C8A65C814F93910AA4BB80D516CB70D2E1D11969238E6F022D628FA2F33A0A15C4EF0CE7F753DF
+80A8AD9494885A1B9ADAE6C38AC9DA6FB0A61696AD3A502630252AD7B574C841117D34BD20BD6581
+217D977B35F5D04E02B933E1E84F5C090F6615AF484D63265D28517BA74BEA8876FDA332A84AEA12
+E6CD82B94AE10A778CD3A216ABC08495EF319F06AD6FF8ADD237D911F846A514FDBFAA8A1EC8E0AA
+9F80F11F1CE615519A4B044F3D1CF1A17D7F3D2174222A5FFA8B39F20197FF6CAF250B6ADBDBF519
+1C525070C8D38220FB501C223F493D80F498621A02EBCCD6EFE914F16B2A435D60C0A1A453E288A5
+3D818FE1EDCA7D55A26A017F2EE47A816E90D6C3FCDF0035EEA307DFB06D2BCCE43458A67354A4ED
+B6E5C57233DE4FBE41ED07EE5EC77A5DFADC4032138DA9E1B74428CAD02A913E40152F8063A774D4
+FDD4070E4B8A6C089F199AF7C529C277E902195DB760D81EC655DFFD1BB283F3C5AA8BB58F2476BC
+797B2892E94414ABBE96D4DB93E280CF7DE23EB852E7CA954D6682A6F1A4BE0507884C2A05AC863D
+2BA73F3B54668397B6C54DC2F4183130AB414875F3C3D8792BF7E5FC4D228DF87748BF0B14178DB7
+E3FFB7891D700A1E9520D778B095DA80E4801F53442D5C073EDEB706A5DB8466FFE7E701ABA9C364
+A37169F585C883A83713A61C9C3BD9336A667EA4E3DB5F4DF6BC6A552BE8D3EF093639EC67E5FF71
+8959F9902477F5AA894ED2D1CD312ED82EE417D95C49C96671B23FB0E1738E892ADFFE62EC1C3D4C
+BEB6CD089C98DE8D247DF7ED17DFA2959D3662F105E8386D75AD308480536959F8E6CF8F2C6937B0
+9F2E8137C811327D6B165ABE46C51834A955FE8306D10033F8C2A34667F13A8BA831CCF52C7A21C1
+3DB92F3E77B55CE291F6190BB1D194A33FD73151C3F61ABD2D8A0C9BDE90E796BD996D2D0094DB2B
+E98657E751BDEEFE8A43EE4501B98F0CC6D80805189438872A60047A8CAA9039893530A3E5F6BD75
+BB466B25165737C939AFF3EA59BFF4A7DB09C2A5B36B8A1F0C6C5E5870C7C9412589877EF44F8428
+4B8A53B5B74315CE72D2EAFC631BC4CC2E5B71DC958B5A6350CB5F615C3A4502E973622E3E18193B
+69572DEF1D02303A375ED60ABA1BC8A179FAA0F221A49078FE15AE13383585FB45FF4D5F3BB3D0F6
+D8BF62E9BD6BAB3C9A7D38C8A5AB0BE57ACDADCBD02B1DC7952D73AEF702D406F62719922BEA96B8
+FDC9B879708E794891C7A0A42F2CCD6812C3F4DB030B5178E3A627C3E77621D312CE4EBE815CD387
+7208FAD92761A5396B67E835222609F823728B1C987857CFEAAE21F2AD5EA9D841212993508091A4
+A2C268BF1D8DA1C650F6AB93995E7C13A3F84DB55748C626FD09C0DA1E3325CCB0BF091E996245BF
+51EB486680162BAE63B6513C74CE83B92359938439921950D713C69324A87BCE67B45A030C9CF10A
+DFA0A82781D49FF224AC57A23C6CB321F95915C5E14E41FA852F66E1E2044A9E7B1DC3BE9E818515
+D28B2C4D2F2210098C39557067062BA4239F2AAE28816D999955910298A450741947A9A1AABCBD8A
+FF3530626089978C87DFC73618C044731B6DB8007739A9699ABC354A6F985E03C11D750B8B9E9AE0
+5436205FAAD1B895B159E2C90562B82A62EA1A7FFB501767DCE2B11C51D55A17529EF5ADF0A0EE9A
+96D0E7E89F68E50EED813836531B4B46E9071E84AA413F4135CC882CE832BF78ECFA7CAB0C9F64EB
+92C86DFCD1152BB7D4AB33831AA0C139B555967F6346068D5C3351A7A4368EEBD2933E6B9F789DAF
+37EF536FCF965C397AF1B7F98AF864B301F3F440B7ACF704B59540453678FD6C1504519481893812
+3E2F47B265EC4F5CF2172D394543D84CD4281165CBEB11349B315A85DEB2D1699507B0C8C110C726
+62EA2959C4962FF093AA5EE6F21F89B3CCB0149CEFEF1855B9A48D28BB363416C015A1F4EA1975C3
+D8807F616C5817C8162536176F464A198EBEE6C97029F15F414275A39B8219128B8C8542E9483550
+7FC2D3908BB0EC375771280B9EBE87E827811418EF93E52EF70546891BFC0FB34969FD7DEA4CE752
+4D9EEFF2B46BED908C0FB2E02EFC1D1624642EAEA1CAC1EB4841E020532E88E59AC890E6C3F44734
+B99722E9816402D1D0FDF8045C5481EC055100836EBFB48E9FBC392143032C909853C9BA38A19363
+141BED09DAF02FDF4E7CC9808321CD0708A1B45270BFFCC3A0D7C27F7E781713D5DECE82C72ED303
+86B02D14575A1A6447547ECC7FAAC1BDFF332C92984758E242256C054656CDD2C45D46E67AEC6F83
+9F95D74E222A6EAE12EFAAB723A7C816D4E42D4ED2725A794743F67597F3DB8CCDDE45BAABC25726
+B851E02E56341EBE69E4D91F2A233583EC816F18A1DECBDA4AB69320F55E730617360FCFB8AC2D2B
+737675B406297F7F8C4BC370CB084C22BFEC5FEF02E9AB290282F7B153F0A4B1AE569F1E52371A43
+46A748DDE09336CAD1F5337FC3D7CF0677091E59480AB15021E023E356B0E1BAC6C6471AD53625C7
+0206C338536F4D0D40733AB217E2297F86B593717C61458B6C93A16027CC886A8CFDC01EF19C34C9
+A608B95A84B6A2E31454BC03C10FA55CDCB7B1EB7DC16AC1E93981A46DECD7E7F00638DCAC568744
+69A2D9B45CBC81398727E4ED3DB5DB31965F358D8179CBF934EE2C4D652C9CC211807F070C80E3A8
+222B4C31FFEC8DFB9EE07A94C973462254BC1B1581903EE6F9AD91524A787129A63FCE048B45BBE6
+855826750C586B6B23B805FEC3E7AAAC079576949A06F422FC2C826BDB78AE96135E9E2C20C2B2EF
+F6171D610B2EB8635ACAB7C5C5ED9C9FFC26CD54D2FD4CB9E4294E178CECA1E16CC8E3FC06518BD1
+6F4D63AE2B435753538834CDD9D8AE7DE624006CE688938031336351A6578C304C2E5480A3FCB43A
+8BEE4953DABC30558B7790C6E7A6F0F9FFA557C50417407AC6A0DDA1E736F7070BC89455FC293453
+3DB004AA9070734C8C2608A07330E421A0220DAB99F8A77489132F6413ADB9EA637F3B75948050E6
+67276A55BEB09D4153DC126BBDBE0DB9298AC799A943D72AFB769BFA1488D311BEB86A907EC9385A
+AE4F77835DFFE4389E3D9ADED1B08BBC2B1ED6084B3D1074A326CCBF38E06BD026919107BD03BD9C
+30470DB779508DFE0DC82DFFD2DED749E872EB7EB9DDF509D5319865070DD76846C34E4E43691AF4
+29AA40DB4BF2CDD50B275589987D8081F7C5A0461AA5D1455A660178A94A0BA0DCB69C3CEBF5EE04
+26D6534F6F919D9795AD6A0E1A1F452AF3B4CB2EA54D6011FA809132421D111EFC51174E223AB6A1
+3596411A9723079231B050CEDAE7659CF168C39AEA9C6902C2CD37D25492CEE00096EDD63DC7643B
+667FDFDE5B595DC54F0A72C2650E1E46990584C78A5CEF9BFC3C5F88CFB0C49CD6CADD9DBA675177
+D601927D75C6902B55AAED0E9E3CB52A577C887D581B3CE6201A1C77C9546CEE5A13B92963337F17
+070E2BF9F5C5E86B84225863874618AA50F4DE855DE567BF2AB7163944ED43DBD7F4BBC0E1623180
+7C43DCB47B2EB694E6FEDCFBE26194D2D9943A1BFE32AA1E5305F5E341EA021F91532162978DD1B8
+C5295A5E7551E2DEE46DC2347C6B32197AF430AF3BB676A53BCA9BD1EA88678377DC0A9A86E2AB6D
+E29E3E261BFD5573C66FB5687BA9C0544D894A759866B066E1DB5C66E60AE071CC3A1C4AE40197CD
+E4EC723F7B80137619DEDC99AF57A5497D6E03C1C9E672E74F48F6C213A3CFACF2699CAE72345A51
+C71C1D69348DE5BC5F443EC0EADE1E76A8A33066922CF3869E3C1D26A3B34E540DC08EA4DA2DDE3E
+EB17C16790DA4EF1A3A76D71D34B788A87838BF2A5A3DB8176F9C097D2320050A79EA6C4A94926DA
+11ABCDCD26DBA09FD33F30AEED977E8B5AD928F3967F607628859429DCB4ECEC7DA3411BE35A0385
+1017B535985632639D378CDCD13B00FE537A49FD9EB6DF1E3AAF5C41EBE35721FA6833C2FE08AA3C
+FFC3477E7FCEBF9EF9F4DAE62FF78F319481C3F1E72999C8A493EC6EE295316B58A5CD62FFAB62C8
+96E521B678342F04BCE1613CF7F6778CBF5227BA20504500D743270771953ACBD5C6586432F3FA6C
+0987BAD33B88BC6C15D29C4B3CC54A9DD72A2357AA5BAEB2CB057CDCE72DC80CC98C62B16AC50B4C
+6A7641379B766CDDF990DBB2FC7F9CDBBA755B6E3DEA438FD6699C30A99A8B3178E6D613AA938120
+835E517431D28114BCA1AB745C11FE6E52ADB82B9D3D53A33BCC49740C93017D9531ECF43831359C
+5C93CB0E926DB440B139E3125CC2E069B1CF6D96EF68407F32DB517242C3AE0BC6723E560B0F45FC
+7F87A5E44E1751C8B7F9F669C24AD5CF16F84FB03BA121B86B0694234D8F2C9C947269AF96FCA08A
+78F736E4E04ACEA44C5BAAFDE360FCD8BA6A59724CA86160A5527FD564468123D302DB45173C1B21
+6B01DC5B6D3415B13FBDBBD3121A5493374B3357EFB131CABFE5087AA1D2C7472B0377066B3632C8
+2073C6A846285CC953A8F28E131CF587B35217EE498D9A1DB57B063CE068DAF55D8CC1771C0C3099
+9CA4FDC5D67BE4E7E69418F6334BC6149000821B89A7437CCDF9A6A0ED702D5968F1E04F7E4FE9FE
+C9D1E994885CB624035BBC5426CB8EDF0456828F8EEE75BE491B45FAC192A405EBA25CAA4F4C66C0
+DC234D7B417628DA5276C08260BE512B2432256C401A66E3B583E69D23E9FD278CD5F2178544D054
+16B9B4F61A88A4728AF2CEED07C08E207F31D644E8E3BA1E4E2F9D8E30936BCB9C6AEB54E37DB46B
+D64F2ECC1021336D0564DF0F18E5A6B6BA470233D8D41FDD9D1079706EA685B6D8A740570BFB78E3
+984BB155C3155C69BCCCB41CB51975EEA1C1B4294CB546CFB03DC31BF86EC3BCB1977E8F94A771CA
+B09DE12A82F1D6C791FA7800E5A21DF81C9C8FCDA78622ABE75B54AEEA747AA4F26D563200992E33
+7231A430137C720A17D44F3AD6CFFE63B2DE12D3184BD3E151F955786B8DDCCCB290C42718F3A219
+1759DF76371C2FC177544A6C425CAB14AAAB31628A9CF9D71B5257AFF0D59843989CF0D747375A26
+DC9ED29B66AC2147DA0168306C48C2484C70CA92F33C0C138F92F276F5EAF5EA3082A8A1CB12DB66
+1633C2F71E3B69918F509060AC949FCD52C36498A2ABB77D139DF1EB33E3B846A7C1BBDCEF5DEECA
+4EF0AD250CEA9C2751E13EF7681E8FAE0491CFA6C144DBAC1FC39D39E76EB12D3EE9CA159AA77D27
+94F0C433345B135BA632F544082BBDC9471E9FA3AED3A7D465AB7158E8AC97F68B1FBC8D368E2350
+45C18EFCCADEE98778D894D96301F903283C5AE355A863BB0DC5809158F7E108662D04A5C1234915
+E7BD5B4C30F9EFA55E702E54F87FCA06FB321507BC57A1E55CC117E21AA4E3A4DFB77C1A949EFE36
+6D93F2BD827EF8CC16D387CA82AC039F77FE995BE6D9AEFC87F8D809E90C1017803BCFA1C737DAD5
+F1A631EBE6894AD20C70791665E7BC71F21C2C3F4462F60FDE75C8A377CF49BE99314663C6ECB538
+B1BF021B2F2174D2B22CF6FAD115EB0ECE8A2E64097A5FB0A2AF666E1EE13276AEC59FD0C9D4BFF2
+3F71E835984E5EEEE36490C54E077AD7355DBC98BDD37DF29B3DDF8C55480B7349C4D17322418705
+796A8C521FFF920DD11773FC44FC631C7D6E9B420D7965D7F62EC7385F2BE30A51E2D796483134F8
+40AEC71FA19ED1272C27F98F2CDC9C7E54DAB585AC1703ED08F5F9E825564902EFD08EDF99DFD494
+44C21FA6BE16CB8A1B6D0C8A5ABF80A50BB8D055483176FD0AA07EBAEAD88FD694F96FEBD60751E5
+C4D8F9BC747D4F4030BCDF9B0370B7A5E0A6923FF60DEA16EF47F886F10CCEE6956ECF41A21F7C59
+6F3BC78299A9657266807E01762B2B2878E551914CA312C2A68D34CD91E4F5115EA1FBE801346E14
+AE529049089B6B0273E258785773A9CE8E4B6C4211CB7C2767319576758F811CBAF3A3FFB41B3130
+6C49F3798B698A47BFA2E3CA0251C4D90C0B02ACA28C611744526906791D9E157E54CE4E1BCF5B68
+6990BA8AB7897D624EF00EAB92CBAC255AE9177DA9F0D86447D35B452CD2F337147B5D3EBBF2B952
+35778A72914EB3707EA78294B3A3BC4ACB19FE87C72AA1D982E4B822F07B115CADF4D3E7EE3D1BA7
+08653BEC6F0A352A0C33252ED0630E7274961896D461EE8BF523D5911BAC1C8AC763E5FB11FDD217
+4E1F129675969C195476C7A5E18A81BF9A11ED9F2336D5301E3BD32174ED5C933E8C85D6272EA218
+52A6F7E2AAB174E0965F73E0EF89E906BAFB181DBCF8B1F5AA0C12D12C6272753C016AFEC2EC9F95
+41B8757874D6F2E061ABBE8B29281677246305B3C41E90418426C575BAA216CEE3C5EC29B2FDEE1C
+77C14FDF940792F48A56AE80AA33E370B037CB28A7373F882022AF378F26B6006A049FD3B35074A8
+65C97D153352ACC156992C00DE26AD21C982C71F0EDCFEB61593BB40FA5F2CEBF23C4FF34A4F4BDB
+73CA273C269242D1C6117262B7C47771F2619FE5710855134A80FA8F92BB2425CF88940CA3450F81
+234ABF2B11775929B12CFF86442B2AA0F4243D324A5983E5D1829775B3C7A111D5622D1C4E2B2A2F
+982FC8A95F789881416DCB34950A393F4F1720D2212F3D343A17683060182355DE9E4718506D76C9
+184F8DAC55788D7E603CFAF4907DDE965A49C323DFF425FE88C09AA4A4D16283F9B14AB9EF1BB885
+A954034710B4A9DA4C88A8A0932B18D139A687303EE562EC9F656F12F3E8F27DAA9C75DB0FA946FD
+0E1A982BB58E040BFC0A49A4AD8CD668493FCB573C849EC5474049A693CBEBD4D79AC7515047CC34
+7A9A7570C90861F3ECFB57B9F53AB9C0D6B05C8C570A8F3C04D58555A45524C98FF091B8F8A422F2
+E0E9E5A7B7FF69F1CEFC13E42F1CA276BCD584516D266BA6838D5E9CA9E9854F50C7D92CAED61AAC
+AF758A7C7BE59C3BAA82BF32B691ACA3E8EB171E08AD22C39FBE586A54E6E4DE2CD86B31138546BB
+8DA5834B2C6E4838547A1B67E651964E43988C8036931088904BBB589CA901E7EBBC094C0DA81E09
+1915D9E46828AD8596FD0FCA39FF12A6C27A359337F973809E81B2E9E3D43B3146F2516667E607FF
+EB9AC80FC95A7B7D4DED551FEE0F3561C70DB2D69ABA96673E39E3397F1C3F8FE5F48BAB8AD6E0ED
+8901F90F6CFF24E80CB5DCAC498506C4D01033E497C1241E413B022227A3264DA68BC3F91B35781F
+A2D018475C199F43CBA7D3A0D5697B45321BAD2C394B207136E1E16B41794975E8903EF2B2E1C33F
+87CF72C325C11EC0B92FD3890ACDF60B521DA32596763BDFCDCA837ADC6F26F129B23CA32F9CD39B
+33E64576970DF3C05B8DCA4BFE2F17E6C5678B84D69494F1DBA9FE0446AE6AFEAA1FF245C07916C7
+B7569E6267C42B459435A1D116CEC665B311E404171774C0ACC8DDE96B0D9167C8CC7D99C4240559
+2D745C4428755500EB4719340D2FC6BC215B67823F69FA949C08B5EC985D7AA87C9AC1F9BCC8994C
+6CBCE6027B7D1E0C22A83A5DE61DBA05D4AF6884C95F46BA7F253E0B2337E312916E163CAF9DB2EC
+56C5425990FE73EE53E42B3BCCA1CF642F02B0C5ABD529B568E9ADFF865B9DC190240AD78AD226ED
+884BED3C285B4CB0E3929E805C67F1318D186504D92085764B70DE6AB5AB6990F181BDA50FC31262
+348D980EC76608CF08176C2502E065AC2D8EA5CF9E2D44E2B70A7DDC7B922047C471DF8A0B2087D1
+106B5BD8A830EC0E53223CE3C96EF56E5541191167860EEA58D696EC357EC55799438C90156BBF2B
+13A0D5C9EE93227746654ED73EA5B9CAB61DAC5BC690F89C87FECAF9AD03BD39E438F43B81D39E07
+E0422F94E8B096AB38C88BC2E1A043811D8141C1A35DD3A6DBE41620E83C8ED3A379CD80D4F9BC30
+41BB44B933DACA7C5D4427AE94A176829F24B5968B713431CB8BD9F53080832C6B784CEA9B515687
+F121983EB9D9C9CE8BD4FA3BEC48AFE64E643B7BD86D8383D07521FE5D091392BE124CCC91113604
+3824B686988E7C83AEBF406D2DA88FD952D0FA9327F4AD04C55FEDBFBFA76ECAE8A176C516479AE1
+467125B7EB3C9E7C5B103BC0C470946346DF271F8EE19DF7E3FF7478C35EE059297F4BF21A5C7B95
+993BE6202E897776952A7ED0613A5CACAFA731FFC633CAB62963150E86EDAC796026CE02EB235B9F
+7A54E0B0C5281567138A612BAFE409A818C216DA8EAC5EDF9D1E3A1E3514AE50735A111B4D2AA083
+4EC6C11E290D58FF340F82F0E079F1C7B3566F2336EAA45BF72BCF88569988DB5F65D4C1E59B50F3
+41E45A899656A0B522847ED567B49CD5284FE50E5F8652CDAC1C076804F2B2185F6A51ED19DD4941
+2E65A0D2DBC844B75E2DF71B009776D9F97A4C6F786EFFEB87A307FB6B912BB659DC2BCC6D509A9F
+BDE87DE8D716040A8551B6CCFB7743978AD992D14D2B85CA052E87326138DB196C24593F8F7ECD6F
+486F85D1666B9DE2ACA6C7900044EE369D223524664A2790B773F9EA26E0A4CDFD709942A44298B8
+249506EB9B77BC887DC0EF947DDDC7CB3CFC6B48F060DBF032A11884E6C226D9D447A5A458CBA325
+D57E144C6DC295262763E7BB8FF6A0CA473EB7661C12E0E8E23EA37E8AB3387B9E54686F3E57765D
+4067E521BC1AFAE52394227793C737C19208803F2F2DA920B553E2AAF94EB992AB17E31B58C15CC4
+AA8A1B444DF5B3E7CD937CF03E1F7FAC63342731B4589F16939D16E8E497A74CDE5686F529E9495E
+1603D74875288CF53271DB9313A4511B104F80B179FCF213558970A002E945281BF3AE51E668DD6D
+13D9E85152747F562CA0B75DDEC8FE9FE31F8D05B0F59E802888A7A4F19B29954A31108D2F041367
+DEBD6AA1CAD856BDD1427E9EFE89956FE28D500CDC6A0CB80A76902A08D0BC6705583243F1DD8020
+749B257EDF4803BCAA653F7FD6D8B91690995BA5EA3EE92FCD367C11601C6B8ADCEDCE67B16C596C
+5D200693AC5FA15D4CC6CE9DF7A71C8A925E99F5085313D60FAD25C1BBAAD28D4AC2B69062D68F39
+0530A976319A3904CEE44DC9451E441AAB4780425440F8C499B81460B5D3E268974145117ED843B1
+71BB14AA84C3A084A7D8E07B9979260675D5CE6534DC176DDB60DDE90F6A3674F67462EF78195F8D
+FF74FB5882B079DEE31FE92816F16CE1A70D07752EA25FAF5000ADF79BBE7D17EB1BD2F9BF6CDBB6
+F078CAF97986442680A8FC4121866F9CE86C385DE34E30D8B9768A0136D9EEF79A4B38EE99CBB9A4
+D32316564C9D56996E2595753EA71BEF684834FD030D38BB100E2332B026B046316A53270A96DAB2
+182E994E91262FB03D1AFFBAD623F1689228409884F91DBA153030870A7BEB2C7EE2DEC51875B137
+33B7929041F8D23A94904BD54DD4BC9B432DD0C78DD81639F46D686FFAD39AAFBD1B6C1A37E248CE
+48F23E12464D5379B4AED0D50B5A41577E6ECB75270E9AD3EA7D0FC09DAB271FB18B51DCFC0069F1
+5D72546E6C51049F3425AD005F88FD7F02042DABE9F097F9D6A076B30D8CD777B1EC12BD163FDABA
+5972EAA61E3C87E9AC007A052B1A3FFE14D7D43C7A0ADC89B1DD4CB4F9C762A84A6C0701494B2D8C
+4E4E1A9245738BE4111805C2F153A20ED9FECF2DCF4C8F7C3BAF84D60454A7403D4F5F81C6404173
+A7BA81BB0CEAECFD493D877465DC5735D43E3102CEC57B8A589182FC65A4704661A9E351FCCBC731
+5A87E62F65D24EEB9CEE979C6E10DBCF5C162ADB926EC8CC9BFFE381F6B8A3AC0A19D1631BEA2938
+731AFC99E8EAA39BC75DDB3A39D01AD8F0BC1838F4D674B9BEE9F6F7BE4D9C8BD97E8D171EFF330C
+15B76614A1FFD25B3BE19E4A201BCC850F926ED51616318C965AD2F0E56F9433B1247C6D5B72EDF3
+D408A3E0674A509BF30BE813A5E669D72B978794683CA8B85E3469EACB167C30F7666DB5E081B81E
+E99ECFBC1704B9646B1A29E4A4CE5654CA8409ADD60145DFC54225BDB8485E39CC98CBC3F38FD0A7
+97E5DFC2099452A2418C6636BD2D5F6B24345ACFA65F4E7DBD2D0AA0C1776A4920B4466C509BB5BC
+7D6627946C4DCB38A27098B7B5BEEDC2B3BA18F927077F71E38644597719652037621BB350BB5369
+DCCC073954026E6438FD8393DDB3630C4473F06D9FB9E422E435566C396B12FDCD5605DFEA232171
+CD8EF298786806E9159B84599C26D4C7D8C3BB064665CDD072E2083190372AA808B2268B3FEC8878
+B6420CA829BCF995DC20E067EE6B8E44D2869D51BA3AEDD1763F7F8D2CFB8EC41E6E9E0129DE5343
+1457960CC51D546B10B8B6CE08A1C2B79FBA448DF9783D815608A16C55E589DCD8EF6B04C66232F4
+7A473973A35618000D79B8173258B7365C9691DDFE47B16EEB08B28F881828B946FB5D6FE10ECC6A
+FC4EA1F762E90B3320403382E42AF4885B183AA48DB5E4DFC9A54E0B4FFBF7C26EB17A4F13B4BB93
+12234434FFF05549E7587BA0373ACB3E31418BFAF400D8938FC6466B94273D1735306AB912AAB13E
+31DA3541C1733E2A7E4DA5B82767D37F3084AA7A7C488CDCA7ABEF77D19E42B4448ABBD346E9BC28
+8ABC4540C0A1CFD0BF46C5BC7454B25E27E9906A3E6CBF678BFECAD1B19B4E42398A210CD567EC35
+FB115D5C0DF0EEECE593982056B0E1D14C292F70B3E049984F8881C8B477956AD3140B4AA22256DA
+AC0D11C4126808B5B9F922BCC5F24A77FF352E2C621A3941AC07A20E550A69C49B1B87D116EE6F2F
+970918F0F1A501166AC4423FC212E4EC8039AC7F9C212D864F418CBB92948FBD588228108FAC1AD1
+837070512305C110F0FC3FAFE6E1529C2BD0DDE868A9EBE5137DFDFC5C12A3D08014BF0EE27B1080
+02AAD6B607F5C5C0F1B1EED3C552919C9A2E97204A8127F97B1066607ECFB47BA95EF2B51F007C29
+3B2F6A63041A9C1120D9CFCD5357222E5B02DFC73CF94CF9B5CB00EAF073E9BF253E30E09B50341E
+57BF245A746EA31BFFD0B00201C34CF0881BBD1006BC9BA7D420A48E53686B598BEDB3449924EBA5
+8D5DB1B1B01AE2BA281D5758C99EFE38ADCE18F7B182FBD0D0622A6EA497A4E7C00C7D17299A2765
+EFD8DE376C214D01A21819451FC04A0277EC84A151FF93903D61C78AB7886911E36E12526ED855AB
+43F6289C1890222602B8EFBF15782B374AC1E580B6E963403D6D15A051DB8558F2E61C0B9476C6DE
+5D4861585CF515CE951732F20D32969F39192FBF1690D242AC04D47E0C53D467D0FE4656B9526C0F
+7F852348B0437737CB0F29ECF9B54A5E17185236DD0C16349C3496F3ABA569EA20E343F6D771210C
+39DC932DC65ECEF94575C6E76902CDF6C8C8361F9C757A2577DA535187FD526699917CFE0AD438C2
+A758727B306BC7979547E68B94E87ED820614BDBC649D469EF6B4E4E3DD2EAEB5F80B22FE576CED2
+56495467C76A75F589460061E03F3A1B065121A5ABE3E2C51148B3DDC9F624C97889AAF7FB84B158
+C015EDA5670746C6359D27B0C2BD65144F2B88A64331816DA904572BE398E015A9924218B3EEF951
+23AABFC3AC8217B7B4F691219A1C9DD0A3EDD5C04E63ACBDE71B423522532561F4B71B7028415C34
+37E346BE728A415596AB749015C1D59BD8328E39A850CB98085B34B57FB52DD1D154F98FEC49B3AE
+BFCB1672762E4D2A1ECF02787F59DF1EBF2625C3631BED849B298C6D226BE4E6EA2AB66A287D2BA9
+2A6C9C612A5F849B3CB3C25F17164BE286F6E4F5E7E4C9EB17BC68AA5EF0190B64696A570442E1D9
+BDD1A30E7692524E30E4B4C3DF84481DCEC6E10E7308E65DE9D90099F3FABB3F4F766BB86CC98594
+6D2003E21287761A7386CD8461615B570BDA015F5EFA23D18E83C325EE444EC166A1A32D9818C2A6
+5A092D44156C06D3FD079B92450B8A491CBB3529DDAC7D95AFE8EAF33777FBB265FEB8A4B9AFF2CE
+CEFFF49AFBDCF6C4197497D3B448866D70EF28D8E4B17E7CE95F43F64BB48C4A73EB84B26650F62D
+3E5199D64DB0B5B87702650ED0B850FD5D16C848D096E4C7E61BC63B2A3ECFC099CD713E12C91A65
+77A88D6F55D348617C7A49890A86EA8FE2045704B5ED529DB128C9B19EE129E5FE6498CC97087F6B
+DE96007C9D01CE9CAF75646E5A5B32BFEAD9362A52223D746943A2D09C536CFAF78E601BC2D2F0B7
+63AD722E3A7AE7069D65F9F2BDED7278511D0120F5EA071D41A69F8C2A2D720D3B24B4BE61C83FFB
+EFFAE21B0560A6FD1A44E53E42E0D10E0E93F421A8A7E167BB65F0D7F1DDE2809FA3CDFD931CCC69
+B119C83238C1C00EC100D8E7AB1C7FB02EDE97073C8A5860371A8132BE391EB1C397B61F93876FEB
+438C288EF2E38DDCD182A5CFBBA994A94A1BF818312CD8234215FCCD7C240A15AC01A885E1179E5D
+7D6305DC2F534BAA141F25EA6A5F356486E5FA0AE3C6980A9F5E8E99E7AE5B95AC42977510970245
+4FC951E4319AE4B1DDC9B07D0998372C0A95ABA6985A4DBE6DC633154FAA30ACE689D36A7F17011B
+F29CEDC58A6692A8B3B0A5742E6CEC2F69B255BCEDA762DEE72F125EBA98891CFF4D88AAC14188A1
+8D81424979C9079E44890D94EE094D4CADDC1C7AC5F6791FAB8849CC0240A579ABD800EFE3AA4EE2
+F78119A3C2806C05C2B1F17940BE73984982D1C0065433A9BD658EA31AC819DA9A11B87475BB565C
+C294B6F302FE3F7752ED9B963C5279B5F1196762D0E12E6DA46FF9A0CADE3876D7DF695D8965CB4B
+47B351FA3F759811269376B2C3134403633FDE27C9B024F6BA81F3E1699CF64A426618428BA6C326
+6BF016C5DAA5FA4CC82FB6DC23FF2D742160518CD3A65ADB38E53F1067076CA1625466E0C64670A1
+564A54CE14DC5C57D24A12283FBCBFFD0FD594AC2A56EE58B552F7586825E4FB1EC23F8221711692
+C8C56F42272B87EBFF3865191F1C11943BB76D8C0CFC53ED452AE49404D2C8193ECC2A7BB8CFBF24
+870ABA38D2CCF7869E9363DC0AD94FACAED5922B324DC3B6FE83E7B34FE29ABC1EAD62B49FFBCB81
+1ADBB5148D5AC2743E3A058386036FADAB6FF071BC1C3B8023F908B6FF48DB0AB1C9C67487C35211
+D40995E1892C8B66AD6C9C6203F6F8B513B11117B10DA8725AB45B4437B5A88A96AF3178D856D601
+196E8162868A83DA64E408FDDEBD14D6591881EA652032CF2F88B3FD6C0479C8F89AC68D14D01AF0
+CEAFD95AD146E68FAE01A07F39E7A0C5E4FFA6D6A91D710827CA5ACFE7D1F946A8D7B67621D60F53
+41F32C12A6EFB03AE5AC5373A382C044A276F6B41C173D0AAAAE0C1DE4C3CC71EC2637225CCBFBD4
+5EAB92BF39357C57195B410F74283585B12B926438AC72AFADAAD2D0FA2CCA728C8E86BD3FE75D47
+B8BEB96AB13B5480F7A3D5741EB51E3E40C21FF2ED7D9221D9877C7D1A8CECF394E4023FCF8C4EFD
+B38B839499FF5CD96A46AB4FDB46F35D3B48B91757C0159328120E93CF1F2739E936E28908FB1947
+1D3AD7F6F1AD2BD1EC364986A411CC1B547D0CA104FBC10B1CA7B638A60E75485574034561DB345D
+DA68415146AAC632DFA34769B6ED7D7D4694E92CBFF4EFB16B55495908102E85E827FC623CF1BBE6
+A13CBF64E878E1A2A159948B5529B75E071744A5F0E50DF18C110B0AF117CE7F33F8C959D4C98CED
+5A9D492AE6F56DA57B0F17495DACB130660BCEFB064FD8309D965ABE8D2BE98F6898C1B7A39CBBE3
+E75DA0FFEF6CC3945CE76DA3BE915546FE8A5310130AE0ACAA9AB73C7E041C00533B4BC7724657AA
+649B9388B791AAC5EABFCDDDEA2CC67A0FD0AE9BE37DF9AD40636538EE55A83F60E9E026C64FBD8B
+220CEB46E67410144A520FCEACA252E8165448F84D8EA083C793AD09B90B3EE83B73FEFC3365C729
+E3C738894B8C01C2F8AEE0CC8B114E1175EFB44CC4C6CEF5C8754B1CC7CEC200AD8BF1189D741CB7
+5BCA4E88BE959E32216AD33F674F49AB20A354CF3969F1611A95D3934E148831AE7C81A7EBE3C524
+4F743E66A82E10D16CC09F8194EA7A596BC5981D833318AB4F7DBF2ABCE543E410B649D18D146F01
+486159683DF61A3F880F9B21EBFAB77E908C6CFC79F89BA5F51114F0BF7C3CCEC7BF0F3B057C3195
+CFBA6908E31E0DF10DF69163C9DA7BABC00E9A580FA7FAC202910615BD479BBF76FB8068630D1EC2
+1CD2926D351E869E16C2CF1E023CF04D4FC61607DAEFEEEDFF5593E6023492F00029E2AE4B4A2C14
+50954EFA2792F32B4934A768F892171245A1E2F034E2B9F39833F1B331A19A386BAACFEC8C929BA6
+B67CD8922BBC9DC005EC3976575D5B0508D0717C6BF11123EA36D8FD37FA77A6F1F5AA84D4AD8D25
+B2C11D1877A6E2F9B74F3B5829FAEFD4F7209CE9785AA6FDE68672554A6F29D8BF03FE108ED90A7F
+58690FAC399A8AD3A26899072B832874DDB629581A51B3325CD9EDFD49E890EA8959DB937DAB83C7
+77F2A426B967AF5888C33A3635B78D647AD6BA441E222C958EA58D61945F781D7EF409771B89B202
+42AD7D07C2EF592CBF413C5FC89EC30FC9EBEE4BC63709AE33B65EE3091CECBE610B847E12C556A2
+79C8B114C3E460822D3330ADFD72BD69F54C08A81848C2002A08326CF3B09B1305490D35AEE59179
+08E1604ECE75BBE811A715AE8AF7EA9C371B322D0428EDF4C893FDEA607E70E1B6F6614947326101
+EAEF18E29BE0557D2A92CF1FC1505E8B434BC368CE07CCAABC0774F8A63E1073FBBCEB3F4052462A
+A9008A1E53F188C9EAE339FABA74AFD6D60F47282CD9FF721F64BD51787F3C13B5A6C5A5F7861171
+0111F5E0471E206D72520F1DFA465F4A23C71DCF99A04CEEF11B0E3BDFC35B7461A60753D3AC26DC
+50A5956C9195A4F5226388E0953DDD03AF128A98F03BDFA0602CBBAA20AB9ECCDF7255962A332E16
+D4380762E498FDA4885C64FF5F9B480DA487C58E78943DF62616E6E2C69EEC8836DFCFA9EBF58938
+A878F3E792E8BD8C5D6DF557A5D82018DBAE1CA9C64BA5AF8E21BE1B6680FC5DB22422220B776E9B
+A0BF1ED2B7212F8BF111EC8C8C77B223C05EB5E5F1CFABD2D037F4BA0F9503E2CD83F4519D180476
+63F09E308883F5DA5228F83045FF41214D2273B2FE0A9017D5E0557BC2A198C35D1E7E81F7965444
+5760CBA1D3F05EA4B90658E53FDF0823BDB1501ED51DA75C47395073D8980D1E3504E3F67DB3259E
+4EE73A87CFD96F84E221796573958D364A51E635FC55478C9CBF9AEA16B7D8C25F2115CFE4B7F598
+54E24968833BA0D64D1D332A666DFA2A3FD71B05A26BAB7DA382907B13DE0B80871DF184D3622B62
+3D7E09BC32A4F6EA2E6DA450A906EAD36D53FDEC7F83E101FEF32F4FAEC581B000686D86A0D3861C
+1E67F18A4C4647F51F978484D9E3100B37BE9D20AE84C085461C1FBF929C669E936659050C2627AC
+1B019837BAA75757F5B0A82E8AE9CF2111931A38BFC94744E2FDE3F8710342AC615286E4ACE7F269
+743AA05463AF537D9416230ECCA859D8C99B7C6E70BE7FE11DB698589BE9E11900C8E9582A4EF5EA
+94B5F62820C90DBC022A620EC536E06CB8BE7526A789996D0E741AAD980880A33800A6FE92286CCD
+02C9CB407EB31FB95D9C9F4AFF38B37087AC582C1F7B64A7C3D2202BDD62E9AEB31BCA85C4CF323F
+03DA9D318B91F78FDC0D266630F7444ED068B55C05461C97552366A82C2E743CEC353D51028FDCF5
+403B3B74D379B82EB69C4380ED40239E15A86B2E5C860891E26781CC111FB5705E3B7C7AF1946006
+54B5FA1B5FC54FD0BA43666E7BABD2C91C859F393ED49F7123EDFB648A3D6152F2C17F7E438C0A63
+8968AC06B4FB3F77F64F358AE063820BD33F0213C85C40E4D97ED100EC2DA1C2E1EA258BF107AF67
+5A9D995F60BFA37222B9C2B325C0052BB8537D2B27DD43A129C7E8FF42757B3AC9B447703D382108
+DA520B8B3BB3E8C7295B776B44ED28F863B8E1F81B0BD1DAEE8A171525D09D2620C04DD3219D880C
+2ECC79282DD7B1772A9CBBCA706909AE8BC7798E6EC7375189B6CFCE8A875849176E5913B85A18FB
+197A33CA4B5B4058603CF1FA79A56856B43D538E9ECE117D99AFA73B57E307364F553644DE01EDB4
+6234EFAC13046B6E047ECC8F63942F20097AD7ACF0A45C0501A95263DE9439A880D6B5C5214D2918
+0A54D7FE9B2E627EF49E189B59FCC78745E878E45B46C0A648955D3EA8C935113D94F92EC963F66C
+F3CF3A526BA71CDF3CD4CA69EFAB08B7389E3390716892A4872BD29DC1E0889A42D7FFB4190E9A8D
+05D84EB9C5741BE6B02716BC75E0106F5F94BD3778BE985E03860D27E44088C3CB2A059DEBC420DC
+E3A8F4087A9548485E616C409AC400DD1C411CE4B6A229D091B253EB68F06E43511EC5AA6ECA4D6E
+4818D6AA2068DA1AEFCA377611BFA816B5215182432D5683294D67A7C1FD76C52233087CA44943EC
+7280005E93145F5E7AE50100C18364E1B36741E9647C4DC1F68A58EC44095920FDCF05532F603717
+80F78420077EF5C24D63E26040CDDFF8DFD65D871DB943F50CDE84900C1372EF33FD8AB9889C82F9
+4F61A0E6842219A0F39EC7B232CBF802C4A744F33159432E827006C7CA77E480A48A9B0E6A876158
+8A3102E3F98A77BBD62A3A23150FD140D3941773BF7CBBA2338FF37B9EB640558A2313E8824E8E62
+0331568A9B76F4897198A709F9313F4AC40827D8C3A71F2ABFF02BFD57D30D0B14012FB5C39B85AF
+540DDA0ADC27A85B31694E8D7B61F9D9B476571022D98F2D768246550A877293F3FF6ED918A498D6
+A600223E1A61890C49ACFB60265867CE9464F9C32C59E94F7641C3873FB4FA6EB237F8ED94579957
+270D6FD640BD9543E683F2372CCD7B60AAD269E03A72C5CDB732B128818D41A6DDD2BC139F7D3911
+F48E1B1D263DD4AE8E4CE1A686F3A00A2CBF48978631CD243566E22E68F8D7397134A3530EA3745E
+4F1EACB4D6A5FD84C3011094F37573F7F9902305020C53926716D4780C6B0A257BF711AD94C83F1D
+41A02C1C7DD203A3E6E4B14EDA2FDBB36B063A3E074495F626B0EEA146D22AC33457F44F41675967
+6D2A0566EC2B726D2F0540ABF225339F02F406D4E7A62E5233DDF20AE7C86CA0CDD561F33C422654
+BF2DC3685CA91BB9D4B09AC8B15A24A99FF56E2894F11F7BB4728FE8F0F5B799F74F475D2D01F61B
+7E9E0E541F7FEB8A557486D7DF2CE50927515D833BCAA1CD9BF7A650BEE9E003A5951C98ED147C4C
+52F64F692AB281984EE65A47E44A4A5FA93D6F18D276D3B01C5E5F6135AC6940524CD713DF4077FB
+4943E8AC927A68489EA52ACF7A854393CD027EB52EA2DC6234EF034F3DC742D6DB5A67FC21D22B97
+146B9C268BA97C30161CE01EDC69A6A1F05EFB0E06F22644E1A368F0E2C0C6C1C832878E0614B74B
+D645F5CB293CFDB7618B837FFF14A1210AA061C8C81867244305B80DAA73CB25A417228E9559E7BD
+52C119B0CCDB7C4DCE7E1B9F7E8EBBCB575E5BD213BDD6DB88769DACB05E5870232F0EF82F448559
+187423409EEF756BA6247493BE24CB1879B5DD822E03D0ADEA1EDBDD83D3FC46759C679B921F0616
+F27212903F728AB44C1784E8A7DCED0DF5625A7D3F48A20FCA34008184CECD145CCD98E31B79E174
+CF107E8F35C40C19D86B40BAEE6164353408801EDF75A619FFC5B6FAF3F3A95F64795CC40C1F8963
+4FD8C13852D265FBCEF834C800AB46E3E8167476B23CDD8AFF6E2F997C99A86A9CB30EF8C853154D
+0D89EEE9B9CDC1B4F27BDA32432A4173B55CA8D9FB50ACB2D886AD8E5862FFD5DFF224BA13C8B8A5
+4A7F1A9F987FBBDBC5A3C3D762A5BE309D5D926AE5093C40AA47B3B1BD828797CBB9BC9FEC9D19EE
+A73D2A39764816113A8EDC6CFA6E605AD578FC8E30ABD600658A49ABCD5AC54655D29C50FDB72070
+169D1B389F114B7C71EF95A80D82AB537AC8C165D47371FC142A51625029A990A577EB1618480D72
+6DA93C98E5C5F24F622A850CDD94BADAEA91D4BC32CD50CE69E9F00E77DEA8EC1D37916398FB7092
+402605359DF08AFE7B99C76C2A7C70383F28A7C000C696F45291BB8F074791798197CAFF1544C76C
+EEA8C9E6D76EDCBD92A86DF889481F3BBFF0865442264F0EA40D3CAA69AE467A08003F9C30FF7F2B
+77E767580575398462D5B1171DD441D8986F33BC7BDA17D413EBB6B7A32642E33F20B284BF3EDED0
+02352FC66C6F7741A542155F4A159CD778BE56B9492CD95115C1A06189A216CFD2E6725965A13DE9
+73765A05114D9A5A4BE0615AF8BF6A5EAFF84468B849954D15BEAE1CDD57C435788B331905C01421
+B50F20B184506A0BEF746330BC98E9C89AAA8F9D102F158043BEB6A682059A1C8B8CF67B2F3D7AF4
+D8BBE086254CDE53765E3226BA2F95AE8063649F9F94BD9519411DAF8A0287307335668190638806
+E29484A4FFBC1E46B1800E03B162C23B1DC0B4C0DD3C7ABED2F00762972EF06EEB9BCDC7B3F39C70
+BE32789D366F073AC3280C273DFF2979507671B3E1E7685A9A4F0FD3867F96DD675BF05F25ED986A
+79249B75F182FD73CDA2A6A66D693E4CC5AFE3402431B2C816DA1486C34BC9DCA4E2D51C868688A7
+787CD10ABB9ACA14B7181369DE89913CD8FAB58FC84519EA2AA14E54B7A8CE474F213E07CF2DE2E8
+88093DEEC937526816B71C96ED75FA9E2EDC0F9E6E84569C12BB8E39AAEDBF546630745553D6084F
+F9524FEC6A7264F88CEB7EC3358E923B392474E3A48865564431662988FEA768CE555AB0DA48BD52
+6A84B0CB17B4584066C1640C1023D91F7869EF0C4D701BE121A6E3C832010427490758AED7A2B30D
+6028F2215AA44E86D852FDC67DA5CCBA79EEA863BAC9EDC2535B66AB0E54EC4D4411390FDEB8D1FB
+C1743F15C3B68DC92A8659E7A892D5E53872EA51EE8CA7EF51103E87C29A2714E907C79DB9CF3744
+1785D2F73A1EE58550111A4D9BCCBEBF2E39CD3B93DCA300FAC3ED1ADD8215301E5766C30C8CF296
+75746C5A77BF1FE3CD75D25CF193DE8D9AF02AF8F7A6E8F84B548058CDD3C6998ED13463FADE7391
+26D83D3CE2C7201F955382832E32C10DCBCCA35835985B9A93F8E3B0208BE6E92428787C47D3808A
+0F77B8F1D76E6BF6A17FF81CDB065180E03809D03638307BD7BF5CEDBF64904E918FC805AC905379
+928B816480F6E3BDEE47042CBA98539DA0E113B1A5F23EAF1A3210BD18561985E6436EAB90395DA4
+77C7A6D7888D2377B3FC4169368357D880CE041E1F7C875E956600DB7D9B35D1EE66BE476E9DD806
+4CC02230276829C2C0A098F051502E828A0CC505AFD8C3DF293DA1508AC4D25866BEEE6BBD5A230E
+9C2DCDD4F06883936381F476DDCD86CCFE15C2CE3C3243E148CBE603B8513A7CE7A6910A66A90B70
+89E5CCD4368BEFFF2BCF8E918BFE0A1B069AB2A914CA7BB91A0AC3B3C0B060FA1A0316F6135E890E
+E549315897C8464496CC6DEA0F7E3AF43FFA4C3281156067582CA255B1D2E80F999A3AC0402BBD17
+01824C3BB524130F5B82A45275807BC2F3A0655EA208F968B297F98C369192C8ACA26BEBA7DC4506
+FBD1305E2EFA4DBE5375281A88EE2D6FC88FC0A755E72934B4B58F6DD3BDAF7171A4A3C776576735
+2492BFA9A7758504750AB7F38754683B70E9E293CB1CD7B23BA62BD7397ABB84D7EDB22EF6C3F58B
+3EEAF656E361747ED04020163253D1CF3F905B5E85F83FFF30AB2778CAE43781667C0F65C8FD404D
+6B9202A99EA76AF9AE1236631550B66B063847180B6DCA832EA8DC4A6EFDB674B5A26552A7C7D54C
+2799C7D4E03C24F661A91103086DE3A90A774A6988347656344CFBA06065AB22476BB09FB68F9928
+C0045F2764AF643CFEF0516D87FDE6DBF93BAE2829B176CB507BB99835E01BAD5E55C2F8798C93FA
+35EB3FEF02CFA31D3D21B030547F86D27B9448D68E2B155A65C742BD2999DAA0C3AED64447B9CC67
+F7AF33B63AFAF25F3CF7EF86657FE8F952288CA4B691D369E8F1935CDA44A180A6767560C2ED3F2F
+CC38B6BD7991D4170C7C566D690A8A25BE03212A80871108D18CCEFF246623E653107631F29227D6
+4754B2208D19F84E547799E691CA473780DDD56AE620CD953D5133D135E3D51F237078FEEBB73714
+54EE633CFE238AEA63F9999E32850E6C197687A0EC4E5908D2A18C5349627E336AB5E3185B218228
+603A4B1852069F5EE849D571B8387DCE1F8F8E9FE94FADEF128BA83BDD245F8C1C27C11F2ED1A8AB
+2D6D601726842CEE744EE7AAC6B6FA16CCAA39DBF5B3B1D47339F31DFA562671A9CF7DDE6915FEF9
+F19B3E068A464DD350A3AD146D1A241673B5112A4A8768F976723E6E184790C0604506C46591BEF2
+106C40789B733331A80740D59ABED39868F80BECC2AA21C400A0BD0CC326D186FFF9EB37680F1EDC
+32AC78F9059280D07B5FF2E354FED545129FA5FA8F3D4317FF21E027602FDB2522F049BB545FF4DA
+60248130F81F4E348373142F3148DED038AFBA818F26D5B49FC02DE9800D894E9239C88EE0EDE431
+F8083697CB0BE3B497473473E5714717C914A1A926730C249413FEA2615EF72BDB0906933387A892
+370F77EEBF62D26CD583EE643B02E323821379C0DC966407D36AE3CDF646B95DEDC7D7FD0F28E950
+78F12DFC0D6400B327B743C548A0A3517A175A7ED963ED756B1E107AE7087E2446BA702CD4E26E2D
+CDC1A8B697108B5B5E81E9F03105F220C72D4AEBC57665887C8C7964089FBE9424120EFDB14D76EE
+F8C6F7A30B13E1AE90CB9D93D2E14BDE47F4A1D05ED5B18D32AA39911B92D24C93976ACEB7EF597A
+75161923A73B2CC761785493D0EEDC08B5AFE95F3C006B41438A0785C962B070DE2BD096CB63B847
+C87539880AA3D3FC5C345E0992D7BE77C6CFF4948617FDDA784CC55652192B0ED775129C4EA4245A
+41BCF3875BE319DA0EE2DAFEFAE920CD2B6C6C2001762F88C0C5C05053025C0349DB17104360FCE1
+5D7F3A8E30ED13155A74FAF91DC77B8AABDD6FBD5A1EAF255DB209D7F2B90822296B5603FB5E2CC9
+5CBC5F7A6044058B8044ADCE73ACFD896177F1F70EAD2F6534DC3AD755AB2BA87126D63CA2E9C441
+DF0965BDDD6BE494E58D6B5057A561D1E31BD38E92CB73C1465AF6B9C001F7229059BCA4104847D1
+639E124E082F7364B56548BF8112D0EB461B316B2449049F6A476D36D6B7C0C1126C08F2E9A1246A
+3B5B21E7C8FAC6E23B82E33A7783E4F31F0240E96E69C9444E7D7A928636CFD086475DF1E0A28464
+81387BB2010655B9F81A0744121699B4905AAEDCC84BC5D5AB3674601DBBB651EDE7B5DF05C8A463
+DAB41F79706D285C4F9063997F7AC8CEF35CAD51FBE5F5BB1B3FA6DA2C3ABF2B3E925581349728D6
+DA0D59C1EF6444539742EE9A23A5727F20CF9377F4F84DEA420607015A30FB14632D084A2DD181BB
+02FC3A84FC499B318156B675B9CA3CCABD87FDB2497C6705FA70EBA43ADDB6CF961B30E8F6AB9F84
+E1DD8D6DB3314B34B7F7AA3BBE19D5BDC75ECADFD8EAE19E07B387A1FC586F0F30DB695926764B54
+0D89F1D854B0FF86528AD9523CAF56371E29498C11AFB2F4D5202670C834E930103F039D13348824
+16A49BF93B84FD3CF1209EEF7D4994C8302436C0794497461C11F5B8BA152BACBCC08AF8A15F4A4D
+F3EFFB7227CA97FC21D2D0356C93390C749CBE9750B821F1A7BCFAE2C8BC6D9A27F844D8AD088320
+79ABF0EAD8ECD4EA72846DFEED021857F33C1ACE4C07BEC90398B629814C498D33BEB375B9A53DA0
+F926FE6E89E70322C72CB2DDBFB16B13EF7A4F50DF783316584C6AC2BD7D9029124933133B2229BF
+74A228868AB30EA5C3E87C78C3F0962199480DBCADBEF53BDDE45849DA857A4FD85B96682F1EDEB8
+5384929DEE4AFAF84C51A09F5D572705673D885070303FDB47DC898F874E103A9E7C1E894115DFDD
+AD81549C7375D4AEDCCE2E52C13E5130B47F206F7C5AFAF1F9EE83DA8188D70B473269CA280A6A02
+DE85300B93D8A4F6B402FB5DF58F1327470CE11CC63ECEF2EFAA396A6680A6746A20382D9529B58E
+7CE684B39AC00F7086BCB47C2230DF0343BED9B9152A61C9826AEF9E00A1452D91305CF05490D4BC
+0BADC9C6FCBFA93FAD52C3A80705A1956890497557C0873EBDCF61CCDD2219354A4F5621AB33B119
+32065C1D990A9B68858331EE7875CAC855F98563B14EF9E1060BEA90F195AFFF94728AE935453438
+DAB35123D0E2699475884DDAFC7307A5CC06920F35341728D85965F5BA86F261CFFCB1E29B429F97
+6970D42D10E6AF6C4B792B4384122AEF2448E22A58D3AA007743C71324EA08D06819FED14AC1F22A
+4F0BE4787BC8738E1CEF240677571C65804ED3E748D72E89C94B6F310BE748FAEA31EE246859CAF7
+A1EA17CCB5B246C87EAB771E2AC5D378650191081514DDC2C66878E3766CB20DC49F630F2743A7FA
+ECBE9DBE9E815A3CB57DADF2BFF5EF2FCE23A56298A30A2E052FEAEFBD698101F9DB992613706693
+CB0EFAF6F60C8BB5E7D0A50B3392B9831EF3A304A846CD4AF431E9F018FCD3A5B16387552D55DAEA
+683D36257418AAA0E7BF8A03ED7BAB114D7C15119E6C71C1946BD7903C1C42E115E954619051B853
+BF05AE316E15E619A7DEE498F771E809D9435969C1056402725EF40C0200E083F3EC6E0EC27B8ED3
+8DFE32EA0E5E156AC36C4BB9AC5ED111A11678339703F1B9299345AEB1F251FCEFA11FB3101CC499
+907DC862B4463D5523B9B25C5B69F70AB6B29CFC1DF1ECAB8227EB3ED1F882E90B12080EE003714D
+403EC43B7B54491446B6A3DD6EB641EFBFEF060C45E873E7398025B1CB7065441F1753028F6F8C49
+A96801C0D598E098EADC96A21117F817B6FD6E6947642F93E22425A00E8F6B592AD50B317B69C0F9
+4047386A45E5EBC9504FE55451A01EB29DDF9A41D4BAD85FC84CE280971E834F06CEF49C8C20ED2C
+EAC889F158CB14A8C070900478804CFF1D1637CC880C81AA287D8382837FFA8F41FF3C9DF2F22CB2
+0044C171E4815D0D0F6C22D19A52114E780CECD71DAF63427782E85E463DCB333789F496340E8CFF
+885A9D9A4250118B439C71C6BE51A9338BE29251AA794EDC67DEEC6337FA63CA9B03C1C9F75E733A
+4A918646E7BC9792486CB5A4BCC5F84FBABDFE338C3792254A3EEA3D88903C2C47B91E076259DCCC
+8BD3DCA90ECCC832C09C45141C6242026BFE309029A562C3EE0FCCDCD40E5CF265ED9C3DE582884E
+0E14819DB98B3AF734B1B3276AC41D43384EBE73003D15CE39FFCC04109583390E470F431B4407F9
+8550E138F96C4564B494E5480F47C853BDD237E27301F55E42A3BED18FADA152572B7B465A581DBF
+E7DB2619365CF16D71BF8F091862B9FCF04BF8D0859A76F46E7B5712F2757EDCE332D3213B8A30AC
+2CE7D7797EEF6F30904906B0805DFA7CA36D32A20D989858497A66CE72491393DD79332003D55C09
+5A5AB5DF761C4BE5C041FA8407263D604E53091F7B6B15496245DBBEE96A63F10FC2978D99E65731
+28689366FE8B0BADA48B50185B861BAD03E3600F22BAD4274F2542B635F6C7944BEFC3BC741BDEF1
+1A8DD659038CB40FEF2E16AD1AE7EBEDB7D9BA15FDCF26355331505A386DD7399FB999535D6061EA
+BC61DD76EF3EB457446F29D0BB6EC2FC0AABAC20B27A3C123C27BC27A76336D0A0A6D456DA070367
+4D959A4AFE428E2206A511BFC80039ECD56E75F69786DA0A8084D81A66644DD98B6018681F1D70AD
+E09BD9BF3D16D68DD5D0A03AE26DCF1552549E459FE190B310A8776B2C8468C14CA8B1B9A7AF2956
+507A3B705AD75A17A0EEA7FE089273353CECD07BB8563465EC8DECA0EB42F43FE3664EB5F31E1D13
+24185539B28D508BCD065ED576D8814ED3FD637D576F027927162344AFB0255A91FFC616948E4E35
+8867E9FC76A9AFFACAEBFFE110808C1532A2BBB0DBEF3F010E45FFC73F228D28F12E98478B27397D
+8F456781ED9E19711DF2E9EECBC3FE61F7493FDF1A59124668A91BE51F122F93DCA4BBD22DEEA339
+E6EDA3D6EBEE03DF958113E1CA49C8398D2C59DA6764882EE3663F62A55AE50A7E91B4FEAD1B11FE
+0D50ACCC5D75F1A515F0C53616A500F1491381DFD0E2477E402AB0CF9F67D501A442629C8593ED5D
+25A72EDB9746B02F2B0F0759CC9CDCB4C9D8B4519C8C617E569B432F0CF6890372AA879CA7DE46E1
+10D95E230A4F0E52CF65811C54365DF4A3E40D819E2FD379B47DA3233D0DEF0EFBCE04AD8BAA3888
+4F6A69FE5C373E38AE0FD0241480F2BE7CCD18AF85916D2703A049779FE7398FC47D348454CF03F2
+2EB3FECC064606957898B5643464845445C25C0C7D685C8DB042AF5D5882174374ACE90081C68678
+9BCA96AC602EB41D317BD652293EE628951875641661EC86A2C40A42E8F0813A861D41A0F5178E55
+43651CA0E99150462DB5EE0010F00DE6D55B0D7FD7EC5BAEA24ED3E90A7D6A0589761922B91A6A91
+3A7FEDDD3B68254D89ECF767CE8E27F966426A8B4FB1B4085384FD09D63E288405B78A646F44C87E
+EE22C8596B13188085479F75F63D3D97A28F9C8306FD207DBFD38DEDF0FFEB7DD80B2A3292DFBF1E
+D605ADF1B33E85B010309E3EC058FCD922B1325FEE71EFF2DBBC2E68DB52D513E024C01D47CF657B
+B61C9734649A4AB63C0AF4720EC3EFCD82DD3CA6E80BB63BCF1B8DE810A0C6C517C63B76FE68C0B2
+86867BE102424FC31C4937048B6F323D039618586FC21731005D949E7D802A430DF8D2F0CE99F2A2
+376C2953EFC4184355E4D12F422C9E1E25C4DF38DEA334DBC89B540E14C61A7769D77115CE8968FB
+76B27D0863CEA2496783114C24D4CC816DA884D953DA3F9B9D3AF8938BC607BF26A071956CA07E6A
+5509EA2F5D80E5CBEB98041B197FAC760976EE75B470DC20AA023BA3F63C2876EB281FF5173BB490
+D6815604517AA1B1FA0631401B3C1A04CA103E2CA4ECCD83874D9CFC8ABC134CC0F9141D9AFA5684
+8BF222342016C556C14B3482482DCE5D0B6EF1AB522AA1812BDD8DD3397E05327EC12748FC480842
+9B97202E24E1DE0C7C0D272C046BA73B37D30930C5DE5A47D96955CB0F5DED8F3AD929A8B42D2839
+0458F5910A0F93610F79EDDB27078943DFE17C716D65F96589769349F3B66AB7B8C004CCC59EF688
+1F745EC7129865A76F9C2D029D4660CCFB4D5F9D412BA3372A27CB175E9D65F759575CF14A5899A8
+D31FF039AC02DBD8391C3397428AC0D5717C005200790785354813C8859BE90E0E17914F6CB9C674
+F1E9A9648657B54E5E1F52756C4F982DF74E73F6E4D40718C71D1D0E2420FB7462FEC9E457C0414A
+96E475C6BE2C10437096FCA0C942E995A9ADA789AB637B648781D32DFB68E62E91C2CE7E13680F8D
+31ECF8C824885FA7618981CD05FB335AA111B409C59EE337DF4E5F9DCC920A5FC0D620DC07F20DAD
+63F4FF5E0EE5A2F390AF1C32122BA7780F210229E5A5E3ED97BC1C3CDDDD456E739CA782EDBF4B81
+0552368E9C734B0C78B0B8E3F8B2DD782862B74318871BB1EF087828CC173D7B049811FCF598B8EF
+DE4D9BC5447F4848C98029C854F3AE461B9D46DDAD8CE67A521F3C811A81A396CB0F80F3C8D8EC88
+30532FB7F9624F7CAE0F8C6DF875073333DEB28AAA90AAF486AB8C932553CE697B885E71EC8E40C7
+835CD5D59A2C695DB9E51216FF9B77A15B0DA63717FF25B05B939E45CF7FBE490E51E9344213B32E
+115C2DE14D76DFD5845088DE645B0E75042A61D82FB1753C445AD0A956A1263E5A096B681D3BC51A
+9FF32EBAFFF7ECA8B59D40F0937EEFF38312AE57462C7BF3B1FE24D2BA8DFE84515270E09063CE3C
+80DF4935E409F62EB4F54AF16A186D4329972B9BDF15FB08461B688ED49928429226CAD9F67C9D63
+6D1375CBB7B08A5631956B7FE29CC9EFA8D75C9E4919C8C2C54F401D2E0D7BFBA40C50CAE214D210
+C6F3EA5802339F63FC4C1C1995787617F3EC2C806CE44CF8E29F76606CD5836F6E5A2E423CD791BE
+CD3F112F25657DFED9366FC4ADF90B685CCE4A5698E5FE16D7542B913FBC01B288DD13F43DB2B1ED
+8CCB80159DBDC90A8132125DF8DF547C4851CA609D1F6F4D647741260E845B457937787827A89E37
+CDA06BB191669AC84B8608EAE132D10177F3FC384980F3A6E439B048A38D0D6B9CEF09F3F2D732AA
+71BD058169D6D0F8C9D146D9DA046774027559A8B3843F6116B418427E78476AD8F0F81E8A6B1209
+8060FF7DD686503F972D6C42FD6CC29C083AC3D72E3751F21D2E44A572EEC80E81EE44C90FAA7AFA
+BCD3ECEB98FD4068F6C3A4DED0E6CEC523C9A0054D1FC2A8D61A4A26F9BC250B8F302416924AB22E
+722297888B85B9C12F8DFD2A744CBD143F9B2514C1CBE988D9CB4E77D90B2EFD5C2A528355A35F7C
+4AF039C7D1D756305967B847D4ACBB81263D4992C001E2A262B9FEE2D1F5022BE5B15E1D8F1D67BC
+52227344EE912C018CB73E5F47CED54FD202627777BB77AACF3EE6B22706FB2FA9062BEE87E22CD2
+802E7706322648DAA0C624EA885430175F746E1F536F9A8E1C610C4A761D07248426DB63C9319A88
+A3FA449C3FB8AC94C6003C745E6BAD717A3B2EA3862D1E08512A98E57772A62F85F1E2FFBA40E2EE
+43AEC11203DA9CE5AFBF673436F2DB6AF85BBE89D802F7A9E5FA25A408DB69E51F0577DD26F94CF2
+BA2FC53EDDD6FBEB534AF15F74F66EF8D14E7FF77D8A5D284C8202DD5A6053CEAA606BF925992382
+5EF4EFFAA8D878652A4CAF2EE43ED26BF3590402686C876F86C1AE95046E527617CDD3C429BD4CC3
+F9654D2C76DD4102471FF746FA9FA379B16DF96BFE3836D43FCC0B8E95120C27370049ACA4AC313E
+1D50D72D1814F2566B8B29FA9C9C20D0488743722A766436776783B939171FFFA00E04805A8B5821
+4D4F114F7B9C3C17CE7486AEA2BCC895ECDE809502BDE57981318A93F23016F056A421B733C4590E
+34AB08BB348DA4A48F19B6BEFAA1DDD2A49A6C440443028333CDD48C85CD698ADAF3FD8676739E44
+400A98B575BE02350576F96CFA54D4184BA47555B8D12374B86D038D085F7FA51FF4BE2FF5981408
+999B48B2FAF305212ED54B2E371F5A0074CF68D1B0E5CD279BBC8BBAEF694A89A6C43F518D01BB4E
+8402AADF34E96E9B3FCCAB4CBEA2741D3FD9ADF7AF32388F7771845AF99965A6078F4DA335EFA436
+BE36903E33A743C112C0267309F266DD44FA998C9A139704E400B89DAB952EECFE2AC09C82D9F497
+5371CCC27DA37890EC84123193314D8A7A707C217FFC951A547EE5B6D1B7C8ED85BEBD9D3F4B9B09
+6A78E5F7DF88C931E3F396973974454E59340CA51DBFEA1A00DE084B64630E26C6D6A3593B828814
+E27DB0186BF2A87EEF268AA1B135AC09B52CFE53051CBCC88CEC5657BD47F603C8E1A6249161684F
+D9084AC279F57A4F9BBD0A546A87E147B62AC860911969A29B8AA20E3AAAD0079D64E6BF1B0F2CE8
+F0C54C9019207E1B403358253C2FA93A662F63B9380B65C5173C198D86A3D0DC1800D1F5378DA39C
+E8523EB62C6AFAD8A0D7AD1629F2CECAD82B8FDE38975303768C7D3A08B91478EDB3C45A8C6B7725
+EA8596A8ED50B8355FB852FB8966479D12E1086223B1E6523A65FBA81DD106FE254F7309718768AB
+009FF7714A8C363B09DDA73CD3F81BF9C0CD3B0C806CF3B7BBFAB73E46FACAD2480EEBA97AE68EC9
+4D3D79AA01ECC22067858EFFA9D7B7F997ABD2CE5AAA8781E5499E8580C405681CC63EEA53BB47E5
+5ECC5BA2A7A3C5472DF034B022F455C60FFF971B01583A29E211A87F7163187B190B0C1083D696B5
+86E9438FD8BAA45101A5EDCD1BE5AB9A585511089DDAC8DF1B1FDBE582ABD945E67F99ADC4452988
+A9859E39C90EF794C5C4E62997085B7A16A0D90107D08610BA175AD66377345662DA7DA4D8FEF847
+EE5D57E3AC54B928A0957CC1C944E7FF14658FE4A641CD26C61105C0F136A75950764B69CA17509E
+3C19351D456B22C87C55E8DCC4ACD3E150D936333FF36499AD6B02B6403DE0F12901301ECB2EBA10
+324BA72B58206A13B8F37B0AEB12115D0C12879C8EA8A2EB70E85C95434564BA3DFF481C8972587E
+FF74EEBBBAB14FB32B8A84B8FC42EBECA65D25E8C32C19CA5962832BF45DFDA4E871508AEC318495
+0D6DBE89019CEA29E40484C36E33D76B756255531ADD1DB24C03B2A64A47BD8FBA3FDCB1F5B96F8E
+ECB60D5834AB001A70740498720AFB6EC03445CC35B51F7987109618C6C78CBE3041BEDC69B6FB12
+8142CEC5C8683B558AFE3024EFF7A12D04EF59A72E156DF11D33ABA08A8EEB16259DD9529CD003AD
+4EF4137B6FF1654236473DFB93F597331A5E26C7796F528F65C94FE07B3B4F4DD49034FA0CC189DF
+CDFF70C2F1C6D3DF30AE103E2AC5CFF20664AB934CE5C19693292071C93BD590383E0A1931E04D1D
+DD18071DAFB628F5D7472E457BF81D6064EDFA8DEBFF91701C5038CB30865D6122076A336732DBCD
+B0A625548773D0013648A76F07BBDC9C16284D158EC7A105AE37A62279419C3A2F360D0C7A74D6FD
+D0E36DCA2A8BD59945A4196598F690878F84C894852C1811AFEA4BE3B9F6A5219E6628C66669DBD8
+FA9A0CFC2DDE7716A356FC4FB271D8A2CDDC8D4684DE447355BC7A287DC56852A638C5777826EB6E
+B72FACCC86F80BEDDD0D649A883CFEEF4D74750172A90B5DD8252592FCFE19FFAAD868E99562DAEA
+E70514F5DE296EF7B57E6F193737ABB6AA317956584423817E11664A67389197AD9F8F771EA59551
+98C9EE40A0761639E638CE9D890DF468642670235F1373D3AC6B1F43B5777FC0A91A96E095E89BB9
+FD62614DE456CE7AFD6B855112367573FD9FCBBD4A4F9C676E672D62DDD34A9BFE8311B6175A003C
+D143C0DF15E4C0B48C735404086E48AEED6B6FA21FD9F40B84215DFF287F0677904E2DDFDA774A40
+19DF45CC877F553E95A1C65DF1D67BC0C60E0BBA4D205C0DA3DA80229FDD71859F65AD04506B308C
+2B783839F31CFE4425263224F08C5C7E98A2C9D3DC8EA5AC1920F4E395413262E0836BC019A092A0
+DECA104EB2DF6B63392AE8E2136379140DE5FC98B0B69860FE8E31DAB5C5DF7807D19BEA34AC14E0
+ABC6F6519C51247B104DE7D912C5BF6EF11B48FC6DF84512E9F5FEBB48F72FF1B722BDC3BB2E835B
+2E7CC6324BEE84893996B8DC2D4DC2793A4F69C18E63DAF04A7BB5C0A9076E2D5A343E134CC3C89C
+4712900656FFC202E1988526D80C7FD9281FE47FBA8AB5D025E63A84051F6B13167BEC15B346212C
+BD051AFE7A98BE3A2491F3C469718A58E783ED91F90E274FB4978F8719E92A99A1E8F142EA7E1F2C
+46AFF0A2FB50F4D105130CE8EA309B0E480DC8F80D506172B609EA4BB4E2BBAE98D8882814FB273E
+690DA990B60A9CDA20A2418246BD10AE67D846A0FA815AC25858145ADDA106A6778A11877FE59A2A
+BE300D7DB9BBAB31CB5B960B7E4EF91D4600886D8795DC361CBDDDDE05EBD54B1941F426F7FA8399
+270D2F54C998BE92D146227270A8E89AF90C48BAFC4ECCCA01E6322AFC165743475E752F39BDAEC4
+9297290510FFA264342A0AFE2985F85DEEC66C36EB4A1D46683EE7C591A89B81569A8566AFBCA268
+10DDB0970577A76EC8A066622606B08315DB0F2E6C671F3259C73637D773D1A180AAD66ADADA2A65
+95B5F481E5F59E51CBA876FA06D21E1D674CFAB46A02D267E20234324D0891E7847C13C69BFCEEA3
+AC55F2EAF753726BCEB0DE1EECF42ADA964BF9E475953302C2FCA804B70B779482DC9319B40381E0
+9C0096460AE113C19A2DC9157FA138CF0E7758F71008E71D0F7599744D647B09B16E3C795C56EE5B
+D14D8D63E7A512900D67487975EC9CEAEF69572FC3C2342AC5D365E8A4BCF462006B5268ECC15754
+94CAD9A9E7A9E8D9AFFE49AF647C017743EC7CFD5E66F4E4D845A6BBC836849274FBD270CBF263F1
+67DF7E26BA91F21C60F96257C07523AC37A2193010E976965CBD75751E312817C0564E1C5AE0CBA8
+BD12B01122D07020A0852120680985A8AC987BC33BE863EEC52AF13435B6E4048D951F5BCE36526E
+07A8661CF2538F69D1F223BC53BF5896437D1BD46F57D9698F642F0E99C7392D8EE47134E34DCE94
+D392949B418D9821E12CAFA8337323E8469DAC24DADC6AAD4A0DADD7FF65694BA3A27964D28D8EB4
+1179458F91CD3F83B8F119BF5E76184DD29CC4C0718CF7945DCECC993A7A78739363136CEC7F2FB4
+95EEA8CEDB3EBF14373A058758C442939D36774435554851E9519B6F09C31EF26B6CD997DAFA11DA
+91FA9759F17B7079164C5B47B99CCB7A876FBAB1D0D5D1E1A2683CD6914E6B3B755939CEF1C9168D
+30B2738C4349650CF86C90D2542FC9B90F36A494C035A1C86DD716014AA16E6B9EC7AA03B16554BE
+C436511DD3097FAB1FD0CD49EDAB96F74E8FD26400FC748CBD9EE1EEAEE24DA30DB6F8734B52818B
+3A5E510AA5C14E42060898033E7E36CBA9A64042CF94A74E4B52E37AC027C0DC69BAC4944CCE12E7
+AD81AEDCE642EC34CA23E3FF07B8CD35DFF19F33C8D4DBB56A52534F8A827BE47AD4AEDCAD83B273
+38409FD1101C4DFF3F12D3DF79AD1FCE65B2F419451DD059C88BF066413E23DE27D3621DAC2DCC8F
+9F3620DAD0F4B1A6E8C9E6E8ADB552E1EB2C4B2A3B73986AD53ED9ED8911F82F750DF05CD2EBA3E1
+B0DF208A87FB5ED44C3296B803881C1D9776D13350CD29C3F716F0B5A8B8557812024BA70069BE65
+89AA579EADB1F657712DF2570843D7C5FF7F4009D4D232D3547DC8B92ED5C4DB77B76255E661FF8B
+163C6F3856DE5651B597EC7C78B84F0C6C1D6EA3A82286F1D3BB45F708D564E139E81F473C705AB2
+56346328DAA64D1EA8645DC10FD449092E0634D9D7344B2AEC3C75F6B6CD8B3F3867FF3CBB0F556B
+186EE9A7C26BD2D17C8A773055D9D5013BD2F937D697A770C57BDB36D922CB911CD14E7FA14160BE
+19C1A052E297B1A2D682D4BBC9F1D2493BCD7CAD2FA75D904C5F5479179DAF7DC6A4E0D269BACA2C
+4F2430B4C8CF1572FBDC750A05DCD5B09FA3A9CD6F2F2A386E2B3D4D8E257BD43A783B38E63BCEE5
+03EA96FF2C373181744A607F0CB8D281D7DB1A6F4076AA3E2C61914BD796EF8A0873F79F964FDE28
+B792BA99A20C3F1F5ED1FD189FB1867C84DCD6AF43D49420C8B1F3DCE7DBAE71DEB17FE45644DB24
+4F44B1011C7C768EBB7254F4DACA64E9BA87AA7CD0F0C4B2228FFB9EBDCF3DDE4DCED39399FFEB34
+8811547D025320A88B480943A339E2CD2FA3605AAAE87939B1D7901465A1879BCB4C5BE1A179E7E3
+71F1BA2E0844F88AFBAE9B78DCCA47AE8AEDF5BD3D458C7D4A7A08ACCBF880D1F1DC69C636628DF1
+EBDC5C42FF88FF8B66351F3F72D703E52F3CE91E4E00759753A599FDD863788E99858498B66B93E5
+083BC3501C39A9BA928B0D763C28826FD237E949EF0BA85CCA9AA20C405DB6D5612DB718F7B4AD31
+D253AE306E4D7CB615C59AE668D347A4E60FFF7B103F8BD0E7CBDB142A763BE88AB40EEF6B8FC200
+458D728930AD0F94FE52ACBF0657C4907CC7942710AB1FD8BD149A9C9DEF6B8DCA7DB9062AA7B1B0
+11ABB5AAE8B77893A023F9EEEED4A20FBC30F922282A7AE2F1ACFF64151013D6B8AC2EAAE58171A1
+0F80BC18C3BBB5DE1E22EBE6033BF83040629023D74CCBAB3F1923CFA4A6735E1DFA8A1B261FBF1C
+397E26F3BA9C2629CFDA84DFA3D1087EBB19DDA7E2D76E30DC2E15B8821D5291DA1DFD73940E5560
+A8A6DC91BE0075E3ED8D9E8CAC85AC20768D868CD2DC45DEADCC8B59AABE6EE5B2F891E0D7CBAE82
+0F83479332BF9707486698FE196C72EF72B52F54314329FC498171782BF160E1110A19B8208FC591
+EF0F0DA71AF657B43A7CC649A8488B759F7B69134B4F9DCF79DAEBC1CE52CC8015F324C9D46320F4
+4E1551EDA6D86139DFD1DB814CF38A22A89FABB4F75FB896B00E769820F763486E86668253CC466C
+1529A5A924CC337C48448851A381DCEF63A0A302B65203D6571A1DD1FB9DC0C3BD6AEF4891497033
+109CEB5A481BFE442249940EC54096F1D0F2436D9E60495D0ACFF967A741B30467D24AC6B0032213
+18666B951EFD45324987B10BEF4AAA0FF1DF6887377A7F70F555DFB9FF1001C67438A167A00B05D2
+C37065655173A7ED9AE342DFA1497FB1F2FED6098901249A085D31B66DBB6AC25EF16C106B0A6FF3
+47CDF66434DC3F0012DAADE80B942D522CD59AF4C31C1C062157B3D000B9CB86E2AA7B4A5BF31605
+8A0D5A148EAA2C67977FAA0966E4C3454E08DF14C2498AD76E389AF65D2C139A6D8675298C46ACEB
+7DBE6904C373C06E5F71399B2EDA0B40AB96E8BE991DDC39F92F1D24797F9EC9F2FAE25669B43754
+E2498E8EA5C44B176C3FB3E8F7A7A1481275A461F2549AFC4CC73E28417BD8C5212C13105EAB967D
+AA679AE822B9B75B372A99C7E82D6BD83AA2BA00314DA4AC51B9CAA30D80507505BE24BAD0A87C5D
+5D7336EDF60CCA4CEC8201D243C3932F74D171E2409D789AAD0D04A7BB22FB6DC3AB92AE33FFEA89
+7C484D741039F38C317EA396A0FBB9F15A27D87FCBE007558799BAB73212B6E5FAF2080BA074724E
+AC87D88166DBC1464CF5D41B99428851FF1D99246944511CF42C3F9248513E9E51593F253D89C604
+388AD7132D6A169E9DD888E020AC1F8BA606F2E1EBB97977E505D8C40853653D8F398F71CC9F8F9C
+540C22A1E6195BA578AE7262FC845FCCF77B33F33EEF266489AF8B81A615D6A13464BCA58BEC16C2
+3F31D678F14A938BEC31272DAC3CCB1B2DAE577A26BED852FC59843176A5FCFCFA0AB7FB00D2309D
+E55C82CB9049F44FA61F1E313205A76317C4CF529A4456019D970624129681F46A9CD7950B8B5C40
+61853040113C8115319E68B37F88D864C6957DF813B305D09E6A1716B10F26F2EF5C727FC77AABBA
+73E12B5AE6416AB19F6563CE14046B715BD4CB2B1E4D315F42D10F74CDEDE82BCDD524A1A5460921
+9084CF1CDABFE72CC8375478B41614BC18A914903596D6FC2F361EE519F875385F4ECB50F7053127
+4EBDEB14A5DBD906A60817246042E3799BB3AC647CDA7244B7998AE4F3BFBE5C767FD2142E48518A
+4217599E0EC2CF5E86C8C270FF8B02F949EE001D6A439BCB4BC7D7F7C8167C3AE0A7E59687FB8BF6
+F37BEAA164541B8EAFD92E9D152E3FD0F413C99CCC34FCD8AA455A0B55DEC846A5874B94FC95CFF1
+BB386B2A1E22CD1C3914264B6D5BD1746972857C9235052D77A6C0DD3019F8A307FBEE63A3EF12B0
+39B224108276FFA84021F1AC5B745C54690B3FF587B4B1710AC3533A67BCEFC503ADF1F4B62B2910
+B31965E364EEC9CC437CC40181A7320CD52BE9C546B8F1DC824312216C2FD8232E2BB8D40EE2E314
+54C09772A387F9520E331456C269F51A078E6ABD9FB6A68BFD5F557215B0BBD2227B8959CBD1BD4A
+EEAB094DD18E891C61FB00933C0A0D76174D169C0B6445D34C00DC9E06D85EB086C18F3BE27DF734
+EBB9CF078AFF6514438549CBE92A0C0D25EFE4A527D86F158B4E9D8870C7AC5D6C059643A3298079
+CC20398324CA87273B86ED801057D797D91BC3CF2F96C650EE1566CD3CF8656CC577D38B830201BE
+718DC9A494268177A5019546EEEDBF101996BE593631654B638C75A6BAA648CD1E7AA9AC1EA60F4C
+D604071C89DCCFF8B3E430A57ED6DE11C5837E78956ED991058F3646219BEAE94E4D9381A33D48CA
+9B8FF12B54A73FF869D0EEED7E098D80152295E6016CDD809173C57D1F5FCE908A37010AD4C4471A
+53451DE9B4363B63437C374C598F548F145D3D288F42531FCF36A9CDF72521F1C0868FCEEEB1857E
+A983F6B75CE245D875BEAD1BCB8819E5464518E04717B78BD6E335F0AD77B832AF5682062A1E2AC7
+7CD5EDD5DC372EE456C96D38BF8BF348DAC2B4EBBB2440F2CE97B4B337F2E23247E3E8423BFA9237
+CA6CEB6FB93F960CAD894A96F0371168A33222052DE9B3BE04B022AB95C0C243486E35197721FC55
+311DC55F87BC72D09B6C940CA36E6640AEB66C394A5949A604E7F15DCE3A008BB41B0EEF2840A357
+F348443B4DCE064B4C15E5EC52E448C985FAA1C3D6526270B1CC691009959A7620C9A6202619A19B
+E410FF7BD535A8B2640AAA459DFDCB8F2BB35112626497E8A397D4F9E04788322A738DC8907CB643
+15CF63C95809E90D06EF02F72AB04AA61FE02ECCF7E9049FF9F3EF2258A75656178AAAC9F3C2A26C
+001341862D526CC14E92A81BD63502F959066E0BCD659CB9B5A45606153DD77039B8C5D5B13565F0
+0D95A41937CF97089F3938E39659A64DC3D6046D0E9EF66544CAF8A206635DF49926A3EEF3FDBC9D
+CCEA2886EC855F1821C4B9CE1D02A19A11BBBEF43A7D4D536715548A62802F64AF30BBCBEA8C7E55
+AD56C801D8A569C8183615A78CD393CA42C103F155941E845712C335F4ACFC7807202B92A983111A
+ED241BBB8501F15560E8F2157C29752BDCDB274008137277920053D6D7DCDC626A574A82A8A34F1E
+77B2FC8CF7C1A7322F22DFCB450259EB450C52B70DF3584A7C54C813DB41E3DD81253A03B02BC252
+346AF0160716355797B6F8210C453DD7E1E756FF08C7E6A5F4F87605E1DFF35A130D79148A57B7AD
+12D94A129FE3F055CF974EBA09A2B13DEECA2E02EA818A58B81E8743004646C7746110BC61B86ADF
+2D5D8C45A6A5461EB34497FCCD09E711F47BFA742C73F87B257B53F30CB68D151424DC3C210D3E8A
+C67C2495A8236EA2D7985A5E1DEAC699D7B700E6D38EEE2E93B191BAA5A8A2C916D206C63FE63427
+AAAFED2B5784276FC21EEFF2D70E47C8540DCCC3E00134642B703795CD3702631AE2A90E063A218B
+61E5B89BBCFFF84F567E37A31A9B349717A8CDB9C9377215BA838FF7469BC486B64EF2B6D92519C0
+BF0826E3652903F40E400689F5749DF86FE3DE178E21E20EDF9053081F6510D8F19ACD021CBA481C
+484D30EAD3B84ED0190087EE478A17154B243346C3938FDD5340CF6E47B185E64ABDF44F8CBCDB82
+94492B91929BFEB9DA2B033C3ACEE554F0F1A7F8A56DF7C06A3583C1E9C5CA458D40E550FDF3E2F2
+E7BE8312D5FEE98543388EDC8A04CA29F1B82B7AB4ADABBA3F2C331EFF3521B2B92F99C4377AB827
+A989B423750D36ADDD2E286E7F3B694E29B8BC403693C6F7CAB5FE34F1E48C8D41B47831E8C3F5BE
+5ED5142E3C44ACF5180CD41FDA149B1F4AED36812E42BC184227F5034220F74F67830255E1CAEC12
+66DEFA358A87D2E3B4B4E7EF30181570D0B2B43072EE0311C2C157D32EE2BEA8EA4251B59F6B61D2
+B4FDEB654DEB67AA3DFF4AD65B727F0D6B7D61523E4B44D99BA5CD33540F340A35DDD466ABEA4E72
+E504FC9BAAE51D231C33A8CE7DC2970DE4C1FB5B096A3D9C641EF77DC9039886831DDD01C4F21E6E
+168E38BBDDA5F4308C959C7BBF36A42D042DA6862937EB20D4FA2E5927741A58DA5CBFFD9553BEFF
+BD92E6D64871D8B25D9049F4E71970A8FF5557D1DE83DD24286D6C3E4770EE00F9A1A0B0063C9999
+4AEC75E84D6F9C488434D1F3DCFD0A8BEE9ED8257CA97E75E8B1285747184D6D2228EF95D4A0B8DA
+252318ABD35C8398FC6568B294D90AB308A7675F9F160140F0A08C88AD0CA1CA2CF85E4D031CFA3B
+87635F1398EB7DBC666A259F02DB6741D13E11B230025DD6DD64C438409AF109090058151E4DFB8C
+0E9CD65935C4CC063CC6100FDE70896E23E3661C7FC1B8228B26A55903E997F80207EDD8863FA074
+EE4FF23BE585BAF708040C9F8CFDEB42FB8EB71D4CB6D7757E973E4D8C9DDD082712C23F868E1135
+ECD91250BB4335958B07C12FDA75EEB56BE19D1644C1F76A8811C021122619F751CBBFEB1D3DC912
+999017FA163672A1EF754C5CB78962BAAB76EC48461B492FA88F9897170DE857CC8374C8BAE417D4
+C78A56047024731F4A45145F0393A27CAB614A7FF747BBC28E6880D4D01C0A6CF317A1DE5BB5ADFA
+4B5FBFE0C57598C79F25AE57BB797A489D51F85A9B9CF8BEA64293F8FCC43B0D5484DF99DBE19152
+692CE756F6FBE8CE5831CF4B8A5AF47524E272C45C62ACBFBDFE7E60B05BB1A1A6AF0E9210012014
+69B3DBB49EC7B23A363FA68417B7118DCEA71D4ACA2E36F88C6DDEFB70205DF3AB7C74CF65CFD01F
+F85FAF99F172689737331D4C6CFF7A29029772F487FBF625F17BDAD89B4AC076948277B4ED687840
+301016C2B7AD4C6D02F81E88C75B7A04D724E234E38A38269351582245E361A42C75B8256AFD5624
+B558ADA2190F960A896BBAE7A8C57E76DA10DC29E69BBF3AA86214C001A27B39C1D17C548DA5601E
+86A5CF53E7B1896BF003AAE9387ABA9B102EB1E9002DD3754A378F3E49F2C6EECF47EB1BAC2CFCE1
+1AC0C5CB063672D32733563F3E1E891B6073739BC53AAA0043FC45E90E413DFBD4548DD320B681ED
+70A7443A233D79E3F038D26975586E5CDD2115AA614727B1F6DD4024B85CCCFC79D10B7B6AFA789D
+B37BD0E8C423C1A4A8681B5FF3A9FA1F61A46E46C4B1836D1AA41A89264A7F4B1C259E4B10ECDF37
+5BD26A1F412FE01FBDC03368FCAF48AA0EC28B1BD603A6A0D0DADE66D14C9B7285569230FAB76803
+35BE104305E4B748FA99FA31F23991608DFDD2097DA292551136F255051C9F7EEF3FB7C7FDB4E651
+C3D03A4CA357B587245236F4FF3252563F6BE08EF8A3EC09BE2BF27B9120F7D37801F6999EFB1C8A
+D1A08698CC59CEAE2CFCDBF6BD8F94DEC94F7EBF33AF05F52C85760C63950B455510C6AB9398D09A
+C288EFA09E8F631A59B03FBBC75BBDAFD675FFACCCF8ADF71E815A4A49F14BF70E42DB0B7347B528
+4E234C24010E2177DBBD57648E398FA6B54571A37BA8C989503594D03C6E60871A7F964599022154
+02BA168B8D1D2685F5CF8645D5E11A1769473027F42564C2966C10C0DEE1EE1B6975852A4870D492
+83A470E623337544A7CDA5C16FE2855BA2A548511FB4D4FF2E3E78D108E4C734F64EE2F12CC9562C
+BDF363EFAF5201B673AD00583FF108AFF6B68055A5F299452D176EAAFB92C84F114C8C22A05EAD65
+64A3371420EA9E646308DE97D40705E1638DF08704FC90249CBC0D2D3E884A4562CC27370B1A9738
+9D8EFD237E644A7370B8B38ED1C377F522C75F981D878A5E87101E621DF9D85C7207BBE5A87CCB60
+7F93A2E52F660E05C83A7A6CE6D01AB4B62A1EF8DA47CF97D4BBA0FA8EFFA9C0F61A325A97ADA694
+45F23AB1FE27A66C271639F839203040D44B11ECC6E805FBE88843B34C4FD52D1D3C6C70FFED433F
+C04501FC20536ABDFFA429B8DC8192B2D45DD9D646049CBF40719C3D674773F9676F9FCF32817DCB
+55402A72C56D74AA4CE4035687C730B6B44A9CC614BCA5A3FD17C170ED949E588EE45E89E18B0766
+2A6327FB9E8475C43E5DA1B0AF07C23774B19C9EF59281F5D884990D6194170D8293A86DB52A0FE1
+7E88DA82209A00A16BD29B8B2F13FD60AA25FCFA9745F57C8216283C1D6EA1C119CB9B8D57C00419
+5210FFBD56395A3EC2D3098ED38F389EFC0324FD0E55EA339B3892568229D8D3E205A821E8219FCB
+1A7713FCF3450F8BEF976CA0BECA47376A8CA73DF85B340C67EFE4534D459617996526B5E5D3D19E
+17CC5449E5EF2B82B2C4C2131FF8A19FCFE6A186A9840D872D85C40665A7A04E67EE26B8BC9206C3
+5B44C8F8A1AFC3867D96DC6D48BD45063BE25B882E9BC0D0948C18DC870E6925818E1FE17D336217
+F174EB4481F5C0ED37A3BEAFAF4D46F857811B6728BEC461AE6468D87A736572F4FF95B58B04564A
+9D3C22754587DF15495A319D822B838461764B73483C1F7CB930EECC6F7424841EE10E4087E95120
+2FE88A391375C96BEC4480328A54740213F741105B12A39F19808F3823507B88115D468C61B212A8
+ABAE7480E39BA52390A1892C7EC50271156B4E8076FC3ADA222695DF372385DA7B117A29E04CD2B8
+0A320F186D61C963FBDAFE9224E537057C49E82E405196AAB621B5FE4011E1782A747EF935ED8BB1
+1BDA39A141CC0BA42D04AE123383BC95A1D03A85A9440010C3B9613064FFECA76197E10919BA5006
+F35837ED9BCD7DE5E6D968AACB6FC91178091FA467EF6FDEB728E17293DC89DDE5A5261FAA95A2B0
+000FC750E7073900D4D88247DA464613ADC2B3903A6132D96AC0E1C564385FFBF6249DEA76BEA2A9
+9160632DD2FC2B99133E9F2F470F72B45D6F18B45020F604B06CD9174BA3805DB60EB9C5E6A9C789
+ACE76AE9C79C1BD34434E95E501BC968633AF93FF4883C6A596776254C0C74993710327086B2886B
+02FD3E42A725A03459CB36EE34A094139AF5FCF487D3DFE63FAD20BF0DFB60DEEDA2ACCA3510E963
+189D1256EABD81253F7FF9D11263FDBC1DCFDA3D1EA2E52005CE3C605C993231258A717423F64BFE
+EBC34684EFA676358B9B543C2042BEF954829FE3246A879845B30EBACB43D8DD7A20FCFEDF763AD2
+C5D20A798B69E08722DCE6A5762E249ACE3055B650D9E110599EA30DE5C4FE7200D5A8DA9E1FE268
+6350D0DF334877D0B9F6524C552D0B6DFFAE125EC4C18F7547BD51C14288E4ABB7F8A1A00458596C
+390AEEE6FA308AC1F788FAE30D7F8928AFC91D4DE6352D20B19D8D8AB122B7378CB379C5BE7E3CE2
+922FE667EA057B5D7B3F0B51C7BF0C85F87AC2F360D82C38964F4DABCC9104B32F0FB8802235E8E8
+D9A5997D392259074C00AF2CE1D2BF7B8E90E2E2AC34185C68A03BAB8B267778292B227245D7FF86
+70786E3F746F86B9D4D17190DB859A0E144B2A61E6AC9254DE5DBAEF20E2E9DB0B2FF654B996E962
+F55E465DD238BD1643CE59DC2B5A58B1E6E4AE2DDC2D74D79AFF3C34E4E593E051FDA236B79CC0DB
+268D2A89B1878051223BB8F33FF99BA87A4811C0B3BCC01171D0A731EB732ECD8749D27952C27886
+B252F9C3D190419FD2900987A0A255B9753FB7AA70C37462134C467A2C4B7920BED9F9E86F8F98B9
+6D00AF8B05A4BD5F14C2A0D914A9A84160D554FD0718F50ECB5DF5E76623065852DAA74C9AD6DA07
+A119DF12C3577FE276AE551D48B1C5CD8A50E84DEC9CB0840520D78FA7F9A7C2071E28CD20EC7649
+B991F3818CDE295CDB6085F24FCF93147E9F4DD084FBD32525326D2EA147ECD5B6C9D9F4A7166663
+AD18BF234E9CB92FF72138A8A49E73E527E9A6488A4CA808AECABC94D693CD2C0C357D285F65006F
+A2F9197F61FBCA6EF07B013E2B558AB531D2FD270CEE7FA8E467FAB885E90C5884843AA08E2BBFEA
+0AA575643727BA18ACC499FF34E3438645BE2AA71EA491E54687CD305E12BBC94FAEC848311AE816
+495B013BC5075A2D2AE54A7AD7C9105B64356CB51F18C2C28E3A83B9D81A4554DBEC9BEA9A660CF7
+E1BA89E6D4DFB3EEC6A3DE3FCDED9B2D614156EDAE8CFDAD5FF0EFEE31DA3E6A54D94CE9453A1CAA
+D9756D91BE85315F6514BAFBC821EE810BB5D8E1B8F05F64F3F72C4B35D424F7E4DC3AB581B74ADE
+B6D6297CDE7AA8278909F269FED79B7DFD39B1C0338E01D556C4DB9CA3A8578ACE3EC3D743ED4B9C
+0145E4525E8C315F7A1B98584B975C70F0D415708C8CCC13F848B1D36AC8249B73638F95DE0CD27C
+7EFB52BED4339EBDA4812564D7A77416DDF4CC88CFB52D07A252D89353C6826CA1832A153242979B
+6CEE783ABDE65C8B40CF4EA7B42B8DBCC0E02423DD693108006F6A4AEBF053B666C3CB63D1861F86
+EAACD43BB9BB6F2C3A17293C189331D253B447757EE7CBF4518BABB73A1D44874D7F0625E6A013C6
+08E991B4AD17A9ADB36740D25E3E35B459B422F7370B134CDFFF3F3BCC4C32B4E9EBF6A2478013F6
+6933A1FA9403A2F1161EC632F1F04EDF95ED0F33DAD9665D54DD9DB2564E51DA7B65978CAB50D6DC
+1568976E83B056EB0E3A6758518B6E17E9EBFE49B72EB148B472BA144BDC2AC95744C9BF1258F0A2
+E47470AB0EFF90E190A41108914AB8C1ED6B11E0681778521870E80C16AF2AFC723CAD8719ADB62D
+3939D3BC8CC1D8A4E07E9D734F54ECA33D936D2C39D5C8055739C33E53359BD40E576C11E93B4B4C
+122BDBC9B1BBF44243AF4F0BCDBDFADE68C526B5CD74E29CE3F70D62BA83C489034111FE8E4DAEA2
+F01F9D938ABB532DEEAC0E329F42453FF5C15DEC2AEA8C198323C9E8FEA55B3F5DC4751D2E2E16B6
+154E7F2ADD46860E9CA71DC114C99D80E7EA1DAB51E925DE161CEDD678EE6282AFF38E3CD0E65954
+9C970613209955A3F581E1ABE485E56402A3DB0D1E9B8A9DFD05C4B0B7F97FC6D0EED0B69AD6F182
+B1D028ADD2F24463834B13F5C1307F91D363891824E81108E57CFD5211F86400D3E96B107F3B1FE8
+9C4908649D04A46DC3CEE0DE66AF03A7FF9F4DAFECDD6DF4D93784CC899B527784DBE0718050FCE1
+85BDE3F39DEBCDD660B2488D23AB1CFF87B0546D02B48E7B7724C9E87B71BF34B5D6640E0F6ECE47
+B182D41C89461F712849C6CFDB7E3F5EBC1ACDD12D65A422BA362A8FD6CAAC5104CCC5AB5FC04A46
+E4309ACAC83D659DDDA256CCDDD1BFF9AB3622450C4FBC89C82214F00C42FB0311BCB1B722A691ED
+839CAF9024FB1671F18E4639C96D84718C663A4341DEC037175C6BBD288BBF5A0478298CA726567A
+9B74C32A527339C666A294A17F6821CBF243D13EA4B1603C292953308B566653423E7301A032E5D5
+E2B93F1C1434893633DD19501AD12728B5A1D9D36635B589FA2E151140B543D7C5E469AFAE8E80C4
+FC1D9CB6C3823CC1BB7EE40AECB58CBC1465792226B19E0FE79235115F6A3AFE19F98C5DB63D372D
+D7C041CD940F4F79F2474D9CEEA0334FA04A97DC9773064895CF11CF73F11B4684F06E48F4469F6A
+1AEB2CBBC52994DFAB3319DCE3A0C8C2EFA9627496F8CC84D3DF3BDC4FFCB61672780F294F453278
+AEB9262E66486856D37B7647141A82E049364ED3D03F925284A3F1FA3DDF4C0B48B3FE22E7DF9ABA
+239D33CD300FFA8FD4B96192BD568FB18D325CAA8E1F1FD4B27527417B034841FD49E4A77F217062
+3CC8B22101166D80361EB15FA9020D24F61007B0A8274DF9DFCD8E97C85568E76D34AD5DB1779B02
+F034A69CCF9D4EBAA188EB3017EEF5B22A0A552696A574907F695098BD8A4849D5C8311F129447CD
+7A3CF88B8191AEC0AFF30A38A9AB8135608A7829207A7D242F6E1FA7DDA19F5E4C28560D42DB4405
+77CC0C5F5803EEE897103ECA0BD944E320AC26553BEE7852EAA733BD13DF760056B2F5BD1243BEDA
+BC3C1EA0531017D74B47E18F801A60074D6DF849FD0532234545E5B5E112D1E7385341D39A89551C
+80DC2DEAED5D5DA2A4BE5015D297324E92BE64C68428132E6EC654DD4BDCC6640C68835FF8A05E09
+9604B8CD43D3AF2B2FE10C8AFEDEC5A70AF8509D12F662338CBF166D9452CD36331758AC4F4CBD7E
+DD52139AD27DC52569877FE709F297444C4F31899D1945C81B14ABDECBF31DC463A4148F04EC4FB9
+703C158216C0FBE65CCD450043ABFD4E65BF8B28CC148252E9F3E797EA0B57B8721C94CBC2EA602D
+F2C57E87938C887A382D2659226463BC7D6A1DA87F4A341A59BEA458177D3F18D1213539DC0E301F
+6EFE0111FCF6921368BE17CCBB7428127E0C059C2C5ADB2A3F0197F0CEAB77FF7F3C027A8EC3EE76
+CF5C986EB47CB60561C773B3A2DA47B5A35394E29373DBD5C3FF4C9213A89AED77CC4F3FCFC49EF6
+EC7557C521979A546983C106B3627B5FD2D71CC5F08A32BF49332A89C5DA71AFBFB94C949A91220A
+B1F885C981423AF93F73BC1CA4D92D9DBAE3EFE6A76E2DE3D0F74FD3255820636E3F1A6B7C185306
+23C12AF90CDCD2C0A728521E9B639EB6345D1DE8FFFC3B19C72E7A93823DFE3115E9E7BBBEB28CB7
+3DB121AED8920D47D8CC08EA2E472E39A4CAD5881B5C4204F2B732AF9D5189D25ABF413CC78714CB
+01B1D8CA5565169A919DC481F6D2E67F1D490AEBC5CC62A8F62C1A323EBB55ED35AA5C8D6F8B970E
+93205C2701CF4817BDA994FC16197B469ECC5F5E9DDF0FA05640C2E571849571CBD26402B1EB1E80
+3FCF423345007B9B52B13E3B034E8CB3984B925EBFFE719ED4F39F3D0E3343316A6FDC26BDBEA88C
+4366D3B2F851D2B244CC4408251AE2C77348CCE9DD8BB9C89800B572D38C5D1CC34C740BEEBB5DDB
+0A8BB251655FB989840D23205D16311A9FCCF7C85F6DFFEA9704492A4E7A8F6C0BDC29745AAC2ABF
+AEBA02B0E7AEFEB92BA63AB0DF844EB09D505C3DFC1058CE42CDD8043B76398401E1DB862FF9F76C
+05E8BC6260A4443CF494BC1755913D51745BF45ADF2F8C7A9546D7EF4FB11E9D94E4539632C2A396
+06D04480EE459408D7A2A869807A4C01881C1BB21C296A402B5E6E07093D833C3DFF075F4DD426EB
+87B1B8DE16C146DE79F52F5943015331EEB852809CBB8E1D6460AC4D176FE96F8D19F6CCB22ABBBA
+A27C4497D91312C3CFB5BB913B314E43D2EC6AB6897BA7C34CF2CAA6DB4BD69EB5DFCEE0AA917D69
+50E36A68A4C22A60DCC69379D47544A58D640EB10DFE120FCA843B588CA8B94F7869F97609A6FE03
+AC86EC1F7CEAD2EC8E81977D1B946E459DFCFEFE65A7BFF67E66F5F78A45D8DF65AF0146DF74E024
+FC042328886CC1DD7779F49CDBB750345CF83CD678A6A8897577299DEB38AD665DC4F21CE1892A18
+C256F318107DD3E9245C1AD3BC93CEF7B7BF057E33EC9A3F953251261AA3D1A8347261E70A46F777
+3A84F3D4D1A0DF6DD22A96429349DE0D180310E17955B10FBF53220EF6483D03C650A8D5C16D63DA
+F65C21ADCD6C2D0B5D4ADEB2F5526AACF7CF42F9A8BF4832FB2D4F73F3D5FFD984B572232F87BD3E
+59133ED3D2FA19F7856AD812515C74F7D851574019C532C25F8E163E595FC9C83E3E820C3CBF690D
+A62578A980FC0803EB6DB9B1E90E3256BD4650816ABE5EA86CE65C2EB418D0ADDA5F3EA04E17AA8C
+4536CC471AC20236E66ECA3619F161DFEFA485386C30EBB86A7AD930FD0AADF2DA69DCAF26C0F677
+206E2030E3B15B3662C0AD03DBC1636EBFAD1F2F2C37F5FA9856B0198C5B1D80B69C5EFFD94CE071
+5135C649C26B9BA1266B0A5B270CD08A706166C0B320915C87B27DE21DEB5D7E4806F6E700B7A06A
+4E29B629CB40761983E9CA8E34E869ABD04DDA190BFE5A6EE8B22D7E511B84EA584A84211F27AF89
+18DC5AF8A1FF2D360B6BE3CA8E66BA4CD2CE6A25E7E89406684DA83FFBCCCCBFD0844FE3BECD7DE6
+7764C59C022DB1168D585FE25073FE00E30218D1DFE115CA1FC606AFCB04F2A082EF91788B6BD096
+84DEA31F20034A91AB9D971366F97B5009FEFBF1EF0AD941654081B1E8F0B2EA495069A1DDF11DC5
+6857D29533DC857958B49D1A0779732819FD22E437084BD9F3C4F2CDA4D12CA14431937AB63A03F9
+C040AF1D801F367ABDCA7302E18A9050D6026FBA5A5A7FAD44E31593173CDF277CD737D1CEF59FE9
+684252BC0DDD00A80E023B88222494C1C8C0884230AB11D1083225AFDCDBC1E24D4AD5FAB396D2E3
+70E44A7571B230660D510A5076D8E35F7DB72C0566DFC119EE1B8AC3C0406950A3C4A4DA36BDE297
+040A27F70753A87E6CD593DC6BE9962261A99AE5949340C5D45C94A9AA3DD636CE8B497BBB812345
+7C824F443A53B3EE595C38983FE3E07DBDC6ACD55CAE8BE1081AFD4857A5F52A3C925143507A3C37
+F1992CF72ED0D4C48D94AE6CADDC3BC87AC3A3EF035E02181F78449E4B063B0835E827644051551C
+1603E2EAB5875F28FC77BEBA6923428D5521C698C6B7F133B0F689F105FDBAC30A8ED2F29F0255DD
+F8A037B81F04EDF004CBE639C8DB0F94D0C5DB92D34D66C2FED66CF8B895AFC4E659D08388EA44EA
+E83CE459E5BE306750A682B627802990037157339BF142BCB9C08FAFDC3C3FB16DC3544F62C6C7E3
+3E20CC4FC7CA21E2C3F6C546CD78DEE348F1A4C8CB548EF20C049678916771D83ACC9B7B22784AD8
+580134471A3C79BC86B5D6D0D305C32E6204274351C94F9DF45D9B2AD5B5087A89F90D6AA033E4B1
+D1BED022F36147C7ABD2B73134DFFD50907258E610C3B20949E141172B1C6A76DB238C375021CBA6
+645CDC26B717428B5A9B4D3F32A4B1E22FEFF3BB93FD889E1DEF8087718D5E3E650FE4A3330DA9C3
+7E9EB499DF5A342D8BA4C0A033C3347CB25A31BE143ECBF91384F2381E323E7FD3A82A3197C18905
+3200AE2C86B9D01AB0B289841EA7E9E9A26966E0DEF54DE0B85D8DF084B8C590081E444BAF1E1F60
+670FA12AB97159318624F2AF1B5EC7DD83C1073A99398D2143A52D10A13C201FB356BC9E90C63BB0
+BC2D4C42AF4A8B9C8C4D58A1B32E0597C63B3F8B3E893BD3BE8C60231838F1BC78E73A6C8CDD5E7F
+2907F897FC8EE99BFFDA7338BCEFB5AEF950E5549ADFD207AEB15846B509FC57989883642498A381
+1B8E5CDE69C05924EFAEC232FA4CEF302EE3251366ECAEF57D25CFA3B4A9E6397D996F421C900BEB
+CF73B038FE7B16FD0A1172AC2F40D19CE0B02FCEB8BC47DA5344CB933C7FEC950184F78ACB32D3E5
+E290E84BE753B9E7A7BFC4416CCF29D023760C06CDDEF2505806A65E1508990529245059AFD301DB
+669D41BD72BF7A80A9DF66B876B3553FDF4DD38D15289AF7A1AFBC53FFFF135A6348DD784AB42A6C
+0D6AA330B069607E2DF3CBEFCE79D6F63E274C9E73A33EB85246D5EBB986BFA923DF68B2B8CF82AF
+6C33E785F35B25B1D1D614DE85A4F4510ADFE42D75B5FA5408A59ABE53859E28B3D000EB9C6A7D2F
+67C91DD14C895BA87B9CB57B851E5193FCC2A443AF85FE28DF6F39537F23A058BCF81DD8C04CB2C2
+5040300F4C55975E856DCB4E21E2B5481BDCC05601942FB25BB8A6B6F93E2C2A33CD478B44655657
+C557EBB080179EE5D98C5CEBE0B25BFDD952FFEB258014D7A5BC4BCA4F1A23BBA73C454B12960451
+CE1752401B0151CB2E01D5C72595095EAE91D8D3BD55A54A2AEA89239FA176FA7CD6F16BB0733EF6
+CE6E77763A23AAC77DA88C8EFA7BBB2991E472FF2075FB25A75ACFA70A04C28764F4AE4C12051B25
+B120CAD2E3044DA35C1F94135DBD69B10DE147321CBBDC814CE99982AC1D76CE3D3330E41AB31F3C
+76BF89B95EAB81AF3464C732D5B1411D97DB36C9063537F64756F205B16ED7058E2CB1D6946C00A1
+A0CDA9EBBE924BDA6C7D7B605C514A98133907B793C74CA858E82DA3519188CD974B34DAA74265DB
+5BC8550D5F0B1173ACEB87458BCE2AB1F96996C811699A0FE4A9B849D39023725E2B1EE7E426D30A
+6C5C75AE6BCEA6DB41E4EB2035F7F924E6B9F0DCD00EB2BB014222E55FE387FBF5B9B7C04F4688D5
+AE3529FDACB38B5EB0AF5C3A874C1AA6B17CDA8D1E22EEE05A3DA88449200D3D0D002DB86F6C51B3
+37C8E19F338E7BFA01E1202612D50E210140947D5F350E84F790286C3F679A5D7E43BCDC337265C2
+631527FD62D598B7CA1F5835C0441881B97F5197901ECDC4F195BC665A846823D2E41417373F8639
+567B228FE7B73D781F07A361AA49C3E9D80FE5B2A32C4C1E575D194E841967B08D10405FA44EEE28
+47DB9372C5CC931E50469532F1BAF577F680BAB4E30B7E1CFFA8574ABB679789F69A8A1BAC07B7C6
+4EF5CE5EB00E97B36FBEACA9BBA4A13B0293D34BDBC77AD1FF88E5744AF009823BC262511C4724DD
+585E7E17D90F230F7A5861B0DFC42F0B4E49A04EE0EE4DADB908479DEF8372F334C53D2BA5D855CB
+39DC7C9550F9D0F7F77E82D5A59FBBF34BFFE92DC9E6668B68FEEAA4F20053433D6749162BBAC5D0
+D428DCF2D58D49B127FA2E674EDC7D3613B1342F4D0ABD7F4C5B049FBF78E804D5F16505AE7EDCBF
+4D6FA08D72890F5D55199034572AB4B0C9A7E7F6F5A403198864ADF113CAFF5BF9D4AB5B16F81D0F
+C2188FC80875E10034D12E30C0364F8F72797F1AED525A2712A40D44210B813DF5A29C84E9F6D51B
+1D60A5F6F938FAABF878D29E6AB252D95D05FC1ADF5D4CE1C9E585219112112BC6CD5C766411FBD2
+2731794B5DE0A27AC57D3C57926807469C360372BE529098C350EFE2154B87F1205A57A0B04C5206
+CC4FA66B8793BBBE492CC3271FB4F90A28D0066E0D7F63B8DD01549A05AFA5482C29560ABD628568
+75CAC16100087540162473498C14087B29B86B7BFAD693E81765CEC781F3FC80E9C7B410E9B55B88
+114191A1703C638DFBB469ED1DD8254B1407003A319CE74AD419B077F17047A01F0BC0AC8507191B
+F72D77D9333C9DA8C9DA733EFB5305F49CB8C7BC451321ADD7D896395D269DCDFDD084EB3AA70338
+6C0697E962929651164135C094D9BB1C9B949D5EEBD3BB17F02C98C813CCBFB23C2C26218A2F4C63
+9A8B9DFF2C29406037F91938A5E1227310728428B56F48108CDEB33BD3191ECA89F947271983DB77
+6B2BC897A30EECF2601EE3B2A6F0E135397622AAC1F2DF523CE6E6BC720E13CB530CEF4AB9C8273B
+D3D81563AC8A8E6C44A195112DAF824BC7A72FCDC4E129A480717BEB01085DEE65EE4344D0B41EC0
+BCDF842566B1D9F5353B1F6A063FFA6CDB06EF634C8BD5A7A63F991D178F56EACA653DD67685CE49
+E98C7554745A4AC533217662D23E1D6937135D13BC2208EB8D50560A2BAAC319DFAE478B6BA4CA5E
+DA20222F0E9BDB0806320ED1665B54A347DE0C42E9F77842DE4D188E7E824EB2F0D7AD163F05480A
+7FA99C5A603BBC5DBC843774CA66E889B945054C0ED0B1A4BB14324EF901B023C208CB95DFCE9284
+89789690CC45BAB97BE449F8E2F5AA9276C0571303E9788C46E7F789555BFCDC3FA9ED8DA8AD9BA4
+8B3AE09404664391E63A989EF1E24BB464043AA099E4F2D796E352EB277106D8D81BAF2F8562EF46
+BCFD1E0047E8018CBD973021DC1C1D821AF03F083F0B088A62EBCF2BF6C5B0FCFA441AAD1625FDB8
+34F943DD47A5A42EB3E9A5B49641F797C288B799A64897F1346070461B6D535E0C4ED099199C387A
+3176AEDC7DA7E7D9E118E55565092A36F7C74ABF281720C0147F4E4F37D49436466C61FF12764E30
+43D8A6D027E70537164F0E7942F4ACA42BB2CB136177EF7197E76F49AB403F741C0EF902FEBC471A
+D6C627424320A8C3A1F04C310C511B3F91C3937D9ACF459999C18A33F2C852EC38CA806599C728C5
+43714018C65E2C5F430F6270AF52AD71ED38813B60440779455F9529A4A1623CB9F5422B9216F9CD
+BA913B9A1CD95DA225E254E8101216085020660509D03A034B5D7E32E3DB5E5962A9A27711D4C3E2
+9CD84057F7D0D7E8000947AFE896F8523253391D2E11FFFE523366B05C532D5629A90741EAB3D4A7
+31D3F6D4F03FF93233DDF88BB1913ABA22EB9AA6311E3144381DAE29BCC8639958EEE59ACCFA06F3
+5DCCC63E0609F542F3EE5DFB1CF718CA3F328455726F8F65E23ACD970E4049225998371B63E35AE9
+8DC54D8329B8DB0901FAA63129EDE21B158776981D4D094013C096E9CD020315D123C03DEBA21E97
+E4B584B4BC0AF25F5DCE53C2DC0F3E61F99BECAB40799478BE7F5AFD7F68E23EF50AD6645C967EE1
+1206B6E791769428ACDC370D64E4F2B3972E0E4F442297199350663D6E772FC6777A9B9DE215273D
+082CCE4E8678FE9948DC8D5B0E459CD02F1645AC5620F3571A40B4D5A17DF5CFF48B6C843DDEAB5E
+BF58FE13D7DA08E8AA7902119248B3B151DA583101CF80853B0150FE05BDEDBFB50A7FB0F65728C9
+3B9DF48CE8AF1DF1FAC25C1D58E1AD30274A00EB54CF2F16029E1AC0A0919C0655474B9A6936AEE0
+FB74BD185FE7D70BB84786997D34A40326A74356A4AFAEE67B6B26D1C1A7BCFF8697B55C816CCD77
+312C332A55315DC54F9BC0A0F12500E0A76B3936292A3DA2DDF5AA8CBB9B5DC32EDACC4827D684D2
+74E65B8B76FB2C2B19F7D5607523FA953E34BB39032C05B1C1244304606C55660D3CA8607E764EA5
+B03DB7FCAB5CF7788C6E60EC8C449BCAFD90BCABA4132B6CBCCFF16784FB59B36B77CF0A9EA572E4
+CA0A01C725A6CF2E4500CDDF5BACCB9094D48925434F044118CFDC2696AF5FC0CAB3884107ED17B9
+BDE0C0104B1292A1F8C99B06FC4A6360B24480BD59DF0488641899B0F42B1311B582717BA7ECFEE1
+4143654B5371C8B9B2D80685AD38D897AD1E64875C28C7020A84FBB3A3BBEE16617DCB9BC822B7C5
+9C5A18C0CF7E80163ADFB7AA03B7CDE8497C1697D90F2ED90F813095C5B91657FC294EF0E341DB33
+92ED860CB2E0AA09293D0F99AE9EB54C761CA2DB1E51E1CEAEAB276C7BD916C68510D72D9A67468B
+09B3C39A7815628FB126CDFD5EFF59CC8184C0D35A5B5960F824BD175495DD3EB12A4E96008CB13B
+8C5745303E66CF8608FF27C4709C1D854EB79608E52F068FEC0151A74C125EDEAEA555C198FC0802
+7BBBB802835E1D435077AE4B1CCDBF722354F6C572BEB1376D3E342195FA80AC9722EB2F46E44DE0
+5F5A227B731B8D4A4B6EDEF04AF2C5DEC2EEF8FF48C5B18710ADE3DBFA0C956505B6DA9CCB7CBB83
+4DB6CC754948855D833670FF0AC42A4773FEA8322BECEE04CA74AC2D66855132D11A51524488C547
+71B5B7A512796D7D7AE0F9C1FBC9CBDBA0831074F4D200349D0CA40537B92496692766F020AC43AC
+01DB8B2AA2EFA9D21732BE3A315F6CAA402BB2E61D40DDEBDE11276D90C2C601A935C168BE600464
+76ADED15087D54A14C68EECBBBB590927C1E10D291C9285334CB0C80EDBD392BDE4D535EB61F8E76
+41F58AC1DF5B1C5A5D91E3E27E05CAF7EC97ECF0C85B6425197AA856521ED701E5AEB82A7F52A8BD
+7DC97D5B3FB5C99A5DF84D1BAFF89072922509D76BC6EDB15CE5F9EB8F4154BEE1E82020240283BD
+C83A8E49AA9A2649B7955D5C058F2818A63BD0BFE7EACED4A49063C489A626277AE1246F721C9926
+E2A2B6C31045FBCD235F3CC58BC4DD6C57FE998EBD1E9FA5154652BE3A1685BCD2EFAA079A3293F7
+8142A6473822FAB627927EACCD61B3E99C3077103D2D19382BC7EE15BAD0FDE489602D055A01DBBC
+F91A566974559D1B477C209416887053169C3F8F59955BE4DE82B60558CC9AE15602A93F029F6B43
+29E0E62A03982DB32F5229714EFA1491A7B24AEFE18FEBC2C93DFE50B3F641B51BDD33DA38871BF5
+243C17502D00AEA2D9E9734E80A96788D4CF5BC12A42BC386162FC88A7435EE13200C1C2C6CCC5D2
+1A03941007B4C4291BDB711446CEAF27148104BB240357D5EDA0EA5A5CE27D4A83909D75BFC05D75
+F10AA74A6DE37D7DE15C1DDA3AC3045DA6CD48323D904E716B445E5E096FCB379353ED70CF4B6FAC
+102C762711079EFAF13FB74C9B47AF75F3F6BDA2A4647D2AB47ECAB64DA6CC01479F618E8D2D0A36
+45445E8744683CBBC560D47C98078B84206E90EB839B02D37C852B8E284463D4E4D890203C3D5B20
+352110034EAD6BD7F41456B807E1DB1631A9D499E52E9D9853D86728B1A2E511F40F8CA1E4724A0D
+17ECD640B52FF6C66E28693D89765FC391612E5889E77423EC85CBD0A038B6BA98B607701DC0C4B6
+6B3B28C7790A1F1EB8D051DC98276DD9CFEFAB3F65C1C928E48A060C992B392A43E56EAA6DED896D
+EBCE71F8245BE4687F2F1B8FC0F43ECE8DB0BD0AB0811C5CE73CBE336023A0D66168B34A95B4B0A7
+50B3BF1D197E3C042C7914FA731D7831AF798E9429571CBB977E6258244E84701E5FF91D608F98FC
+3D68A4EE5B81D5FF38B6C184F6118B875F022B4CE207DC7B37E1452DFDC591A3E506AE82C7E7BFF0
+011B0A3DBD616A993FBF878FB03B6C9F2055A2B095D29361F8253C2623653687FE0AB98078F6AEE5
+FC2C2BDE0405EABEDB3A33EB7F04CB6837176245F190C6BBBCD64522B12FE7F9CDCF201A1AA8A19A
+7BBC4AC064B4958F44AA0F8DDA23835AD28A1FD0EA105DE2F395385DCCFBE2261DC5A89A23AF606A
+3985E5038706B1FE0910400E16BF008F250F3BDE3AD806C735495D499F16F99275010478FD2127BF
+7CEDD6B5BD505FBE9BD0065B4A7090C9D27CD5B36C3AD33E1B31EB6D44E375003B51B909DA50BD18
+218418B3CD22B43278B144BE78406EAF16C7DF6B6C1C6238004AAB73736B38E168441DC16F9A5CF6
+0793A18633BC43D78674D12D38CC979F7CAADA6EFE807CEA499CB9FE616496682A66E04BBDACE1DC
+112B2156B9B0B20A58A8CB43FF0EEDB99805234B9A5789762AC7D65F5A319C33F4F7438CD15E06BB
+80A7A97E976E8CEC23F4C646A5821880A82B2F1DC27767F090997E91488BFA15064B702F864FCE65
+05D6CEF87D2A0A12B55BA189AF269811E3B8B850C8401F3906C080D32618D9698A766732A40A9FC5
+A94E5BDDA3D028D823D6B603B6D17DD046DE181FD989EA0F80B4CA62F7973E4DF5E032A31FE6BC8F
+5CDA678D4A72787EB8253EA5882C337CDF9AA3E1E7D9536DD09B047CD8962E773F72F6418A3AEF5A
+289B3406C152A50CE7BD4B493FFFC27F6AA52F79EA67E362FD92559AA4F94A2F787F6C735DFADCF2
+F08AAF98B80C53CA5607A94F25F04AA65A70A75937840E73055B3D65FB054C63E2E48E68488C9315
+A13EE949E03E46723C11CC759D222CBFAD2E1A87CAD779B23D38F7E2F660DE1388EAF1CF4D18994D
+75C6CC63F187FDB949940C18B537A0AFB12AC5F67B0283CA5EFE2E764C4369104B9D3B06490D1244
+C41D6085C85F1106082EC9DB84586230511C05C82412D2CDF3DAFBF4759A775628878F997415296B
+C416AC8352A6C6988691FCB831CF95C10BAE691ADB3BA2918B35924BD5C3ACAD8B137397B10AF82B
+479800FE16D472CD0CDBDAAB4F882A0649CF561004B8CB7CA32EC129D0A415BE6CB91DA2B65F44E8
+0D138808A127E851A7FCF927E99DAA0EA2D626B77A16C72E37F058A3B882FC4955DC8CB6312434BD
+3BCED75780B13590BF4FE8D64ACF0371F9FB1D361B05025852AAB9EDA1A0C997CFA58052C454FD45
+1E6C1F194F4D363114E312F6DC35BBAF357A32CD200A3DD9654155134259887D677ACC44F89AA401
+CA27282DF7DC3F2F04A108CBEF2558DCCE28BAC2D87B8D5B7181EA927F61977764F882626D4AB338
+D95C9477C54E9C36012A3CFFBE199EC8120A99D2D70A21F9D9A0354E4EAC7947990E8A6E0601796A
+AF6F14E758CABCABDFBD8204A8E748A3E5FEBA570D36E2BF474C0083229A63F96114182321B2EBE1
+BC76DD193724C4588C1D39D184C332FAEAF4C629F2B3B2F49996E46AA6C9F497428BEA52D58876B0
+DC07B460248BC85CC16773A5DAC36CDE8B152D96057F4EFAAF8B1DC10022038577368057699B3A37
+178A9F1F6C6CC60BAE820B7ADD0717911BD23A6DCDADAFA32473491AA80CFE90F2A77E24CE2826FF
+77B18B869C33FA292FE01D6477765044C7D14A548B28B1360125C6933F05C58B0889390537CDD16F
+8E967E0B38579449DFC1E07389B7069AA8594C5103465D5041CC929268DE863FADB6925B350AA94A
+27D421FB7FCC81C6B35F906F12246B7A5140511A97211BA9BD6831A508E963FE8BE961332F557808
+488F06EAD75E86D60DE3FA2425AE8439ECB9112BC3E4D73747C1C8E87A649919827049832DB0BF6D
+A8C85C9A2592AC002809070900ECAD52A56F1BFD456AFE066509694EAC075788456B0B0BDD7C192D
+321E9FB6AADCAEF00F570F22CD4A5322FBCE8FA98FAEB681940895426270BB4319C11DA67D88552A
+7373398AEC5DA7C9CAA9F3B34581C6E968DAAAB2751CC012199DD897B448986CFFBAE4D412BF9ECB
+F46742715A9569932516259D3B3A5431CD7028E42FC751C434E2B714C718202BF02CAF9B8A2075DE
+922322EA7CFA605C8376FA958B8FBE43031E1026FBE6126A3775F643EA67EBBD97F239FB3C435526
+75CD08B19CA5EBF53B40D728556B4481C7F73EC71CAB0F89E34D60C69B272FADC22E8E7BDC6210DB
+09FDD913E209F49FD28E8712B8508904620250746CA3B21B026EDAE60A2822F59E912E626B93E0D2
+BFB3230DFD0E54E91A1DBA25A609B64D41ABD897A5D21764C351E85F9E87BEAB9E645149AD32AEEB
+B3B1161032C701647115F98C1C2AAECE871862D91D321AB90F3E923B1FDEE00D927F897AA9812373
+6536E2E0700F10053D7E6C589BF66029D794883EAE4C8228941CE96565B50D48887B5314A2E55379
+59638222A6CA54C77CBABD460DAC11B063519AE4F50D93DE41763BA7CFBF4C7724360E750478EB62
+8921DAA065858341958E4F3EB5966C6DD77C05EEECDF4B5F6CF19AB507589B4219377959BD258EC9
+21C34FE1DB003F7D0FEA3E2FD6F5DDB0A2D62CA5A2CD3C7AB457DFF25094EFE04A9E1B9CE7AE3F30
+026B1CB039228D309A22899F6E9B9BFF922E117123347967D7C62C670E2C74579C35989925603022
+C17B1DCE378031ABC9B4B437C7B6E64620932E93189754C01D4B280B8B08699B2CA953AE4823BB9E
+E34133C5C95B3290E1BF010705AD852C72BE87291E1034B09F44A95B6A2F83FEE8841DCF661770AF
+44D0AC7F9CDB280939FC5D953D525E0B41B7BE188D5C794687330CD770D24D9CD53B895A253004E1
+8A31BE4E82B384
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+cleartomark
+%%EndResource
+/Times-Roman-iso1252 /Times-Roman ISO1252Encoding psp_definefont
+/Times-Italic-iso1252 /Times-Italic ISO1252Encoding psp_definefont
+/NimbusMonL-Regu-iso1252 /NimbusMonL-Regu ISO1252Encoding psp_definefont
+/NimbusMonL-ReguObli-iso1252 /NimbusMonL-ReguObli ISO1252Encoding psp_definefont
+220 265 moveto
+0 0 0 setrgbcolor
+/Times-Roman-iso1252 findfont 50 -50 matrix scale makefont setfont
+<636F706965292E>
+show
+295 383 moveto
+/Symbol findfont 50 -50 matrix scale makefont setfont
+<B7>
+show
+370 383 moveto
+/Times-Roman-iso1252 findfont 50 -50 matrix scale makefont setfont
+<4D6F64696669636174696F6E>
+show
+671 383 moveto
+<6475>
+show
+763 383 moveto
+<66696368696572>
+show
+934 383 moveto
+1 0 0 setrgbcolor
+/Times-Italic-iso1252 findfont 50 -50 matrix scale makefont setfont
+<534D4553485F5352432F7372632F534D4553482F534D4553485F4879706F746865736973466163
+746F72792E637878>
+show
+370 443 moveto
+0 0 0 setrgbcolor
+/Times-Roman-iso1252 findfont 50 -50 matrix scale makefont setfont
+<706F7572>
+show
+479 443 moveto
+<72616A6F75746572>
+show
+653 443 moveto
+<6C6573>
+show
+726 443 moveto
+<6E6F7576656C6C6573>
+show
+935 443 moveto
+<6879706F7468E8736573>
+show
+1175 443 moveto
+<636F6E6365726E616E74>
+show
+1411 443 moveto
+<6C65>
+show
+1466 443 moveto
+<63686F6978>
+show
+1595 443 moveto
+<6475>
+show
+1662 443 moveto
+<6D61696C6C657572>
+show
+1846 443 moveto
+<74E974726168E9647269717565>
+show
+370 499 moveto
+<6465204E657467656E206574206465206C61207461696C6C652064657320E96CE96D656E747320
+766F6C756D69717565732E>
+show
+294 601 moveto
+/NimbusMonL-Regu-iso1252 findfont 42 -42 matrix scale makefont setfont
+<23696E636C75646520>
+show
+520 601 moveto
+<94534D4553485F4D6178456C656D656E74566F6C756D652E68787894>
+show
+294 645 moveto
+<20202020202020202020202020202020202E202020202020202020202020202020202020202020
+20202020202020202020202020202E>
+show
+294 689 moveto
+<20202020202020202020202020202020202E202020202020202020202020202020202020202020
+20202020202020202020202020202E>
+show
+294 733 moveto
+<20202020202020202020202020202020202E202020202020202020202020202020202020202020
+20202020202020202020202020202E>
+show
+294 776 moveto
+<23696E636C7564652094534D4553485F4E455447454E5F332E68787894>
+show
+294 820 moveto
+<20202020202020202020202020202020202E202020202020202020202020202020202020202020
+20202020202020202020202020202E>
+show
+294 864 moveto
+<20202020202020202020202020202020202E202020202020202020202020202020202020202020
+20202020202020202020202020202E>
+show
+294 908 moveto
+<20202020202020202020202020202020202E202020202020202020202020202020202020202020
+20202020202020202020202020202E>
+show
+294 952 moveto
+/NimbusMonL-ReguObli-iso1252 findfont 42 -42 matrix scale makefont setfont
+<63726561746F724D61705B944D6178456C656D656E74566F6C756D65945D203D>
+show
+294 996 moveto
+<20202020202020206E657720534D4553485F>
+show
+747 996 moveto
+/NimbusMonL-Regu-iso1252 findfont 42 -42 matrix scale makefont setfont
+<4879706F74686573697343726561746F72>
+show
+1175 996 moveto
+<3C534D4553485F4D6178456C656D656E74566F6C756D653E3B>
+show
+294 1040 moveto
+<2020202020202020202020202020202020>
+show
+722 1040 moveto
+<2E20202020202020202020202020202020202020202020202020202020202020202020202E>
+show
+294 1084 moveto
+<20202020202020202020202020202020202E202020202020202020202020202020202020202020
+20202020202020202020202020202E>
+show
+294 1128 moveto
+<20202020202020202020202020202020202E202020202020202020202020202020202020202020
+20202020202020202020202020202E>
+show
+294 1172 moveto
+/NimbusMonL-ReguObli-iso1252 findfont 42 -42 matrix scale makefont setfont
+<63726561746F724D61705B944E455447454E5F3344945D203D206E657720534D4553485F>
+show
+1201 1172 moveto
+/NimbusMonL-Regu-iso1252 findfont 42 -42 matrix scale makefont setfont
+<4879706F74686573697343726561746F72>
+show
+1629 1172 moveto
+<3C534D4553485F4E455447454E5F33443E3B>
+show
+295 1289 moveto
+/Symbol findfont 50 -50 matrix scale makefont setfont
+<B7>
+show
+370 1289 moveto
+/Times-Roman-iso1252 findfont 50 -50 matrix scale makefont setfont
+<4D6F64696669636174696F6E2064752066696368696572>
+show
+370 1349 moveto
+<20>
+show
+382 1349 moveto
+1 0 0 setrgbcolor
+/Times-Italic-iso1252 findfont 50 -50 matrix scale makefont setfont
+<534D4553485F5352432F7372632F534D4553485F492F534D4553485F4879706F74686573697346
+6163746F72795F692E6378782C>
+show
+1651 1349 moveto
+0 0 0 setrgbcolor
+<20E971756976616C656E7420434F524241206465>
+show
+370 1405 moveto
+<6C61206D6F64696669636174696F6E207072E963E964656E7465>
+show
+906 1405 moveto
+/Times-Roman-iso1252 findfont 50 -50 matrix scale makefont setfont
+<2E>
+show
+294 1507 moveto
+/NimbusMonL-Regu-iso1252 findfont 42 -42 matrix scale makefont setfont
+<23696E636C7564652094534D4553485F4D6178456C656D656E74566F6C756D655F692E68787894>
+show
+294 1551 moveto
+<20202020202020202020202020202020202E202020202020202020202020202020202020202020
+20202020202020202020202020202E>
+show
+294 1595 moveto
+<20202020202020202020202020202020202E202020202020202020202020202020202020202020
+20202020202020202020202020202E>
+show
+294 1639 moveto
+<20202020202020202020202020202020202E202020202020202020202020202020202020202020
+20202020202020202020202020202E>
+show
+294 1683 moveto
+<23696E636C7564652094534D4553485F4E455447454E5F335F692E68787894>
+show
+294 1726 moveto
+<20202020202020202020202020202020202E202020202020202020202020202020202020202020
+20202020202020202020202020202E>
+show
+294 1770 moveto
+<20202020202020202020202020202020202E202020202020202020202020202020202020202020
+20202020202020202020202020202E>
+show
+294 1814 moveto
+<20202020202020202020202020202020202E202020202020202020202020202020202020202020
+20202020202020202020202020202E>
+show
+294 1858 moveto
+/NimbusMonL-ReguObli-iso1252 findfont 42 -42 matrix scale makefont setfont
+<63726561746F724D61705B944D6178456C656D656E74566F6C756D65945D203D>
+show
+294 1902 moveto
+<20202020202020206E657720534D4553485F>
+show
+747 1902 moveto
+/NimbusMonL-Regu-iso1252 findfont 42 -42 matrix scale makefont setfont
+<4879706F74686573697343726561746F725F69>
+show
+1225 1902 moveto
+<3C534D4553485F4D6178456C656D656E74566F6C756D655F693E3B>
+show
+294 1946 moveto
+<20202020202020202020202020202020202E202020202020202020202020202020202020202020
+20202020202020202020202020202E>
+show
+294 1990 moveto
+<20202020202020202020202020202020202E202020202020202020202020202020202020202020
+20202020202020202020202020202E>
+show
+294 2034 moveto
+<20202020202020202020202020202020202E202020202020202020202020202020202020202020
+20202020202020202020202020202E>
+show
+294 2078 moveto
+/NimbusMonL-ReguObli-iso1252 findfont 42 -42 matrix scale makefont setfont
+<63726561746F724D61705B944E455447454E5F3344945D203D>
+show
+294 2122 moveto
+<20202020202020206E657720534D4553485F>
+show
+747 2122 moveto
+/NimbusMonL-Regu-iso1252 findfont 42 -42 matrix scale makefont setfont
+<4879706F74686573697343726561746F725F69>
+show
+1225 2122 moveto
+<3C534D4553485F4E455447454E5F33445F693E3B>
+show
+295 2239 moveto
+/Symbol findfont 50 -50 matrix scale makefont setfont
+<B7>
+show
+370 2239 moveto
+/Times-Roman-iso1252 findfont 50 -50 matrix scale makefont setfont
+<4D6F64696669636174696F6E>
+show
+651 2239 moveto
+<6475>
+show
+723 2239 moveto
+<66696368696572>
+show
+874 2239 moveto
+1 0 0 setrgbcolor
+/Times-Italic-iso1252 findfont 50 -50 matrix scale makefont setfont
+<534D4553485F5352432F7372632F534D4553484755492F534D4553484755492E637878>
+show
+1843 2239 moveto
+0 0 0 setrgbcolor
+/Times-Roman-iso1252 findfont 50 -50 matrix scale makefont setfont
+<706F7572>
+show
+1955 2239 moveto
+<72616A6F75746572>
+show
+370 2299 moveto
+<6C6573>
+show
+443 2299 moveto
+<6E6F7576656C6C6573>
+show
+653 2299 moveto
+<6879706F7468E8736573>
+show
+892 2299 moveto
+<636F6E6365726E616E74>
+show
+1129 2299 moveto
+<6C65>
+show
+1183 2299 moveto
+<63686F6978>
+show
+1311 2299 moveto
+<6475>
+show
+1380 2299 moveto
+<6D61696C6C657572>
+show
+1564 2299 moveto
+<74E974726168E9647269717565>
+show
+1845 2299 moveto
+<6465>
+show
+1910 2299 moveto
+<4E657467656E>
+show
+2073 2299 moveto
+<6574>
+show
+370 2355 moveto
+<6465206C61207461696C6C652064657320E96CE96D656E747320766F6C756D6971756573206461
+6E73206C612047554920646520534D4553482E>
+show
+294 2457 moveto
+/NimbusMonL-Regu-iso1252 findfont 42 -42 matrix scale makefont setfont
+<656C736520696620282054797065416C676F2E636F6D7061726528944E455447454E5F33449420
+3D3D203029>
+show
+294 2501 moveto
+<2020487970203D206D79436F6D706F6E656E744D6573682D>
+show
+898 2501 moveto
+<3E4372656174654879706F74686573697328>
+show
+1351 2501 moveto
+<54797065416C676F2C206D795374756479496420293B>
+show
+294 2545 moveto
+<20202020202020202020202020202020202E202020202020202020202020202020202020202020
+20202020202020202020202020202E>
+show
+294 2589 moveto
+<20202020202020202020202020202020202E202020202020202020202020202020202020202020
+20202020202020202020202020202E>
+show
+294 2633 moveto
+<20202020202020202020202020202020202E202020202020202020202020202020202020202020
+20202020202020202020202020202E>
+show
+294 2676 moveto
+<20202020202020202020202020202020202020202020202020202020202074722894534D455348
+5F4D41585F454C454D454E545F564F4C554D455F4859504F54484553495394292C>
+show
+294 2720 moveto
+<20202020202020202020202020202020202E202020202020202020202020202020202020202020
+20202020202020202020202020202E>
+show
+294 2764 moveto
+<20202020202020202020202020202020202E202020202020202020202020202020202020202020
+20202020202020202020202020202E>
+show
+294 2808 moveto
+<20202020202020202020202020202020202E202020202020202020202020202020202020202020
+20202020202020202020202020202E>
+show
+294 2852 moveto
+<2020627265616B3B>
+show
+294 2896 moveto
+<20207D>
+show
+294 2940 moveto
+<6361736520353032313A>
+show
+294 2984 moveto
+<20207B>
+show
+294 3028 moveto
+<2020736D6573684755492D>
+show
+571 3028 moveto
+<3E437265617465416C676F726974686D28>
+show
+999 3028 moveto
+<944E455447454E5F3344942C94546574726168656472616C20284E657467656E2994>
+show
+1855 3028 moveto
+<293B>
+show
+280 567 1 616 rectfill
+2125 567 1 616 rectfill
+280 567 1846 1 rectfill
+280 1182 1846 1 rectfill
+280 1473 1 660 rectfill
+2125 1473 1 660 rectfill
+280 1473 1846 1 rectfill
+280 2132 1846 1 rectfill
+280 2423 1 616 rectfill
+2125 2423 1 616 rectfill
+280 2423 1846 1 rectfill
+280 3038 1846 1 rectfill
+showpage
+grestore grestore
+%%PageTrailer
+
+%%Page: 4 4
+%%PageBoundingBox: 18 18 577 824
+%%BeginSetup
+%
+%%EndSetup
+%%BeginPageSetup
+%
+gsave
+[0.24 0 0 -0.24 18 824] concat
+gsave
+%%EndPageSetup
+%%BeginResource: font NimbusMonL-Regu
+%!PS-AdobeFont-1.0: NimbusMonL-Regu 1.05
+%%CreationDate: Wed Dec 22 1999
+% Copyright (URW)++,Copyright 1999 by (URW)++ Design & Development
+% (URW)++,Copyright 1999 by (URW)++ Design & Development
+% See the file PUBLIC (Aladdin Free Public License) for license conditions.
+% As a special exception, permission is granted to include this font
+% program in a Postscript or PDF file that consists of a document that
+% contains text to be displayed or printed using this font, regardless
+% of the conditions or license applying to the document itself.
+12 dict begin
+/FontInfo 10 dict dup begin
+/version (1.05) readonly def
+/Notice ((URW)++,Copyright 1999 by (URW)++ Design & Development. See the file PUBLIC (Aladdin Free Public License) for license conditions. As a special exception, permission is granted to include this font program in a Postscript or PDF file that consists of a document that contains text to be displayed or printed using this font, regardless of the conditions or license applying to the document itself.) readonly def
+/Copyright (Copyright (URW)++,Copyright 1999 by (URW)++ Design & Development) readonly def
+/FullName (Nimbus Mono L Regular) readonly def
+/FamilyName (Nimbus Mono L) readonly def
+/Weight (Regular) readonly def
+/ItalicAngle 0.0 def
+/isFixedPitch false def
+/UnderlinePosition -100 def
+/UnderlineThickness 50 def
+end readonly def
+/FontName /NimbusMonL-Regu def
+/PaintType 0 def
+/WMode 0 def
+/FontBBox {-12 -237 650 811} readonly def
+/FontType 1 def
+/FontMatrix [0.001 0.0 0.0 0.001 0.0 0.0] readonly def
+/Encoding StandardEncoding def
+/UniqueID 5020945 def
+currentdict end
+currentfile eexec
+E98D09D760A3C22CF119F9DC699A22C35B5B35ED6AA23593C76D54CABB5E942BF7D6DD84F1664B89
+699C74B472DE9F8E6DF925F6C4F204E9F1C639B4DBA988ED2AC419FF2B2BDE605B8EE3264EDD6641
+2D4F21C64AC522BDFC7C5502F9C3F3E5592B3B2093D33C9BFAEDD2D49E89AABAA832E23F062E91A2
+5032519D1868816E44B4E0747795003D7930299D6E1E2A5BFE0D595DC97E140989CE81D8D7F852FF
+9CDC7A1B1B598C69131DEE005B415805A16D8A123E6A2261C63C769D2F4B60FA2C438AD7D199D8E4
+5F7E7C9A605C8CA14E21FCD81C9A515FB8DB6F99604534D06EA9D87FE0FAA852899C9D0595C7A97E
+6C55F79FAC45CD38E87B10D210CE7501E88C8FCD3444354365FB893A12F596AE2C1E70D5819EE0D0
+87D10BF8DA96F3DABD5405D28C4228C6C31BA4052464859640933FEEFD8071C0C84CDD829A9B1D0B
+A01F25A4D50EE2EA2B45160CA6333B2D2800306ED2BEFDFE155E9D9F9342EB8D5B0ADBF2460CCC98
+643FB1287CCD28ABA7B5CAB92EC39EE2E918990372B16F8487EBA30EAE88708B6CF33B6C015D8096
+C7CFE2F139F52052E3925C0D50FD64CE68236D59CB83EF56BFC584150EC38065059F3308AD6F9A99
+F83EF4E6CB13855C8175E31417D190D036B387D3952344A950F4D8C7781B307A094DF1ECAEE4D2C2
+FD747BC6F7F9C6BD0E90C19294F96C8C5CFE88FB34C477574A1B1630B8CC591529E59B20794DA32E
+61DECDA8ABBD1AE956CF74012AA01D42EE01E861B0AA6897C864788AE59DEF43C493246FDB1ACA55
+4C12594BC7B33657A9ECC9E3D1472EF826073F632BE540C35FF6FB40566773F3BB2204D3A579A08C
+CBC844C14B18C350F003B9DA23A570C362D6003893CA32F86F59B829C78EE3188B6E3F7FA81D7F62
+2825C639638DFB78B7AF1F500F5B450FA54DBFA5CBA277C794ECE93275A3DE0B452FDC8DDC2993BA
+A42F28A636008CDCB03EBF71BDCAF35019778993443F88412AD2AD0D7155A3944606463266322DBC
+0244B07DA1E9C27A27B59664E8566D7A54CC03E995AAD008B0A17E2C3EF61F720CE7F7788599C4E4
+4C709CD5C31B11107F16AD70B17B9AFE2E8CD922A7428DAC171427FFAF51067307FAB0ADB530E701
+FD22DA22C4CD3064067BD4F6089C4B2C87937DD426E4E9D2F60E608288BAC9056554D04947E69200
+61E379CF5E81BFD32FD37EFAC1F61CEBEE551B0851516471A7472C60DF89DAA9EB1DC5A67E479745
+3E69B9E22BAF4E3CCA4192D603295B018C4AB69D18DE52DFDF15E96B557F290A4B8C5B1E7A6CACA8
+1F2351B97ADFC36995ABA43803A6E5AC04A3C93495F6D38106B8B144449C07D1358210F9176E1565
+72363CFBDE576BFDF99FA329DD1346E83F79E06CF68250CA57A68931BC7F342AD295D0CBA17AA95B
+B8EEB53EA6E8E660B814E9F857CECB14F44A43288B69A9E7908D55BF19E844359879D28CAEF1C38A
+36420185D20DFB32C2E002202800E8EF3D67C5D50E919657CA958B538D537D503444865331D79BFC
+40312068D72364503BD0CC84B5F30A74D8B5B6A26AF2DB764564FB65A6BA8F9051AE2B4EA458D46A
+4569F30C6E77DC097356770362E6CF3F1661074778EBB44FF7D1E3B64FF75E77E11FE525BB121C65
+46CFD13300CA1F02D571B82A5825E6226D14FDCF27F06D87452A8B6C5DCA658535CEE2A795E58137
+D48E566B69D53A0C3B766E84C51EAA221C46999CC8065ADB2F129D5B630FAB1814C0C33B5AEA0EFB
+B6E994D80941B53079AF96D90A0B924F9B0E319BED9836B8F9053F868363D3CA554CBB181863301F
+8CB940872ED5FA7BD18CE39218B5AD8AC57D0F752D941076B1C64D99BE0DB86D7A6D96510D772EB2
+4C587F11779BD21CFE5BDE1F29C1EF9022B2B8BCD7F91153C845906722477829C40111D810480F3C
+F62DE8DBA7FD86CD236E656618CAF6FC46827FBC4898EA7672F8C9971AFE43E0E01EC8B77D4AF48C
+BF1210E98C1DB15C16D149BFF58AB0270CF015B107A3A50F5DC8F37FFB92EEC8CB6778DDB7CE4AAB
+C464C4AFF654223006A550EB52485A23D2B4AA7198D3CD54418102F1E9A4FBDE37B841E56F5C2C53
+966DB9B66B000E4588282E3FB80C2C519339F0002D2F83C979EDC5827A3B3C8EF8810A0F9DACB6B9
+998E9AF6551F56313DC4011904CB979AA2D32B11A811BC248141E4B9734D9FB7982A5671002D8279
+CAB93ABE057474628DEFC95D43890DB1ED34CFA8A20BDC3D874E7679A396158E522ED0AB969A4E3E
+C7E4474E192590504D54DEB7B260B7935C4E56548A7D121AC1F741F8CDF259EA1B5813175A77A1D2
+D30BA26F65EB765A04C09ED51F69F41551ADF399E6AA2FC09788137BEA4913F17B8EB838C38FB272
+1FDCB55FD65697FF0B850E7D3D1CE266BF90F7EC06A9A0876BDFE767D3A918B092FC78C775F945CF
+1F96E859C03DBF630D9A940939654C3549D8F7921CB94EE23D5A0535DE9DF31EA0F937F860B4F220
+A99ADDFC343D7CF7BFA0B803C12C26403F0DCFFC8EA786D0D8A8D9C367419CA8AE41190CE93A8086
+583A1E6C9D70B612C84D87D2EEAA71EC2DC12F4CDE6A821303D5F6A9BBDB7EEDCD289E80FA3B75F4
+7F481B50719DCF4A142069393593B9AF9CCEEAEC56A35B8787193D7C88113E9E1E221D151E093B01
+9EF89F6118BEC4735103CC8003CC5AD1B6727B3226CD44C497DA7052DD681695DBEC3397F9598C91
+77701C73BF0594CE93F23D50EC5BEE2FB9DA1FC966DF148B27B28EE3C89526DD6625E2887F9FA076
+7C127C609EE315626BC14D274FBEA56528DC06A27B2D476D46E9E7916590B156A5DF04A6CB15E362
+45D77021767B6E5BDFCC679670263FD891446C3371B11BB6E1DF60F960AAB4149D7753E6A5C33810
+C42C8BFF4E935003388506F8278BD7CB672F132E065AE684DCA0B9064D01DD620E7FFDFE04F14277
+EFE8E60159BA0FCA3FE2F28B902D4AC275D19F0AC6971EBE827C4A232D87650D2688345BCA78F879
+077114F0463C5F058107B669566F8171E4E284D278405580F04BFFC9902784216E0C9A17AA9B2935
+E66E18A783F723BE044389B7E9D62AA36818FF2EA406C3C1A9D2F3436F3EE7DB8BE86AFA8DAA6A4B
+1B84611350D8D27605509612B515E16AA843164D5D0805E36A2B9EF74C5F6A0B9D59A04B55697123
+27F4B1B30E9587CD103337639967CBDC655AA46E80D2CFD24BEB50815B5338E522B3A7AFE8362AB4
+F05D8BC52BBA9C5089ADA8C89529B0275AF422EB540D31A938B8740860756325B966B36817115213
+FAAF92DE63F6BAE1E0064BFBC5588098B61EB83C71F1C2082436D37DAF1ACBE186FEDC4BE7C1233B
+6F18BEC5F99002D21CB7864E4811F7AB3C03003E1E4490AD1AC793BD28FCD5EF0E6CC30EF39A08C5
+2F71939B0CEF620DC69E31E39D6DB969049031B0C92EF2DB653D97F370141456A52985076B268652
+FA2648C792780BAD637C4D7581FB2D62011D57E293719487CF2D1F013CFAA532E1C2D39178D51272
+A6AF041440BCA174B5CC902BD7390C7D3695056CB4BD7791F9FB6D88E7A70DEF2C97869F5DBC5BD8
+23C517C7B7C39D624DF627DC9653EA5347BFDA80B723F05F6DBB4C9EA501D862ACE05B9DBDF21B70
+56FBCD8C6D4B85873DCEE6166C8B5ADC0316CA12D9639F361B15A42F00E1D62EDBCA1111972FA0F4
+5758BECB31DB38316F3CDFE1B41748C93ED58B67E9B57ABBED5924A6D53E99FBC9A994A6489A8BDF
+13EB685548B4DC6D62DA7426C22227D4D43B6FFC7B5EA91C896730253E8941AFEE588359C2BECF6F
+FC415B9EB6D31CCB0F6C7F85853E6449FA6D627A97A3CE8303F148393ADCCCDFA2FE085C6908BE5C
+3C05AF00A6F02840206C3253A559AC5C049BDDFD11AD9B118403B84DA10AE3C470CB9A9A2D1D7B73
+2F59F5FE146DEDA60AE750F551AAC934621B4470E1BC324C436303E25F81D0DC3188BE0D6FEC5414
+C20E4CB18952E12CB6423DF7124627ACDE145500D77A97A8BFD9CB50D1FAA008E2CE2B2505A4749F
+1EBBB092C347023714055A9B63353AF9E7FEE05BB54C9843698101F79888A91531773830C2C967B5
+88D3ACD2192883D5CE3962D51084FC653EAE2C5FB2DA41DACEFB5C76812D2EDB5B109677289CD199
+8D457FB1023A19AC67295BBC1A9A20A426B06A368DF3C5DD083CB1180D287F5500F2C635EDE157EE
+FCEEC5503447382D15C748C1E35F68753992E5C90F900DE54D18F8E1B355D1076ADFB1F3590135FA
+D1A36F028E44F48ABB149B80CA9A54614D467F8D71CB310BBC7AC7100261092DB8C5BFD39E0AC6BC
+2C9D6CBC3A8C05FF8A74CB21608EC4A4CFE4CBAA2D056DBA14206106044DECF59F957EF8A9CADE4C
+9B19D8D30DD4FDE6A9548E50DB51ACA73330142153FC36B69C1C8D5B26D0C689B7040E81AC2C864F
+D7C097C99BE5953843E172C97AB5684F35FB03A725A89DBF371F08DDF40A1531FC1B676DB0E1543A
+EC6E97D3D2E4AA3D5831D8B3C952ABBFA112352814FB6FAB61A0D680E6640F6AEC8426200CF61286
+F7422CB2F78C61EBAA36D47EC16D7FAF8B4AF31D090CDFA255D9D7C61D46CFB22A7D6E1758E71ED5
+67E00CBD8E8F468DDFB477F091A2F915627F22FF47B876544BC1F03B6BBB98385F009C20BB1AA2A7
+A78674692B8EAC2E3C8069B79E679338DA57F72976810F845BEB6B9ADD32B95D78E5E60F16DD1668
+9C05FD82D36A3115BE8ED494A74DD211D58A2CDF983FCB9CDC29BF7F0E29988FA23560EDF514BC1D
+183F3B2A22C09FB179B47E05ADEF48DF02F31C29875D1915037B19407764A4292FE44E741651A8E3
+BEB5F0D972B6327090F664417C84F84FFBF0AFFF8B1D85C822D90730AB4140C42A51AA8B1DBE4398
+4EA8566040EB8B341CCE23FD3F69DD235A080BA5C69AECB9BC732BC2D7D40617DDA6B79FB6EE40C3
+556C7DF9B23DAD89E94054B1345DB8402AE679FC4655A4A776C0150463F8DB2BFC0608EA1F124E22
+1DDAE6026B5E5D007A7E4A0D6B3B0CF3A2669E67C5E4F01551966A7BC48F2F4B6A87E740D8095E63
+F77C7A027F26B52F2299DE5B8A2F6209BCF3D31CB0235F998F781E5CC81E31DC424E008D46EC0920
+2951E5684804A0592EA47D6C788A20487BEA2EC8F2E6C1D7F378B62DB43CA43C4B366F8B4319631C
+FE9854F0E10321CFA3B01C873584863BBEFC23C72C05E695B56E8A52E89AA2DAB543834D34DCAC5F
+ED08DC51825C5257AE59850D101D84F4CAA1D29FC932F9E0EFFBF7A9A7F3685F61F0490CD3CC8988
+2DB52A757A6AF4C4E67B407BD2316B1C0FFE7DC54E43C87B874F57E4903334E2140B011484863CDC
+ACA331175F2CF3D72E0042855983AAF8853D3015E870FF0807014C31D55060DF3FE1FCE157324481
+2744AB51322444632F9AFDA6706E320FFE82B8CBE242A19DF00CE73EE48E25FF49D5871BD3E60652
+298FE3E8D400609E232E0DDC794C0579ACEF89E841B2EDCA50D51151F65E8C1CC3B01EF1870558F0
+BF5743718C3E068617E81BFE120C6CA16E0924BFC2541177D53671CAA3AB641C41557DCDAE1A3461
+47B5E999C4541B08B4AFCBC187AFD653D5B5F8386DF6AD8FE69E21BD0567DF494F736C6A184FA4DE
+48DC9F347787CA96E2E00A296C2DA05C2AD9BC423E9CA428D7F1FA12DC9353A302FB8C529AF8688C
+BB543B45B2717EBF8F6C497935F4F3BFFD285E0402AB7544B3CA4643AE5A8B5250ED987A95FC1F27
+5B9707ACD0641BD0EE2AE9758494F8D8A51DCE408A38AC20EAF0852D72D84D0C6BE973326793AEB9
+55EAC6FE0A2813A355DCD22F6F2CE56588D1C055CDDFA98878BCEB6A018DB22922D2B600A20F8184
+2E665DF41013CA0947C4237C2BD60A75E2FD1A3FB8C8FA19485730B87461AD466ACB02DF8CA24091
+4FB090B3D2B41EB6B8FF05E1A59D9FD668AF70BA5BB72778953BA55FC5F9F626043450E1D09BC83D
+8605098ABEF884639A37809A32565CBEFB3FF39EE53D6C18C58C272BB928E4410E361E59A50F242D
+69747A032617C52DEBBF62364AB5A96EFAF642D9D82BA679B1D70FAC10A4EB62FA5CFC308E86368A
+AAD7E75948F43598CD1C544A0D4091374D7E88D4522CBE902391641327E888E7748FA889DCE67ADE
+61699E7D77763681CAEE9B1CA8837B2F7EF9C18CBCC538C465C8E2DD34616953CCB6030A222C728B
+834911C1A179E2C770289407AB28B303E724D97F747D6134B425216A64C6E0B60F633E2B85300047
+E4C90339CE030A0FAE31E830C8ABA5AB3386A3B69267351A7BFDD66356AE5E57FB2994452993E90D
+E7C4E260ABAB93C37831856A650D56E44172FECA01D6C7C380F250B82473960D2A2A5FB6B4DA668F
+46E624ACF7FA0FD4490F485D640A3ADFC9F8652E7A38CE5799F770C3606DB4B8B947F93967F779E3
+A3C0572F13A5A187D31D7BD12A5C7BE23CB6ED6192086241B76C5BA6983DB9C93E4B208D707D3760
+F03CD6272EF3A4CE89B8E52E6AC5871A3D03EB975759AB4BE239E5EC7842CBB333E692CC607C722E
+185D3C39164DD320C6945629C70FF66A5237C0A9520A1FAD6EB9816069351AB0F135D90CC0982B14
+7D2294AE4A38A527EE40BE9CDE2512AAEBB590E134388BB171D0956A7C4566D65A9A041BE6C4F883
+6B3EC3D2ED1B48B566A783292B15B6127920D247D494F070BB20BEFF60640B11B276DDEEE49706E8
+B2B21BB40B7F00AAFC594C492C25DCA774E0B80D82E927448DE2E74A9D0DC7AC9260096EAF187B6C
+D6AEAA6D1DC4205B4411122751A5B22688404EA7C5861730371FFAC10F5AFD4727A0E402AB5EA757
+606B75EB86A05E8F774D6E430A1A3FE2A37EBB06700474239FB1CFA05EE44B91B82244C575B52E7F
+AF934B04EEB0D933FEB57EBE326D75821C8B23EAA85B583AED4320B7F04B9F2DC591091216FDE52E
+064BAAA9C2C9D9714B95A4558C21F3CEBE624B5403B31508F178581AF6863083ED762F1E2E34A45C
+FDD71660D626FF8648F5D6C5E580D4765A67FB6159EC8077A9F0A88038C8D3D7C77FF0926E2123BE
+874F7BCAF129D55A5B5960F824BD1728ABCFCC51D23936DE9A25C408D786E44C3A2BAFA4423177AD
+060D21D38E15E23EB6FFC0B4120E814695D423EEFC2744A1FC81B4DF89D76F0A6803D8B14E75538C
+AAD03A72517B86514F6952F6FD619D9E910D980F00964DB325318C045BDF79647F453D4A5CF4E61D
+D5359782827229310405FBCF6107C3AD9DDEF9A9A339D5D5A6EB2E7838A0A43221BD62CBDF732DB0
+A638A52016FB35BA7761AEC846A023D3BF2D1BB183543E81EB7CAC1E5970CDC6F068C5EA118C7AAE
+528D1396E6DC939112DA4460C890EAD5C01BDC438F5BB734218BA6270ADD0DC1778FD8AB16831D6A
+302B814A1A44B07EDC65956C9E6CF4875DF521F3CE5B422F71081B6D69BD270F739095C9E81C0377
+934A8BC6390C420C4E4CDD9CF7E32544C68D884E15ACA3BCC07FC8C132D8FB9D752C15D75C52C288
+57E2EA461A6FCAD90C56843513F74461F18D7164BC597A28AE4BA7C86EE1703535A9B9ED50122627
+71FC12F102E800E0E1AF7BB46681BD2B14B614CEA91B7B2AAA35235DE76C0E113C92688F8EC81277
+D58C3406778E1EC1CC15F1CD9A137C8FFDAAB99ACE3BFC782916F1A877170589A92DC921E6740A22
+B84DC6BACDABCC76E64C79E3A588D80F8F4D376E1B426F15751CF7391102102F0AFAFD8B22DFDEB5
+48AEB5F30B1673023D22054A13391A0EC08DE6E7B685A0D031AABF20B7C62187C0284892D5EAADF1
+21BA28263EB863D5E36EA9C06A77CCFC0E17F593961591F84D82AF823EFE41044C8D606FEF83CCC7
+B0E961E7994DF8A3CC36B209D953E250ADAB8D22D7F2B4E2C9CA39EFA2D93E56195C1560E30A5190
+CC5B17FAEFCF250DF79F6B624A4B917E11C332222FCCFEC4F6A47BD9E75DA9854FC3F7AE554E91ED
+DE144D7AEF38A0E3EDB5E5A5626374DB94F022C8CF549093041DE00D7269B7CE544E748439BA2870
+718C08E58FB4A77D93EBC04B7957D272AE1601D41BF85A2BADAA0DF73B0D3841D4839C85677FB2E1
+5F1D6CE592669FF4BBC9C69DBA334DC37706F2F6BE83D5863E8CD6A30C08640AAC4C233684E66B4F
+E6B62D4A8BE9D531E47BEF5640D9B5C27D990092BE1597F6995C8A77BE9C18AAE6C1CF130775DDAC
+41D34438FC7AD8E042CB56CBF2944932EBA7D053E9376FF398367450E35A1945FE23E05C921096A1
+5454721FFD0F429A3E06DC3ED36F1C170BE79C66996EF8337AFF85B90C5D3A4A94455AE9FA32E211
+7A63E59001F052D5F6223125BFAFA40901E98960ADF7BB886729DCA82FC3B8CC52B37FF2517299E1
+D769057F8154FB95582F02CB0BECC873A9C71796ADBD3E91324FAA94F2C41CF57C30B5897D031C02
+D256C909E080E70BFD1F32E69EF67031138C2DDCD1A8E4B65E485C23C3E450ABDD9815512D6F34A8
+4B9DB715DB2C7A93BFB424316E1AA44397749CB01088428F149A3B4324737ED9957FD388248462AC
+1B2610D72BF5C073ECA567E7385CC959E37CAC7E05470160FFA5A9F63B8E9B082937E911586EA165
+374938F492EDF28CE6020953A5B5CCEC7737F9D9CC8538C4339567AAED3794ABA3B9F4EAE65466E8
+E326F6C399B36355935FBDCB9972F10B13494DC25097FCEC5A6398F275C8C151558E74C5175F7BAF
+4155E36B733F75CF9D5C5979B0764F14D8306E06BA24BF791141E404C69F3F8FCCD91B9C58C2C671
+AAE7D4F9E5D6414E46ED633A5F78AA5BF04E652246A066EAD9E582B181CC196EA2D3CFAA383B5D0E
+4CAC9336E119C08CC6AC55CBFBAE147C623B400453BBF447E96DE036FC025624384359EED7C7D5F7
+858DC0521377CF647A157FC3F188DE5EEF094DBA125510FDE34C570D7BE76AB5DF0A28BF45DDAADB
+EA7EEEDB936332DFE93081E0AFD3FDD46BED08D6914B2EFCFDC41662A33B90B03D76D34F48D30FC6
+BBBB600E90E6AC7243FDF026762A44B4D6E4ECBEF48C9D7B696AF29EEE063E557D8FCF0F09E0136F
+45D17E608DA36E59F2AECF8493F8D62536119B5F7E1554DFE3F6E8D7C9A2C6F557D18B4AF92C9F6E
+050975C3B5C54F9B5F4E39D600B6FA2CD6DE203A174028CBB2A201AF126D1013C229BB82CFD013ED
+199D01E51EE2780FE896E01C63C655087A3E61A7F1029FA5E97EA1872F1B45F22282DDC317E17926
+7368CB52DA9444F6055A3C653659CAD2A1D8712BC2B1B32C1DC6906D957FB88524EE066156ED6BDE
+B8D832F9338F9912E29A250A8C4674E667C1C278B677AEC9972BE83CBA3FB779893FCB8F81A323AC
+91474BA2A2334A07BB5628E905C518E634F6761A3289056F83D5DD7B3890987EEE1C18FB2D379CC1
+905F1AEB3B3D2AD578F0D6C845D2D40C4BCEE3F71C90E68E5417BB8CDDD878D83BA80AD8485F4067
+E5C3CABF28AB56CBB219C0AAB8FFC6C7E192BEC8CBCA1459AE4450AFCC81B9548F40CE2622E5A7C2
+81F74DCC02DAD57EFD92D072318DDF05BF42F1EA8163071E23949B0179CF7DE64677CA99B23CB926
+B3E294194EC13397EA1DC9A5E1CDCD828156CD71F81B64167D4FB01E6002713BD8AC6F82B20CD369
+9C6CA4704DC5C65A2D66EB155B7AF1C9BB46469416FB49C1C7E17A30A5F045271D7DF3FFF2F42C6B
+470701C381E3456A500C6BB3D0E47B4D91C5F34B49BB6272F1F8698B307D89EDA3A1565DAD1C0864
+627560CF922DCF5B34C67860352390B282F95394AA2CDE0E97CE3ED39546A6AF1C52BFCF81A29BE8
+2C47C99E8050E4889E4575B75F39E662F2DB7420673797E2ED3D67CDA7AE2C15D0A0A794D57D168E
+BE13214E89E0209AB2C0EB7784E9491AEFA3C02D0DF3AE5365A0FC4AE023CAB528162C7A1B173664
+9DFADDACA8DA5FA18B7D6489E4229E9E24D38A620464A744A5C60F6F9D334B908706B738AED18669
+8A8B278341FA4D65A0A88680BA484694921512F7DE93337FC1C02BBE6E64AF2DAD07603279D87329
+1D1F4D39C1DD6D89C90F65240F4808F6F1115CA55B88E242565E59F3BBF1F10EC7B88872E9AE61D4
+4CAE185463EDFAF7DF63DE4D2207D307AFB61501892965170D2945846FCF5973A1D458607F50C15E
+06E5BEC715E0C156259AAA6C735593E5564F65F443B78CC7512EC35A56F126DF9D30974A40872E42
+65E1AE5FD483CFCBBBA26DEE426CDC4721F19C3FDA86ED7AD4FA1120F63669BEFE7002B128CEAFD8
+C63E8AC09943B6CBDFB3D2476A026C00A8FF81B1F651B97F310C82ABA5F388CC1DB5AFCFF5996D52
+52A6A42FA4D972E41EE56088F78CB966F9051171C472C774879AECFFF08BFD9CEA40D7C298922ACE
+64F28C14E0B81F4DCADE81D71DE3983D87D905192EF13CEE71B2D3FF1A88AEC671EC318917DF98A3
+C9054E372D22A3CEC82FCC217F47319A40900312F6E32B536B9E7A7FA0837EC65CCDB5FB0D414371
+17596CB39D9382262DE6E65379D3A9709B2CFBABF5FC5D5B352425F06F88CD31012A2A4147B112F0
+C1C0ACCC808CD625E0228EEF66661F70AF96D3DCFECD402700E4F6522AC9A856DA466D55C84F65BE
+2810A1565163872D62EB81333A698ED7B68352CACCA2D7AD38AB55C19E4F5582F75818302F5FDADF
+1DCED09D94872F2D48FB636C8E38C7563C72C771A08C6B1F041F3532BDB39006C89A33C09BE1E3E6
+03622D891F98010BF1DE5355F557A1E09448D486ADEF565705277B31B8BF2B86761E32631E3435B6
+88B79D566F1747BA456DDB43CD239FB47FF7B425EAA4C657C8EEC26EE01AED07CF916E77D53634C1
+37AEEA009C6B515B6342C54BE2C7B95955B1A9DA277A0ABCDA2346E88018C726F481F71D6011AA42
+F8852F2E5749518FE3B3AB668213FE1A05C10A1C53953D75312631D6BBBA01D418199DFEFF8CF548
+6109B099FE8E2F606165FE30F532C03567785D5362AA873C9D3EECEB20F1945D55F49B0CCAC84967
+59FCC7292E46938943C262D78F3212D3F9D0F7B103157F423D71B1ED54B2A603F4C269029918F238
+EC6828FFCEC66009DB9C9E59534EABB183F31D7AD4C57B1BDF0BD2CE5A421882BC10CC1BCE6A970E
+2B586BB221567CCA483989DD0B8DEC424C1D1FF042DCB7834423CF244EDA28D2D969B17440CAEAF0
+24A6119DB010CE366821AFA424D1B8299609C04148275AE6E5257A7ACB3C766C747CE99CBA2D703C
+F19B7CF301B634D8B613DDC4AFE4633A4D77BFF8E00CFB5E289EBBCAC90A24307E7941EC1685CBAE
+400CADD876FCEF7F6557EEE167D2035A05120293527700DC510B038A496BE1D5CBAEF24ED39F7421
+1A93AADF22214ED606A80582485AFE358E3A46D0671148998A3B3BE209467009B43400870359D418
+9A8CEB4D5866AB52D16D9CEB1EAB71C07E6CAA34B70E3096BF7604C22C40D5FBFEEA616DA3BABD59
+DCDB97D883FC8742B8267A16A99B7953225F7144568D566E64542C92E538AC140C851E5D295528EB
+7CBB49909B1CAF6409C9BCCEB325468FA0B5F7CB2987382616B477CCFE4F4AC79E4A6F7165363543
+F04DE5B6F6E1C2E910CDC3CDD6C4C92737198F892337DCB6647BD226C820AC99C65D8E7772BBB74F
+E65DCAA8A22C33BC168BF48E40A82700A3A7668C5A9A71E397ACDFEE7D556C5C19467B7AA69C260B
+727407AC837BDB7D67DEC055C1F45D8BAC61048C45BC9FB3CEFE7549EAA2992D2EDC126FF7A05EAE
+58613332A2BC1465B2BC0429162B907D65F793D236EDDD8D35405866D71B25F62DC4A7E06D4DEE82
+840ACCAABC0774F8A63E9C0F7FC980B3583E7A8B01C46590E3BC04EBA565C2EA94F057D964A78A90
+EA9F52ABFD70F84E44E434BD10A42E98C794065724341F907E35D3CB257161E01C7084E3A0166D15
+CED65DA7BA87DBB2EA33D39BD99AFB93D3548358D08330E807F8552CECF63C84F805205491BA3A1A
+622E70C232FADF3BF2DCFD6F0539158D3306506F150B0518371912A25EB96163D73E9EEED42EDC84
+D688BC7F7708D9DCA348FAB4DF62E5809BD094842D0A31DBB7C4B41F94D946810C5EC10B69AABC2C
+91A59500B2E5D37F4755DDFB7AE4ABF757F4C5BCF77C7F95E6A616646456FE8F18407080BCABBFA5
+7704287AD26222DF91AB2613951E2D679472F8ADF06EA2A20205EC19972299A78BAC52114334470C
+5F5890C2F846B4C6042D73945127F2E3910ECA1C4CD7A16EFE4B4BE38A15AAA710682C3836A8CA83
+FD384970139D8B46FB0AEBB002DD224199672FFA02250FBCFA4E649E335428FC71F50F45E498419E
+DB0E970F46894A48F65580881C9C4250FCEF65C9B28699408E18B26FE6DB7F1CBDB767564E73CB59
+54C6D639CE33220C894F36E70F71C9F9AA3FE2AE0AA0E3F2E304EC5ABC661675CDE2E70519E4220A
+E26FBACBD01D5169EB844750753E6CED53E3678FDCD08AB93E10067E9C64F38B40B76D99B6CD92BD
+F4155A1EA5CC824998B59AAD06E09E5F15EBB2288D66EA71B296616734FEF2796F07FF0D8B047074
+A1111D68B99C2B70FC56E74A51B062F4998ACC85B1943C9477E436E5CD7AB18DBC898D21BB93475A
+623BDDA71D7B895BA2D4C10F4B90BF335126F4FD57D73AFA50170F6B3C364922E551D40E35DA75FA
+891762FA23401D39260F2E92C7807C746F13BB35CEF9DBF2E76E66A72FEFF095DA482A4DE8A42091
+7065736CF4DE904FB52E649A32255E2030A7B31B686353492F31C064A3C4B0448C4BFD44B8E15384
+FD809B8761EE26A7DFA1758D57CE4F0BC376EB2B3833534B15A83436BA553955ACB5A7A66796AC5B
+92DB5388BC53EFA27508B08E82821E5CF669BCE52BB860780F749B4F38ACDF5FF12726BF3EC2743F
+01014CDE96FE6B4C40A034E9EAFCA2A35CCC776C2669E6AD138070A40F48ED79136D7FF57E993E09
+B81C543FBADD350FF5B5F7A46F060F88E30FE2D8233832D18B6C323EE017EBC1DF5C838321CDC8A8
+4CABCAB20B60A1A3AA028F36EA6E87C850AF8AF7CD50AA6359038BFA8818821D02CEE8F51DAB8C05
+F7AE9797814D97F3DB8CCDDE45B21DBB15CEE292FAA534A5F317B357F4091F3DA357325B8B9F5EDB
+45865415973C143E5E5BAA483FBF2D06CDD4246675EC58B84C6AE65CA743117FF00F229243772561
+31A7F2BA26A9115AFD96C18216CFDF41B7220ED0CB3FCC26C36380007B382A02AEAE428887DC8BE5
+FDD630AC57EE3DC156C7B8B29E687F24442E35CE10BA4087295A641F7139C831F7CCDA6CCEB5DAFE
+537CC1A97C5A337D3C48A6AE947F58A30DC08CC7B58DBBB4737AD52783C573FC1E9408F55495A80E
+7FDA61F0B9C4F090158F1A416249EBBA936C27BEFDEF19D1BFB839EB70576A010706D8B95657B218
+9C2AE04C11EF9E57FE09880273761FB4302C388BD608FA0C7F00F033C9C00F4E3D5CE2D903E0DA52
+E69C7745EE9FA75E2AD93DC6CB5CCFCD3782A699B807AFC36AD1F62B05856D5DFD6F88831B90EB3D
+CD523582A49732E3FD7253126D39E8AFB8458B5F7AD7F94A8DAC13365F433C857AF4A42C0A08C4DB
+9887C4957259ED22D13CFDF5995DA957EA5A0F620B0214FBFE08AB6D552DBF048D62CEF6EFF12F15
+3511ECA7833E0E3E95F85E6AC0F95438AC4C126E1F1ECF336ED31CCA7EB216D279877123FD9FCD8F
+B5E52B587CFFC4428456DDCA816819A8A4A211D8F1629E5D42BA4C5C356E580C8A22C61D987552FA
+A97893816DA73D423686E4EBD44375C257F031318865A20F22115E72BF1EB9F93AAA169C140A33A0
+6C35BD4526A38BE79CF40AD1EFA10411E8F3300A8A8B97AB140EE6734E1BEE6C8EE443D698D34159
+97649C6F10F20ACD80236422E215E146D744A262DA3FC88DC0D86FF66512F49D3F957D3C5CFFEB42
+4823509F33F155057A4C6F37B52F4667767BA94F6B8B62856B553F307E5D230C44CBFDC9A97A45B1
+39FFB2F2565EB0E22026972FAD0FB7B9576FB6F368B61979943A398773600E7EE1DFEFBF26D45D40
+BDA66EBB96A56EE9CAE0B2420C5DD83E24DBA9FF885BB844BF3D2BF93B07325DFF60C0CB5FDCCA0A
+C8FB5A2E119D5AF26E53AB8E3B428481C2871DDA26EF0B621CD8572B3C664BC7AAC01A1D05B98F79
+1A7080D294BE81099BDA7982432F3DFF4775C44D23F4F1B2E0162B61A8B2CB5EE8564BF98E2ED403
+2219085FE6194C19DAC98A421826CAED7F1AB1477AB327506010217283894235D7DBFC1153D5ECC4
+8AA7293F19592B4D7E95FE55151889BCD1D7FA7DC2370D2DFE11D7E4EA34B5C7A8E73BD3A348FD38
+9EF45B6167FB90BA44C23E912F9A4F2FC0427ED070592F7110183BFDB2C400393BA7569058227926
+351F07FED4F33633BA03A72AA2DC6B598E49B96021DD868DAD0F352E5722FB714F667C15C68D49C0
+3D822D82677EDFE86FE9668E537DA284068C9B0AED83074C92A5B939296D505B837E6A9DDAB1AEAB
+7455A08A114C2222B339284674B74BF4CA9EE0C020BF2A148B439C71C6BE51A94CB64FBE4A7EB295
+5A455047CF5CB348B062ED4F6471CBC3E9ADD9BE9B96879AC7BC71BCE02FD02F17C6063985A5E898
+3D205AA1489DA13C408990ABA1C54F2F501AA172F530480D789C848118C0A74EF98D5F607A067BAF
+F6030D887AC6A6497F9A0B38F9705F328AAD4BFBB634F739386177B07F22D5771282444E5EE17335
+B4D0EC86117C697E79A5F4F65FDC08E4904DAEDAB20067EAE2448FD4301849E456D085F392DD1316
+7ADF75CCFDB723E2904A9C0C976D6B84DDEF9D92B0E15FB246C3ECC2D0BF314CFB957757B3A3E8E5
+801F520644E4601D291DA0F7507C06F3B9BB36FC1C70EAA444E14E56C0CFF06C7F853DF36DA9D8B6
+AF2544B853DFFF535A7E5C6FC145250CDDA229956019659D0D253A19A7B51A4E538BDC01F74D7704
+9949C2C97C7EC6392C2E61CCC0992B66DAF1AB08551063E53180D2A67DE496716CCBAA45462D9F91
+B66A22545962DDAB120511FF08627131B95E5DEEB8B4DD9643E7B2AF65C0FDCE11F5F1E8DD468DA1
+8D41C8C4F00EA73836F4F70EC50FC3EC6D358C0658A4261C6D15A582A2C7C994E7882E661855B352
+014576858A265FFBC425160669CE159D07EDAC04D060B44E5800A7AAE8E339C29B929AA81D2F515C
+46229D2080D5917AB20AB6B34FDCA8E4AF64ED660A3173786FB1A1D005D575C2A5187D3F7CFDC94C
+CC44A38C5CD523E9DA726D8EFA6DA7B6131DFF3435FEE838B2C7D6B97934295F06202D307FF78D90
+6699CB9C5BBB10D1D4DEA5FDA5BFB094E704607083B646D37F5DA1FC7AD21B813F44D8C1AFEAB666
+55AAA19703BEA2E77DF3BF350E17C74B3447A452235919452B5175570A006C7680AC05E8950A62E1
+1D7E3ACA35A397D1E19630D094A86807593C97F4C484E4E06BCFF708B6DCA972E3A0009E1CAC0EA4
+141530F5C1B8AEF5E1B933F37FDDBC4BE22B74FE346D1A3F5FEC0818F8E61765568A2AC04713E828
+F98C449D9A1CCE52D10D61DD8BFD084C8D099A75D89DEA64D5A7CC68BD5B0593D97953DADA976383
+F5015915618AEC56D71D1DCD55B89736395C609B315A3F1E1255432FDBD37F38CC43C354FB4B7C44
+F1A7318B0B7E99C3C08C33B953727B6A6328051783A0A33E3CD9E498346A3CA6A77B517096EDD52A
+E443B87643A646C3A7BB97F742888D33F9B3127E61942F4103C1DBDCD8EAC8F9E259773066736CA6
+53CE57E8822651261D847C131321BB9D6626A1AC50D047C0BA47B411DF2A995545BD68EC0287CC9B
+31D5DDCA8755EBEB10ACCB3903AB0FD5788E984220443B8459E7C078DA4289F1350905881AD6DFDE
+C47302B0ACB0D4AF8CAED02B4B70DF3CF8FEC118F0FC2D3DDE3E494CD160E676E300BC464BD4400D
+B50EE43B314E0517037BF971ACD7CD327CB2134893B8A0410E68DDC518F5DEC966C7884CF5FDFE74
+723177F20DEDC039D879056CAAB4BF045062D3904F615C5CFE109AC7A35599C94024B41019B9AFD4
+04A80ACAA4837929F5C9317680A13D157A03B59A5588DF79D2E113F5F51021D6F6F90E8BBBA2C252
+FD10651BE80BAFD59C53A3367BA3C28DB6EB9DABF1EA99F47B503F627E15DCF3FD645FC52C5D5D0F
+2F07DB4C25C0D1E1C00146E1C4D973E613CCDBD3F9450CC0F5343D79F05E9492E86A1BB889ADF405
+03BD7F3E7543436859184A5B20BD8A172F350D846B7570803990ADAA48D4B9155A2B4C4BFBEF1E1A
+065C08E03928559735BDD442FF1E83E1FA20A5DA57D8BDB2FF5427C034CF0128AF111E6E73099E04
+6E0C240E80A73D7BE72B87834E45898D475521CA3306707631F5C6136199F354632D1A085F12A1C7
+C473868B62E534D15F5484323E63D0574196A19EF175214EB35A90873EFCFB92D6CF68761D45E37E
+AA61E1A1979A82009507CA193E44B36A806486665CEDBCF387053ACEAB979BD35D30978FC7659ABB
+E844F4ECAB3303318ECE80777A5FA5A9DD91B3D06804C4B4E9B4EFCF07EB89866D0DD8CA390CFD15
+98651417114D78776B1A1D36B4BA17746D6BE7FC123D473EF1EFED1C3BC1D555F914536869FD5B0C
+35F9C83F65B0E6BF7A627B9202D787D72C600DDB6BCCE613D88492E13CA0AAAB196E8A49928C62CE
+A4FFE2D0208EDA334ACF47F20BD793124D2C5546C03F4A364369A76A0425262F9D9118AF54E37D32
+E33AB25DD533A49DF5FBF1BAF4CEAC2D9D378CDCD13B00FDA432D9042F623DA41AFB80699B5538A2
+5403B0B3EABEC9E8EFCF42FEF3EA9F91766902CD206B0787C187D5370B60AD6DCD002DE2DE8DCDC0
+B4719A797C5E26BAA67665016DA0D967FA1346F9588AEDA174CA001B31213617FE19EA218EC23597
+79D979E2663166489C06993230B0D07973A117C4E3F4A4C93CF8428248DD5389414D679C69644142
+67C7FEA17E35B0CEE456667A9B1875C81B2302BDDEA2818D6019FC1622A82051F60584ABC904CD91
+8676305DC03FFBCC64FDDAC8D8AA9CE2EA00D6C97BC63C8A617DEDFC0E40775649438E9F61AFD179
+5E3B20560B01BE5E0983F136CF48AB206954E41DEE0D9DDD953DFD01CAEB569151D6BC0DFEF29D70
+FAE3E198E7EDD8922C0E0BCB8BCCF1C016142C1A8B337AFA7A05A9D7534B184BF3BF827F371E9BD1
+9A71244ECA1BA73D484CD2FAD54DB2F0EEFBD54B536EBCB5094E6BC2F5B2AAE41F05B4B311115876
+ED42C34F8E643B53372E3F6350DB8A38445822EA9A33E27FB0CC42CEDCD1FE2FDF723FC47C996EE3
+56C402112F24D0AF899B2D00BEA1CFD427998BD22B2A09046D6737814448ACFB10D387547D7009FB
+384AF0562C85694C071584236D0F1F3D3FCD0CFB38B77C81889061E668BA7AB37AA60F58A3967DE2
+6F939B79CBF10A9DCC42852561D8D6754F1B660D216AAB1E133FBAA321C56E2584BE5C9BAE20CCF0
+0E8DBE6D9C2FCEBEBAD945C3C04101D2387351F132628786F6D9D4CAB83419288D31F9BC600D9664
+12E6AA457CE6CAD26A4C0671097B98C2384C81DD8B9A3222D4F4BBDA7017895C3EDC26662779AEE7
+40D9D7E24185FB821970B0A3A94041A69E4805EC88EE1EE521981536F2844FB8F5EF645F67D42CE5
+148E2DDE43AD5AEF200EDB3A2C7866C98458A92666E5F9E070178BCC39F65A893102A10564AF4E8C
+AAA5075D2F8CD7FAB0401C03AF299EA3515CC93066744EB5AF7CF0ED06675BF049A6E3C211A89E16
+DE5BF0445A7CCA6EE8EB0347454950485D884606651E5887FE8B24323E2AA16DE22FC1FC8C4F06A8
+2A1FDE5758976024068197E1F4506E4D3D8A16D40461A4586338B374A592DC60334402F76388AD6A
+457DC3F54E6169CF7AE3959676E966A45609621055EC3AF80E182633300A4418E34A66DDFA6B569E
+5A13C9115B5FD3EC1CEBE50FBA247F60803AA83976F00117536342DC3D9890C49B2AC701D370E43A
+955118967827760F7091469C5406F08F18D7E3548148CF0E312B1DC71DF67A5E7A1656CF2F47F3AF
+F3DD50FFC2FCDAB7177285B29C17CA43019F62AC6FBA52D1493ED7C427526470ACC8389BAE827759
+4958908F517B2863B83292EB5AB3F57FFFB08393CA610FB1FE905D88A0A16AC395E2A2A6DD033D6A
+0D68992F830B2E1B95FE357BF672716E88FFB92FFC3D62945D1EAD22BC68C51EE0E10A43011DB94C
+44685A5C4576F6EF44CBFB45F2A4BF110A01657DB51FD499767E78058199B31DFD60813F1A344F86
+289F9378231D5B151C92385E3650B4FEB1DC91018EAB8474CBF69FDC1496A4D078D2C351C8196451
+247A9DCF8117E5B637371D8E22E248C64D999015C3FD2311E9950B8EE0922FBDD3D7BFF766BFE9E7
+CE0BE12F318FF2A7B5A9C6D00A54401609304ED2C55F5C1EAC3D4B38355BBD85D66D61636FA6E30C
+2E82829376BEC979A6FEEE040E452359768ECF90CC539A546F17AE906C76F14F86FF697797322B05
+1EB311A759FE260C1EEE5DACF383816AAF1294CFFA7BF87A4D9BC595EE8F2C2F86FEEE11AD959D86
+F22FDAF4CEC098942A57E57813A0FA99239E994FFF353C1E781D666B8928CFC648FCF0869FC68468
+BDBDA7D280DFAB8B0B3A4CA35B074B686DE8D372C61FB32305169A1A9912F6541DA16CD6316A6EA4
+51524757BE5CF6E820011BE3859FB8B8578C100FF029680E05F0E0BF11D33FE19460C85EA5E4C0EF
+28E29407C8AE6BE01CFA0D5022BF9FB01416FFF722A784DFC8FCE330EC95737A854471D334FDC58F
+AB42867A7B62836A8B56466E9A6C1247D46EBAFFB905CD4321970F59FB8D6FF65FDDD34BF913AD32
+2E68455C5FF2D23C1A5EAE687F259BC982B6A384D35440F7C693CF50B9ECAC0B5578CAEE87588B56
+2EB6B7F42034C9F2E545EC866316552354EB3728C7D26527ED75174EAF635E048B08DC5D23E88981
+070AD5641A652F2344956E9CF4C16E652A99F4A644D1787D6D36537489DA4D74E61B2FC4DFDF1D1D
+9D58F9C26C5EB63200526AFD168AC57D5611ADE4D4A382FC28BB60F9E7D626A6C67AFBCCD1183C5E
+3CF2EF210D0BF5CFA7BB10FA3887BDD4CD96EEEAA8F9219AA2F10ABC0A960C3B57C0EC0313AE10CC
+FF1F522124CFC8D2D49BFBB0C193EAFFC5B48FB3FF30B21CB76F0A4C0F1377C9223145BB0468A5D7
+1B9BC25873EA12E1C60334571C67385C00D0B570D3FFC6C7FF0DE62C183C76AEEB12DFFEE1459E0F
+C818C621B8D12FA1357E2B55D48935D70BF140B4CFFE8813DEFD479350B20DC2EB1D3CBB1A2D3DC6
+EE975D58C89D61FC50E6A0197DA9A586B72255023DE47DABEFB11E8AA02414C2FF6258A281219B9D
+DDFE41BA7D7977D0D6F18224FE22F7D4E9355FDB35BF7ED3418F4F68D093AC48F7D8FE4194FEB6C8
+0B9DC1F74E023C604DEA27089F98C3973FF9F4AD7BF7BAE601DB89B08D5D8139B95EDCF6C885FFA8
+B3E4B0477E7040225733826BACFD1EC4A0DD72DC41734856AB9FB700DF83CA2CE812913BD142D84C
+5C83C0B2583768198AF9E885F2BA74877A414233207234AA5F18840557CA11682AABDE8993533887
+7C6D404BDE4153C9827EB16D66C1D73A8143C8A2D3604FF72CE579FAA3C5224BAC48EA83BA848429
+9472007DE96466B5B29ACC7C03B05DCAA38A48BFF9F214DE43146AE4E04FA705421917F99BC54533
+F0EBC01849E396216B9F0794E6F6C6B61B52EF1B1950C0FB609895C3C55FF574163FC8B6B09E66AB
+AED1810E698FF37CC1F926B2CDA3B48C7D77790EBD2D514B6F385D397F713EC3AD3954EA9C846158
+6031D369E8B99E53408A79D64C34EB5A56DE8A67DE91837960E98A66FC04DFA0EBDE21DB003234BB
+78665B039D0A469A0221BD541AF7149A2A659C300132C14581EF766FFFBECBA8B58A5EB3F95446DE
+F49AF863A8113D17B2E7E6ECDEAFC3834D4DF900E3475596E86FBB4E2974C090DB4AD61A737D611D
+92B4535AC291C56AD8B1C031D2F9B505BB77517B737D70AB3723DB52AE2ACCD5DD2F617423ED3CC3
+9CA882EF41757BF7151806A9B8B0F312808863E3673FB54DE939B35CDECA7FBC4DC3BDF5A5F47D35
+E345916C39366C8B4F439CE1C6F1835C320BD1E67375B03B5DE18C93256F251761A4C8CEC01019C0
+68E34447BCC503B9571FE8000627A6B3DAD5854CBC0A2D69E5A8F46BC78F6A7B1422334EC7A98ABE
+FE9B83E01DCF3C6C9273B346F3240EA225AE4A4083CC7B0EA141A0773FDE940768358EB4B13D82AA
+304A1386D450C1C0C6A7D5A8FD2BD313F78F85248B5196241E31E5595F3BC01F37700A2DD3D4A0EE
+2DD01A36569CD507130E8F5B1E96CB560BB7DA15560CCADF3B2C9804A11D9E8055C9EC70E48C1D21
+3EB756A1376F2EDCB7189D78CD3D6CA5865537EEC31C17D801605EFD860B0B629472690588D02575
+02C6F7A75B9A1C1B397781329832CF3EC43C09F1559CD562C48FA9500295CD3B0A790DD3FCD4684A
+7C7AC49AC9BFFF36B39A9FB148BC28D37907433943CBBF0CBDAB46D3EA86DC8F81C859C52D15302B
+94A9B51C199B7104DEEC9D769C2634CECF8B700CE9C04152CC59C9326BDACBEC4312DEED92DD087A
+1C4840868D9F97CAC046581F762F75E8D24D6445370A3F1E0AE74A6478D9DAC37E7FA5BEBEC0A1E0
+81AF89C1BBF7F51E3E2E22C8C405E8671BA85F1BF0DF79A465DAC7EC07F731E00632E017D190A99D
+83E27E5C2E63D7DABBA23B2E88334C63721AC5A4CBC5D45F4C177259F34C2EADE01FA008AF65EBC6
+01D8DD16436D86AA94C99F3CC0A2F87134E73BF22F108B825A8963B49C6C685474AFE4A542C8641D
+C0375D7EFE9AC1168D9700459BE52D0DA399023E141969F25C0DAC4668534B6647EC85454BE945E8
+26B26DE6E3C4584B97A38E2B40A0D23481BCA78084FE80E00A71A790BF31DF468A435ECC88E60A57
+860BBCA3D65930186E9917CBD209C230E8F8255A7ABC7D3F043AE4D7AD63D9980BEDF062B7D5C298
+C40225B6D03F29A0339E0FCA02138E526F06B9EF47F5E7A8068A846CFDE2BFDEBD24F5A73A66C079
+18662AEC80B43246284FA4E2EE0D9AAB172B1E59A6CC46B801149D8C0DF6DEC9A55D8E1B0EFD9D30
+2FF618075944CCCB6831D336B11617107B0530D09885E5CA11A5F1FCC8D69D603DA16BEA51116D42
+CAB1AA1E4D7B9B4D79993F2BFE53EAC904FEB70B2D330A89780EAC10D12CC0C35B8399F218AC2976
+E57A26BAD20CE2FA2AE2363D3FD2A8A971747556F2959DA74A8963C20B504711AE1CB0D0C02457FF
+2E9BF696B159AF031DD5155F21C0F5549B0471A3C5DC8918B675CEBCB23E29322B959ABC05283A70
+2E878DE8EF25EA760F3C5C7B7B49D398283DE2ED837FD59F7C22D62C58FE4448B1049FDEBFC8787E
+67D7DAFE9774979BB3802254DA59BCC0219F98C219F84D995CA768B8B5D9D4A32525DFECE003675E
+E4BD5D8DFFC11025AF2B468F9207B5B2B42349B98232BAC0759758C1F4A283405815BD7145C93FA0
+8F3ED2826655053A3C2559073D8ACD199DEA2C5BA5F616A2E48548B4370EC73493BA07E197165DCA
+774438B0766867819C1154D1959FE6E01E6312E0AB91FC2E2BD240FC8652A2D456A1DE7F34EF372A
+53794D4C4E050BF3CA5B7BD2F1B8DE93B4C8002485CB219AD2D029739FD3C81CC6E78EDF38723576
+1A57143EEDE5CC887F282FECD261F6A25D0A7E154ECDF5DC38E426811BE86AAA458577E5E0C5F0F7
+5AAFA9C41E5D1DC9D91ECD79B514F8CDF7A5F1A189470D35FDF4F9B8788879CCBD91B427822ED658
+389E981E0EE5F7FB87692A3E3E931DF8A1D1573E3B0166204240B7080089A09EF7487C9AEE2D665F
+5A82F94C877FB5B0DC531CEBF1E71C6592CEA2401E4B5122E5091DF03D203DF979B9A6EFBA12E2F6
+B422FDF15D49AC0914D372D21E871DE65CBECD105FD4A3E4714B9CCA5C6803FA39DBB015EA8A88BE
+7913502E562E5B170B87BFC8572DC9DF49AD63694311EF1334444BDF0B4CA3245271C1F7A4D7FAF1
+703E3AA0E1EA8D5C6E821B28707EE0C9B4F22F23796FE87356C58AE2CADC191F4C58E1FB58DA03B4
+5A25AC95DBAE13A293474217BDB214742B9D9D6AF35F70FED2891942EACE3E625E55FFB820543FBB
+250A062D3D395BC0F219ECFE0D76686AC148BC41476A887BC494DDBD396BE200FD3E03CFA12EC9AF
+6B934A283C42AA05589AA6B4A8D16946BB51F50419CABECEAEC5AEF9085C9989289E9B46BAFB6FB2
+782D84DE2B068F91A9744AAB237CEB1BA513E57E4C307108E993C972A3E0A898D5A8D27833155031
+FDB98863C3BE7FEF3004CBAA5CB60A1F2E3EB4D7290FF5FAFA088B1CECCB6CF51A58DAAD998F0839
+6CDFD68F5ABC9C1CCB8F6514107773C69C26873E889D1F79D10E866910E4684186FCD71C965ADF62
+39BA3418B313A27AD632300969B6F284519366ED85E7CD968D64823F8C59B5911A72D0A20EB72B60
+3A61E36F52F256FFCDF706B4560B4DFA5D918FBC530D83A4B3C01BDD3CB4572E24242D141BF9E775
+36693A0407D002E09CDA5B195BF1CCF430AE9824C07928A050D0B460F2704BE8F9E647A4884C4567
+0A81EACF7CC038643EB0FF18A376FF6F32B6FE4F197273327FBBDEC6443A299CAD4B26F7778A99F6
+5A11BDE047153E764039EDB251936AA43DEE50DDFDF8856519056AAFC4C5AE6F2051AF0579A9ACD4
+1D00775D7DBE70022CC263DCA5E0A25B9C7C4F5C418587666B2FE24816B1E0EC92F9074F1403BB83
+AFC3F1D52CA79C387BDEF864366E34C90BE52F7AA09935373A07E4E026224E76F9EC3CB9E7EDE50D
+EFDA48248D61F3CEC880A3B8843306375D9711E58645F3625BDB8E87052DA67F9794EF4AF8DB0BCF
+E00677C3A26907DC651BC838C40EC39E2B5A5DC0DBD345944A6C32226089D63C52490FA10B215AE7
+03CFB663EB8A47793B84CE7364DA1C4E7FCE32DFEF09490121222774915BA59C78C2275F829D15CF
+4D8686B095C38C731B83D48738C25F40B8ADD487C350A2EBE846C3916AE384CB1050F9F5DFE09FCB
+D9129C6270FD86D55A459618FDFA4F907E6B4746196BB717865AB378414029017551161A52E9D24B
+E4F7EED553A927933D4ABC8F25DF607779A717909CB4D810DE8F5762581900E224E4B91598149BA4
+71CF8068ABE8744356B261600BFCC57FB8BE45036CF6571D9B2A95304933BD4F17215F8EF53F8E08
+1AF61FA7F9583C34EB5655CB0ECB82246959F09091F36989EBDD646BEDCA614B9A61AB7696B3FF18
+1058A150FA6EC1BE2EBC7F64357A3FF2A2B0491D2F4E0B970DE5B7788B467CA678039B5EF55C88A3
+84578D427FD2CB16C87B0BF0A3D37CE8ED43E0F049AF2436344D5F47C948C632C94A287509282561
+6C64C5D262FE5B24916FFEE982A69A6CCF888BD01D62EA591EEC51F4B7DDFAFFBEEA93FE08D736C2
+0129E345D06B10246A5F57151C198D407730713F32299638EFBDC01367E23EB59AAD42A83AB41B43
+2DB462652E29813740F4680A5D4BD47B18328FAE6BDF4200CFA4CE3773809B45E8887C9B2E423698
+9F6C48D64F5986F563D9A7538A8716082F81936AEBD0461E6F4BD470436D8B7656F0FDF89108E6DD
+02ABDEF907731D458D690BC608EA9CED09EB1E6E64C0790C7A2378201CE997FFE0317679EE1D4EE9
+F91157449323E53B4ADA8096CD628B5861BF794543A98F2FA2AB54FF0F25A13DAD43DAF9394329B9
+5AA53CA32749FECB0B2BC035DD1EBD53FF9FB5AD8BCE06CD89E5568091C1CC314CFB1D9821D7F9AC
+7C55F55E0A16E39A87D43148201B928F3C42B110FC056189DEF183745F3B637441DE8BD4C3C7EF12
+F4258E306B2877ADAEC63441010750DB4E6269A4C78A0AC01BB3603C386651FE814031CB5D8C1F14
+9EEAFF652A53E57BBD4C8C0CE36A84A319A53BC1E5FD3F1ED1EE72F4C1A9BF264B594062FCAFB22C
+C1FDE3F2E3D3C17DD3F7FE0E15EBD812D550227C06D01127385374A11438ABD50048E17255FCD2BB
+85122A6FB9B7DA9D5E9DE8A747FAE0DA45A1FCEFE92B9E70A5B2CAC668D4D07527A5C1403267D823
+048BE671F725CFC7474B44FC5AAA348420B2D7C23C6CA066666FD6F2208E329878D90CEF1C2E77ED
+22D3BEBB9D547810B189F08920A27E7107F208591A84D463CE2576C70C3DFE6643E4EA93F4E1DAEB
+41D46F0E2F56FC10C69AD5034FC9859D31CF27A3A1EE256C93111F81C11ACF1FC0CE20B90BAC9AA3
+27A5C85A7985B951519FD4B03C40BE637162AF41B2FDA68F0D1E9B7602FE2659D3D75955C579AC51
+DF6A552EB9581AC3F712F083F19B52A6C4F560F36C59CEEB0C996AAF1728A2AA45DCAD79BD7B23AB
+388D5B0B64A2B95154B6259B730B0F4A72C8C7F7CC93C7D64D9D8810D1F63FF8ABD4DB89824E2D26
+4FDEE916C41E299211DB1A53256E1DB5CDD04862F034D9404B73183A99D3D13D642A663F129B6D16
+7095BEB4EAEFD03DF2FF2F0B6B594C1EE90FDB203DA89FACEE23F1BA3901FECC75FE1811BD701259
+343011262B6A0A9707AAA6316BC3C17F787BB80AC8DA5AAC942D90F80C5A3BB59E47EC767244AA95
+C63E50BF809998957936D3BF6ABC24B0A397258F9EB4DC8F65692CB023D9091FB180C69498CD0C08
+BBEBADC84A7E0016E8F8BEA325D924EB0DF82E75D2CC2CCBF039B11934363D4332C5FBC5EC556BE8
+5EE4E707CC2753CCC43D2ED50558E51A104221C9323CDCB0199B7B83454DE3FDC810D0F362C0299F
+5DD981B31D8E3DDA284FEF9DC8F9C8DE138D3065437A7FE8C30572AD06D62E8527AD37AE39AAB0B2
+25F76A25F6C6505241ED73BA494CF923E919F688DDEBF193E188F8C4C154F21631080763B4D091E8
+AD1D2FD6649E0CD9360E8D1A67A5B5FAFC67547CA31C95A5EA8D4EB5D68B9F6D6532DB9B54584735
+9558542A2AE58C09F3BD2918EFBE1699E9C8F2C2A11EA4D224C726D2ACD4A8D8ABAEDC6588CF2AE5
+66528B94F55B823A2A1F7BE19000F3E7579D094E047075DF18C8C868760295533B26EB3ED90635B1
+29C17ACA679C3E88B06998CE5A7A2544B700229F5A6A504BD3E45B276471959C8A3F81917A534287
+39B5EF9E3D463B3BA7318448E2A3E79520D2D245A2A72F31FF7070B6E4624E3A5E216BD103640C8D
+F387E49D732529C611F8B971073F17EBD2F6EB18F9B74A67E1997926DF178D4C9EDED435B9682F1A
+279C81BB9F60DAFE125845A2FF3B02979E5481C78A45C479BEFB9FEF3CE2BA9BC46C77B50B03E48D
+A6D17B76F06F3AD118371ADC69E178C52B5FB4B261C9311874ED07DD6D5B3226A005FDD7A6D53848
+09E7063F036CDEA41619122635E835D2D74CBB6AA9B38CAA4D819C26E95115FE0DBAB4198FC5838F
+2C91B7A87B07D734C6D4F4F83444C1E90AA9BFC908A2BAC4B3DEF9157AFCA5248F2DA31CA87BD363
+AC25E9E77F741D4B2C6E02F04987A6F49D30E9038CEFC41BA172DD675AED8B392164411144E5B738
+F3210B0E66B17A13CB9631C33D44484E792A7C082DD0A5382F34C5637653261B1EB6D2035B08B4D9
+1FA9AB770CAF40A103629511F7B43F2743D7E583433DECFB19C21FD4FD0AFCC22A4119E77C87BFE6
+FE50068B22479015BE5A9F06BEAB4D37412E062A45E0CBCD7BB39FEE747E96306F79FC4F2E8942DF
+5D9DA0E55AACCDA547DA19D30B8404FA121298B44C9CCE198C708C69A8D6BF17591C5C50D3FC5BE6
+961F7ABA8F366DAE957A1C3730DA4A5B4F035A9274675EE3BBF0CA8CE9D8349F50CABB1C3EA4948A
+BE6F9F143592F1EA95404E6909A909168E3279A957AE1924245C356331A75E7008BEE92BEAA304BA
+40B7C3F48F74D9018B3247DF50EBD7CE541DA48ECCB1B0BE51A455C3C13C279D4D8676078C3EBE43
+08748D52C9B041D3E7244C745B1F2F742D010A9E60695F3EC4FDC1050AC082B905D6A57E8F407A3B
+472F731011A5798965B7B1A307E252FE02C8F79CEEDDEB6E165F1A94D7FFF18DDBDF79477F14E9E9
+3981ABD200FE7771B29D1D2D120EE79D28B9543818527039AC74085EAFF241B56D08220C958B5D9C
+87C0C04A14D52AFD475B542D391BC54FF33DEF8D9484AFF6873BEED32DDA4B371112B523B6CE22B4
+0D1B416B64C9370F1CDF2C548F4CCBE9E12E21C36CC3EA52DA232DCFB65F66B22B5E2EC04852510D
+5E264EE939BB67AEC4764B87062AEB7F680B40BCEE04AD45C7519EB3B6199C9E0E332661463647F2
+FB7EDF303EFEF84891CEBCF0FAC5F723A9D0476C3F8C092604C87FC69C7A90F4D64AE45A478EE8BA
+2DF50FB93F55A3546123F0B0E2C1C40C98EAAE9F0F26B8F80FFE6E6B94B7E27D2884D58B8A119662
+2DF6BE608C5569D7864BB756DF2EDD184B90812B44ED4A32D001C31383A40AEEE9743651F7950846
+15C48E402DBC01C818D477EAC0347795CB2792E9C11E8FD4A02E194EED1C919D4598FEC003B6D9A8
+A0BC7D456047A1C0579453FC1D7CB2D158D466939A23D7A7B8ABED7E2777EC7487973E73F2266D9C
+250CE30729E3C5223AD93B9AE8443B35711E446A3DC660123ED45CE1942A1A2AD0610467E081CE2C
+8B92A6C82F0B17B5D2429E99F1A6268072C6B5AAAA6EB6283A872C54D3694CD825EB2926E57DBBC7
+C1663075E687A144E4D61C225781D80FCAE1497B442342B4A3F1CD6BDB50E31791CC3928C30835FE
+F845B6BE5E2D7E3F2F5F085AA3FAEB45CAD0D76BCBB1ED859A9CEBB9F7457036F0BC3F195CB1A98C
+9C8648F6583CDBB23894BC719D68C2DBD8003B10D08C8CAA40BCE784D7BFB4EEC9EA5359AC056E57
+B8B0F2EBCB1F4CE40C87FC7861180133E0CB6CE2FC4FE690756D327A2B5AE063E3021C0C0BD420D0
+56F0B941E6B36088A55BA11D0C35FD0132D5F48E5D9673572347171B4328D4807B972831C0D74CFF
+A5638C145B89C989E6EC942148207D6DB82257585958034D9F9D4221C7C9F7013790DBD130F277E0
+BC88BB179DD09E27062379ED06F25EEA8B7FB33C35861A0034776E3813D2E9E5C10E227CC569AB36
+CB2D9DF2E7B7B44758F9DC4FFAD7A24AC7E9F47AA850C221048C3CB35A37CE8EA75632AE65FE3212
+175146FECD6334AE3D3C5F492F067F795E1E8FF386BA198CB74F0BB4DC0000DA383BC4CC3F070DE1
+7721431988D69C8B1A5AFDCCC83C22E16A87E01C6D3E79DC7AFA3DB0371B0866EFB8B6F88900472A
+FEF1C4A878243C52D4E02E82658979731C841C489A6B97E271C4C93800EC7D91F93EB9B9C659A554
+E1FCE42A5EC65AC39190EF4B66DEAF6FC0569A000A9E1495F42F706FBEA4D32EB7EF11A648910259
+6A65CF899C2F322F5679C6D123469192A9BF1A7F1F2C81C554ADB97BD19ADB746A4F81A4D5559E60
+AB94C483DBABF6CE2F28CDB412D50FF3FCFA3B3DAAACC6A83CFED910CCB3B8D2C19590AFF4D75303
+4A6CE7F4156896A13808E0DFEAC547E69D3C886691728E4A35ACD575B40D721E8FCC5385A2EB28D7
+08101DC50811529528F5CB0C009BA7E3C88468E37768FB0D83895AB54DB2DD5426562AF9D8AF304B
+F6EDA54E9C92643DF926F5C3578269750120302A37CB140A18BA56BA01108D4ACACE8FEAE640A6C6
+958EF156B588ADB0EA5F3B0F37BBA12B7BCB221C811415387B024B7076FA4403A3AD6EBB5D9C26EF
+EBDB7ADE7C60B444AB9F90EA493B658B7767AE2BE649BDBB3FE85F460F1ED137C61BD95F7CD3D8B0
+15CE45138538930AB62AA0E54B4CE1A5EC5FEC0A2B28B345B67089A4E4AE14D2E1F5A9C8848DA688
+CA298F93860649EC3AAFEF3E820D86988C8E3E5A4D4BB937791827994AA3E81D0BB3EE115EC36D5F
+B9A392D09E79AF514D11C7B3A03C9F9C13355CE79E119A19177FFDCA34704D38118A8976D1EE5AA0
+2D14FEB1414419F5E85244ADC5C0A765A522EEF36170064BB19FEE3B5F7B441E4DB967DAE0BAC2C4
+8FC6A836E0EF5A69F073BEE1699F55E9C757EBD6FD8B514E2B49D6333815B7DBD1E0694695FCA3D2
+1320A0C4B852D9706DADD8369A95FDD917328BE93DD33818954DBD2C212D2CA81560ED5BC284EB04
+7A5F389E24E43F4FA8C97FECF46589FA7341076555CF55B1C21B28E0C1CBB00AB8B6F67472F27BC0
+D11148F407824B0159B5188D4BB7386FBDBF1C0FAF34721B7BCB5C0FCB7C4010DCB6A1284E9D7883
+9E3C2111A05D29AB7997073B590A81C6168020F1D48951BC7D8476D5BA593F4F23CAC1F9BB0E091E
+84B4E99E5C584D1370DD12DEE8DF16AF8BC6B7B23E2FEABDB7F32779AF8E2B5094A6E9B7A7225F24
+C43A8E5D2B977E1E19E633C26771E23017ED233DBB02C64F8CF03992C6484528D0C8464B46F24F9E
+8380F385D5D01B8893C67FC103498983CF939432AA380CA576D09030CD52FD99BDC3BE16C7204CDC
+3365BF76294A83A1FC14A236F5FE5321904E779B13232A76F8FE521F425562678436359C2461BEA5
+AB27209541F557AE2AA60009C9CA0A9FC7898C14306CE35A50017BADEFDECBBF94EE2905220706DC
+806409EF87DB1D73EAB0698AD2DB72CDCDB293E7FB13C94D9FC87E74502E6927A212F0D7D2F2D194
+64F7A66AC07872E18CB1DDE8F11835DCBC5C4EF039333FFFC0FC1456DAADE7DAE3EC2EE0D3415B0C
+ABB69FC5006F4D14A4EE1A5CA99AD4D5E629C0DD1E0F097B5B93DE2DD001A8C418234C9C45E8C13D
+1AE04E9466DAB8CF1ECB88A4E059C111A6468D2DABB90DA79C7C79E94DB28F6968B1A632F8C57D9E
+565FF91C6916026FFAC0661856B9FB8DE9C81661816221B1FC159CFEF1751E7E403F5F2CE32529DD
+540792FC17A12A3DCD7C50D38EEAADBD10ADBF5D8A82442AA900CE6150EB7A4639DD9FB6E385B2FD
+093493DCCD9014B23EB172E21AA89643A6CAD1093343D85D81261972DE0ACB16A4C6B5F0BE4C978B
+FA12D3CAF0134F9EA49F6E9687C8F99A456745EA252F0BA9968C7F9586E3DD841AA92DC7705BDD68
+2DAE41518A09DF0E209F321D7FA3417202F4BA76A984DA3ADDBC58136885362F02F0A24EBC439B3D
+BBDACFFD8498EBD29F88F016B1FEABC10785438EAC860B554525F3266097A675299AA0967BD3B7A0
+EEEE3FC578D1BE99D3533BD91571AED904BFC9DA1A1451FDC5406E1CD614E0C7FBC733563CD6CE6C
+C31E9237CA153F1F0411114361D731636BCF98555ABF12848AD109371A42B63675A4130B81E97C2A
+2EE2BB5D8FAE2640156001AF0F55D9D5DF8FF23C8AEFE14F120000F14149A36E5C94CD9081DEC277
+C2C34870D05011F99D48B0875A5FF542F067F7E9880109F586BCF2B50522A1F23ECE44349E539E70
+F84E207DC9BEC7CDF856A046F1A03226AA41F541719AD1AF88FF211E57DD0C1275DD0B7B47440DA0
+89B98C6EE92A7D94700B83CEBE19EAEDD8A615F6587587BA8BBA3CE3AA5E8EAFB1FB0F486BE3609B
+169EFB178A4292F4C0378AFE5D24EED1CAAB514DDC66C696D8E37F294A6579131DDF5488E9436609
+ACD750C3DB0A940C84FE022B22ADC2676F62E91E8F891225F891FBA537679B24547BBBF35F04915D
+20B11739F620D18B5B216921D222F15044368569AA302980B9225BB839F494588481B94B0C724352
+B2DF600A22B062561D86CB8F81514FBDAA4F8A043A0265F992FAB71FC9124A45B8475E1EF3DF6B6D
+E35CF329777D45F08325E8505EC0D979F542807AE77E57E453525F23BC59A50740371EFA98678AEE
+6C425374AEB745B99DDB5D8D908FDB551FBC0DB15832107BBECC4E11A1A8DEC69358A574A2ED46CC
+31D564549EFF23102D92BFDCBB2BB985F78F36033E34F59C0EBAFA3BDD71338736464CEFDBA91398
+33995EDA4207BFD4A9867D32E867FBEB7DE60D132803EF9347CB17BD91315484EF6570892297DD8B
+7D966103339535E28A00CB1EECA4A9775F60A9F5FC9BD8B06D78FE8E6318C31DA2E847E3F9CA587C
+B01AE2BA0A2EBDE308314413F4F230A758184ED60D4F71F6CEC22A93A01B6C54E0449A3860FCA895
+4A347B7588329A80974ECBECDA1070FBC055666375229F13DD995E99265DF870BC8B8CC6347FADBC
+1A6AF64599271A475B9123493D46BEC41289BEEB67EB97A8DED7A9C9730D37C65164CFBDC22E5CA5
+89D2E7954C7136EF4E084C43A6C7F361A3E96989239BDDB9A593CC2A80BA16DE9EE90E95CD39393C
+212AB22EECB677FD36D34DEB46C4AD0D21BF7E6D7CBD0C8083842FCD87B18FEA7CECF939987E99BA
+34C214E44DD84C176C9CC5A4CEA76D380CB316BB4EF9DE73D73B4AFD4ADB54451591DEF86621D138
+D5A0A29441502BF6C2ADE671CEC3CB5CAB903A657EB2D70C943F976C110E46C5D9D29BC00A875F27
+38E5D22496A43E096E009C5D3CB724B4CABB32838DBE527F83B18CB457E57B092C302EE557FD4F00
+DB9C56E66C9FDF4EC9FFAAB85F60D02BA79694FABA476A199A0331C30A78A92E10417BA236E23364
+8174C826331DC1BAB87C5F95027846130C6A2B4027930EBF9A97BA1B039D386FC51C302648E25980
+212F6A582CDE2778C677A01FBFB3C5D1B8A374ADAF6ADBF7DC94075F25ED66D440B3922C5F255FB2
+3FD8F6E21EA65B1D93BB225684B50F11310E242B087575973345B229BA62C1E2C35BDAEC04D10148
+F5B2F3BCF7399BDFDF1F3F79119714AEA697245BC647316EA157484ECB951BE367234FD02E8B1F09
+1AAC3D29BF282DFF4011BC0CBA8E55234D943DB3017CC7A766720BBC29B2D097A956C0F1067177F0
+12D42ADCB473CDE8D1BA35B4030757FA1D8211989DF3BD22CE5D501C21EF8708FB3449DF47D88650
+9FF7B59B76C0DBAE443F336FEE2D615D7EED1C284F14335BC8A26BF4621E10DE9611FB2F1DBD52E4
+B7565D8C65B54EA36D508BCF0C578A49A2665227CDE1F9768EFE847F9D94F1BBB7DB83701C232198
+5C7283D47B2E40B27A268428AAEFE75F6B2F8764A8494E5827573758CB9CA46FA93208836BCCC8B5
+564A69F5AD882052AF1C1417C3FA7F580569528682C77080F3688B65E7FC24D2A3AEB61574B4A321
+5927281544DDD7A6EE0A3E9388F8F631CE7251724DF70726E5912DDCCC8C652DD6C9608F8462303D
+867F589DE0F2F71711B35142EE6EF93B64D6326C4DD7DC83278E057100EE772082E6BA368ED91A55
+53ECFE2293A481E42F83BC8F9148C70EACE91F7B7D9CB8A72415BDB3AF66F68EA733A17ABE9DB005
+3BF148629132969589F38D30EABFA96A01FAC72650B5A6FF3935670198A1EA33810A9B11E330EB8B
+451F24F93544263436F669AB5A90A53B16CCEEAC36B1445574EFA7E802DE73522BE725E68704822C
+B7D3912717333367895BBFBE06966A5CC653AAB5E9B3596702086BF0010085B900711932A95ACF15
+CA4DC45A754EA334E9EB84D6FC8E3FC4F897456BED64BB93B593549FF0D5352275D8E417172A6664
+C5E0ECED1019494A7ED49AB0B965BEC1A82E5873766BB38D7D856049CCE2FCA65AAF61E961B60634
+E2A69EF059754C9D8163D87F928C222772D070D83FEC6FA5AC734AF65E40BFDE521F7D9CB1650FDF
+64754BFF21EA3FF0AF7611A93D525EC9B28C51AFECB04E7FC8323DD6C9B0D8539A34FC3CD8CEB795
+8E8EBBFED4313C77ED469C199552A9FF70BA5423B03B6148D4EAAE17B71C5B39DC436AC53D6BA8A7
+AD81AA8B02335A8B2B11E9F4FA913159A725B8AB60F52F1A2EA50EAF4D56656E615BF382CC68A690
+BF83DFF24FE986570ADC0290ED1A37C1C2AD469CE789E0EA0BB5CE01020100E729721AF3B5BADD33
+A2DAA6C33EB8F9064F5292F715F820B4BBFDD56F76D42E7A1A068C1CBDCE4640082F6E7D582D1939
+990CE6EE8D270015A2C461798B37DCB5798EE9F7512168B76D26C28BE4A49A1BF96C89D235F21A1D
+B6A96E5DA474D0B19B808D13D7A11BF39EA8647499C410ED9894A1ADF33D41B6FC2E614D8087F4C8
+4E437B136F3CB32DB8393C49177A0675A0C9E7EECEF448A97AFDBE840FA01FC7E5F2E8FECEDC1884
+84C312E8635CD79195475DDBFDD4D38D5A0246DE2C7F21608F8D2C0DA1371D302E941572E5792A3C
+F4E51A33228B93A814D03FD4FC223C314CF3714BB3A34BD4F7ED6348577FEED9DEB082C4049E57B5
+D3CDB7F26629E9F3BA36893E09E3C7463D02A22D7056BE76B87763260E46E48BB832B7EE13F8DC05
+37EC8E81E9BDFEAD8C27EBDF1AD706933EFD11131E12814F236EBB01BE85B7F1B2D627413B324918
+D247604F56EC128909873FEC3857028BEF76A3494364C2A7002D104D486236C30B48E2B75D851C34
+EA50BA7FFEB4E19190898AE21768C157C0CAC628A2181A32796FBC1A7271D2473CD88E5395DDBDB1
+FC3AA8DF0F3D588637F19A8B833AFDEB5F655A8838EECD684E2315B72C75CEEFBCEF94344ACE8D6A
+DBE355008EC72FE7CEEAB01363A895F4E73F867639BE0A0BE67333848816B05B419221BE8F9066C3
+62C23FE85B7F392930BFE4C12B9526FF2FDEC38F23A159ED61A0718E7115C24597D849FA76369153
+54A40C965D4D72EC94DA61A03766AB39AAB684E134FD1407A5B1B19BFEBA52AA0DA5D99CBE5C82DB
+AA663711E6DEBA180E1D4A39C320516A4350D296BC19BF1BE054859A0889C7E9727A021F3176FE62
+0FB0C837E4141FECE531A950C03D319E3255703220B7185BD20FE5DBA673F8129AB211EFCF36EE39
+4C7E00EB0876624BC840FA86E58B2F584754CB6BFDFD76810E300741EBE4544E5AC17413ADEB21C6
+2F66CA4F075C32381796BA709782DE34A675B717A2C7F6D88104CB924FDE5DF775B4F0B68E0E2E5C
+2F788BBDEAF06D8E1FC2105CCBBD5827C0B03FD6CD64F0D073F3192D5F94839644E5EC6C5185BADC
+F04112A65F49A8C83174A9AE958E76A2F5AF469E8B76C833782C5FFB8BD7B1BBBB3EA0CB7C9786C3
+BE2ADE5E7AFA8C8F20892659A59BC421E28845A108E34EE17864042EF587A6D67DECDFB3F510EB40
+D2229585347A0035670FCC76C2837A4E4D68304FE113C539B35C1F0234B5079B8E32934546982978
+C5E4DF955A454EA263C3CA5D7101F31A318D82A3F9FCB5A8AFD7A65209663B0FC9DA400B26F285EF
+46D0E1EAF8ACB1F1CB805E3986D04BC585073FC64895E4DAE1CCB749BB439CB32EA91176D5C39C36
+50D10AFB9C9884D5FB90183424CEE67EF2175D01D2478D67511EC9F54F88763C152697B06D948BED
+49240096EEE3D06AB4575E8E8B2CB8263B5BCF4FA1608720F52B675309833071879DF52C3EC2871D
+20F398B5CAC8F8A4D41D0F1D47584DD90DCDAEA4A1CF160C4B3BF1AAB890B5CEB6CB3488672AA68F
+BD938281DBC1D8BCFE92FBF514DA5358443CB6E0147254E91B38CE6787B2BB0DEDD2D38F5938737A
+977B5EA42892520C58F8FBB53C994B57382379E9490F0D6970B980E1BDF8CF9F4C3C5E0A18F66E86
+EE93FFE7FE546DE50F41364BCB3721B637072571FA1779F1D672FAD260C16D7F13CBDF3E4376E7FF
+56D2A710AC5AC35FCBDBCE2C9C17E523BBE6218617B13C1FA6679B308979AE7C61DA6E68369324C6
+CBC7DDEC364E5A86707266C0B459EE7B2C03FE584E529BFFDCE98C90A2F3D9305AA74D3ED8430DBF
+3A49FE2ECFD9C4BC9FEFD22618FE9C8A973AD072AB6F713E4DF02DCDA7AC5359B2D652013E131B76
+B3ED6C75FD53BA58D862846264627F6B9E70D8800F6D9B32242B747A67BB2B45675840D34F852AA8
+062FA6B01E31ED24DAE02F6CF788A17F7B9368175195DB0072259CCE0FFB2C1035C1D26E1777CCA3
+D56A827C3242069E76D6DD69B653768614B9ACFF16567FEA61508D51454BC02F6C60F755AEF6AFAE
+3536BBFA1823F8E1A53C41124DE983E51CEC92AEF4F99785D554488A51C20885346D1F761DA79017
+940A0C557D93F1DB6B3D00FFD61D08E96FF3AFCE5FEDF545CC9F47A2B1BB26713431D6D1E47FD6BD
+6E3C668B0368241F0EBB5FA9C991DF79890E52E83A3675EE699B61BAF869DE91F67278F510061C6F
+E41DE2D883F48CD0E068E2A652B244128D82E5CD52F35F210DDAE3054691ED55A7D99088AAE8FB04
+F525C2084AC09F5EDF80A4EFAFE981F74C0DE9D194320709B3464F3FF2C0F6AAEA6D973D9C323F53
+DE3D741F698FBF01036716BBD62957CB32CD81D3A2674560FFBC5BDC5C6E4F547E589AD0B1CFE14F
+5E17FED1C4A8ABE4E67CCF8A49F32C4C6044F1431E1CC382E7758722A6D0DF9ED23E51F8AD14D11D
+7B6428E27443715EBA4E9C05D6F238378F9498AEF0E7EE4FE6856622CC8E6ED141EE5F109E343CB6
+695C4BE1E0F66601C27975983BF557C04ACFC19227A1AD7E6C44C00529FC7EDD7F886D24B7E029B9
+C395260088BBFB96972199A7B32796D27257DE83A7402291C14FECDF7998C5C96B1EDADE0280F856
+8A8F5007852EED303969180B3329917973C2D32C080C9765B6BAB0673BC7ECFDBBFBEA980C263843
+39B7F1052591D91667D4FEE413AFC23DE2D4B9DA742F4269C6C939F5FC32A38040730A018155AD73
+3F231E4D5B9D01C03A58EAE7B5F590CCFAF25EDC8552CFC8D95C60EBAE1837D7A97CA137E9D4A4BD
+2CD34AEFD68D64B3F4F62326AC429921D7FB3C235184FE0899690A0B775F1A566EC29D5830D32372
+6526F7E7F5AFDD71B77E07613DDC4FC63EDF49051AEB59E6337AC0A4B6DD872E776C9CD0CCB86130
+5322D816732124F5978A86C186BF0A0F88E733CE38E4D7C1BA5378C5629B1EFC97806059990ED42C
+5CD183BAD7E94070E4058569DA2E51831FFE0D080301AEAB4350BA290318AEC582C78D05DD92E5AF
+B4424EA808629BC972E68F4FF2489C245593F07555CA6A2B25964794CF31CBD3AE5C229AB9B8C298
+06C01D116EBD0FF0F159ED2D3D7DFC73EAB4910BFF5B0B0B587CD9EA6E6FC45D63C09766224D8346
+1F0588140B258B1729F70BAE7962189B1554483392988CF230AF4077193E53330519394DD99BA135
+6D4730AB221DC6A66019BFAE564893DDAD7B177DADD16ADD21D396CFA6C3DC818052E2F71149FD59
+4A16DE0C2FFDD366C99B486C55A6E991E4D22CCB15843F0C3363676AF2F5B2D1B7EF66CCF2F12DC5
+0D63776BFFB058D70A9C76DCE96C754872D72C82A0C33F90D49C935402CDD26B6D743B1F43BED5D8
+B539424849C1495DAE73044E885A7D0F307F1816DF6244A6F2D97BFD4E200E93F69B08AF39EA21E6
+E347A47CEEBF803F73B978ADBFCF056789BB8E6E2563DE87DD9A8C877157B934102DCEDAC54D487A
+1BB2694F0034093C48F10A17D32E2BDD0C723CAF59ADDD1BE373AF8C9BEB4415AA5AF36310C31F24
+354A53C0B962573148BEF91D994FE3F3D8450DD4D686725799F53C373A0A3E3C060C2E1A3E800504
+9F26D716E1F381B9F83125E4683264A07E2D8938F605978E2513DD2050B3D8A1012797CBA8961632
+BED260916338A812AE751C7B657E086A0C7DDCD3BFDDFF3E48B84751925736D1310C4910FC114387
+F3ED7FE163F91895EBF55FCB425CEF5729D99BD8F2C072E36C310523E75CD8E5DE49C031C4263410
+9D56E91A46C8C8E89FD92012A00C33D0DEC52597B5C6933291A7BDC5CEDA95DCDA5600F9AE1C8250
+54E7EE1067458CCB66610704C58E4A4FC0CB5FC933D0322A716B2CD430A3AD48DAB3D4CBE9D23F2D
+092368CFC4E1F5495C133A92942EC62118D45C17723646E69407B4A89DCDFD2AB3FFC099A21D9D29
+741D68270629AA3A414FE58658DC9170C247B6E23F35C4BC5FF83009F462F2EEF4DBAC5FD158A658
+57F9B6DC1F5192DFB169DCB65621CAB2F1B07BD22F4155A8E9E2B6388D430FDE5EC1C834D22EA035
+C52E1E34482EADC36B4CAE902AAE89A7284E62B3C84B608D6BD05F75BC31310B2DD3B2C08A00E073
+7F104F03A41989D5F6B9A2C38B22F1D1803EE5D7A4D8DE44E4ABD496A1DE0C0E12C4BC96D0122846
+3F0EA9CE9509FEE987139F3DD3F9D0DF4313F555BE85433718F6D05F197C41A9D9C7A8B0D2740196
+82D49F58DD5F66B12A6520D9F226D1DF1F1B65CDFA261F980CA25A92645B86B64606293F8BFDE364
+C47D2AF2C709BBE77A70A5712F2CC26F3D66F5BE2C307A48E6F887F681D30121E32BBD87271B5DC4
+615D28C309F15AD263FB37424E56DDA6E17B998B45BE6C7FC6C28E3394A8764C9EB2DF5C06626593
+B5C665D550D4600172791CD208AE9F37BC082B0B242B0A504B751B18F4D7495172B697EE217834A8
+A4FB7CC16D6F9E8BB400BE8AEB0850960283DCE725249FCC4DE97D9886745AB6066C3E2F64DD8AB7
+9AA11667F11188D7965DC11EB760B772E282DBF13249F31986AC6898FEBFE23E3E8B8D2C33E00EA6
+FC493850ECB2E6D831D1EFCA3C2EC8EE2E394599091ED58BEDE97D7A43B6F739EB0F845EAC1DF6B1
+EBFE876009CC5D804B15ED4B56761B3CE1AF59C07B49DC798A44532297AD73D5101ED47F36A3678F
+818297CC27F6AAA2AACCC9AA9B6F5459911D8C56CF499E390AE607F3790450B2B9C9BE0F006EDA0C
+715B5CA0481734CFB0597478E7602B0D2C1E4F78F03C68C17C70E4B42D7D2D3C95CF40F73488B371
+8E2CB05A549944D86944D78724E266C3319AF89AE430E777E95F0D792B1C654306E421F3D63A26B2
+1E74B6E8B21B2E2B9DC596D013CDA16D08E65E8F24A84B12B2BADC653E6E1110DE2E709C1C1BED13
+707B70A421B384F20CA7A9A9D20324DD383F28B2D3C7A9C53F5D4C6B7C378D26DF11CF55238BE1B2
+4FA70DCC178DAD3D35670FE4919085EB1CD905971D76A368FDFCF9D2F0A23739851A3A6D2E02D65D
+54DEE69ED5D81315D3EA5E356F94EF256DD267FD1E1A9EDC9CD63E743F299BCC4A4506233B8DD765
+2CA067F741603F93250C087D368F9E9CC4CC1A6DED567487C05BAA992B0056A77F630A72008E3946
+15A9DB24FE56A956650EC9DE90A6C2259189440247970541CA198748928215C0E132A81AA13208D8
+63C1FE817F70CA573B54577D10B73100AF8EA088208A44FB92ACA314AE5879706180788C17BB1D0B
+81B6B95A1C4E0F9EA66F9B39BFE12444A6446691A7BDB03E0F03D9F07A10A7598F2166F108529F34
+CD90E601FFED3479ABCFCBDE8F051C348E48C61D95B00C59EA1287423F05666C3D36288844067E83
+E14F6B5210842C742B89F13ACD126B9FC50ABE2CA7D7ED513D43B6AC7F41EEDA416BFFFCC5C844AB
+2D23D4DC09B2D510504CE98D02E72020D9E669DDAA344C63A1B75632F912A1C0DA3885DA4AF7E243
+E4A4C6493D6595BB6D56B0359106957259E59E336BAAF35BD1CEC5CDE735272EBCCAE8D4904AEBD2
+B32610C6FEA2B69941D6542ECB44D71092A3CF067708A3D087AE99FF29671AB7DD8758759B971A08
+AE1BAD78270D2FBEE37AA2DCB119D72F6C7B0C8509018A70D0B0BE2C6830EF8E0B24B1CE1141EF87
+3A4D7DCC501F808BFD94E4DC0F2915AA023076BCC8006490A43685EA25AAFC187302EBDE7FE1965A
+04A5A398985D29F08E085127B56B057334D88EB638A4DDE64AFD204974C3939536B1B66A54B4DB81
+151853915718F70813F096CC1B0EA25E363B49264C2AD17158A4489F91453FBEDBDE15D7B74D7F98
+E81DF23251785D58295BA297F295AA6248A912CDD4F1111E6B628EECBB5139709E76EA4AB743CEC8
+26621D08E6BC64691CC90B3C3C1778931A28D3D5B1E20E96C643316613FC487C9B604C43463FA453
+3BCA1236286E6F5A6EEB2F1D9C34BDDE4595495A365F88055D9268541CF1654ACF478D384A5496A8
+772EA1402751A093582A6625A0A44816B5FDBE166835D598644296249B92CC90AA3FD6445C9A19BF
+27F59CB0616C7306070F33C7DF4E1DE64AC8C5BB2FFAC1EF2B1B30E5A0275E6004CF64BBE2C6710E
+DCFC3AA4ADD60106334708862FFA6652825BC84842736E47AE6917180365C75B27505EED3C6108E9
+898A780E20C3F606A860229AC46D0471ACA0187D6D539A1B8820F620F72B41AD1D3BF3834BF48CA2
+AFEA8BF535AF74C4562DEADCB63D2F5C7585722B77C989342D190FF926C8A5263B4F25286F99CF6F
+C62EE6E2AD61C82B29D82468AC10FD27764278E5558CE8B41BA111CB2F040914451A480C93084237
+CAC8F66BB7C6689F340B8ABF0150E06D5B1177278A4C08742FE22F42C28680F190900344ADFA486D
+59718C25D37275BCE4DF981AAC35D2C7E85C72A0188B8953CFA516FD545AEE0BF4B8BA301CFDE214
+4241FBDF3D204E3D2823301572E23F204C97305A82401660E12926EE7BA6EA1A81FF5C007933AFC7
+3266FAC4C134ED818A48E7DA01C71A46335C845F9DA5E960B25339D551582B375814148D94CFB781
+FC56093827B78578A73D4FF67B6B87F40CFA5E3F4325D9108CDB64BD06427B88C84105187316FA29
+90B4E3E8EDB6C78ABF164F4A9717D523794B2FE772A04DABBE688CCA977090979B5F47CEB90A1DBC
+167D305EAB231C9F4260C4AD10889CB785169902FC0BED78DA15B8417453BB65856EA0BEA5245BA0
+573F623D215F6C0CF801851C305B355D26B52B0B343645FE25C78A3526841EDA480919A1BBE5F56F
+C10ABEAA3E1FCCA7C43EE560F067F1AA2AFD642F769D1ACE8E2AAAF38850F0D757CD808C921D716E
+96FBC07DA7860DFA70CEAE2888C0ED3CBF9586443532B68DAED9A926655C157A416C383A53D8F283
+2A4E67468112A09ADC837ED8EC95F70852921F50D4417239FC42EE3624CA97F682745CC5E76CC7C6
+7BD99F2180F8C0B7FB49539C8CC474C25C0DDE491671FF329E51BCFA779346D4686835A3AD6633FC
+B5E0F67E0CA9CED8F215BEF4D240453EB2EDD6ADB22278AA5B985FA140C9834D38753DF2014F8C0E
+E6DAD19E8FC54C03C1F6CB0F858986691D99592562CAD95FA0A5B2ABE4A8B54B457D42E8C33A2D19
+51C0419A72FB94FDA78ECD92BD2A1416459E9DECA9469F35E4C47DB531726DEE8F203D7042EDB32F
+025DF3D582547BB1D45F7A5B70D317DF4EBB16E36B0D798E0932FD2A85B04FD67143E4B287A50416
+2C1F5A037CCD780088C5476385AF8168E12D97D44B0630621759173C8F1E3006B5B1C6D7138B7EEF
+C3CC5F54E24B2C3CA7B41AACFD25E554880AAF406EA4C3C6E21D3B550B040FB1952598A7E8E6488F
+E38288B2AEB6C4718338598A2BFE4D2B9D14C65732DA304C16FF3E1F8F03046EF095B65FD609DA87
+EC24A69278BFE65C905CD0329F6A486B8525B7EEA4F7AE56C2633CD83543269E8ACD6D71F500D82F
+DFBDE7F7F7B1AEE67328549232E26CA55085B6E84D9E2E7F74068F93A90C4654F2F396E57C5F76F7
+E61CBBE523DBFBA6E76638BBA3064DA025A79E3A294FE7F1CC28A3B4C57DD6FDC48E541A85534B25
+E1BC11B4F78019457239EAEFD4BE9007D205F1D985F389DB22400B279C10948551A6B4A17FBDA0FF
+C9428B18B43DC76EFB15FC2182216F1B60B4E344A03AD6C00F141EF99F89F24C819C3E32877A927D
+84C2D006940F39CA8B71E5951673EA9BFD1749923219DE38929ECAA9CE43B06CFA7DA1BBEDFDA56C
+61FF6C24F40E59B13870D5FDEB82D981154FAE5D6D5152DE69339359461A41A9713B6BBE47E868C9
+33CD74C75DB71D13BAE4DEC85E02FAA14EAD6C0A253B16C79514657B15E68CCFF9EE6AA385CFF9E2
+C53D9AE40F85C793E4E8FF50B2B7420F4FE69807BC5F37C3E300E6B3C3549D1D3246A2E70F091054
+1135BDF805E0A698E236B6496702D061241687B7B8D1A0E517DF0476DA09D89667A7AB375FD2672D
+CBAB8124E511502DDBD08BA04D941DF1CEBDCCF7ED48405CBCC33774A68C5212FC6F132641FF413C
+984F8B43BDFD7B1A2A3435F15AF07EF4970D3E4A0BB947C181E9CA27CC14A35BD1BD096875B45873
+8CA244F88C28728B74E25CB8C4FC1095A56CA75E4569AD3082EF194ADD11350DB3B74B96761D4538
+596FF7243B1E1B724716A144106E080D42036444FD472998460CE9ABBD05B42AF9389AC452BDBBA3
+A13A96890025789F16B9D92251FD3B3BEB2C61EDDB370A20456E3BFE5F4039E2557C451C524F8087
+015BAF3FF05F51869FB97512968BDB2B49589C1C7AF1E085250A47657465F480B7023E24C76731AC
+0EAB6704123D77977D3A2C4C56B691346EBE589C619C04515D34F81FC6A17527D5D8319013C5D4FF
+27CC3925E24C99231AC7FB9EAF0BBA482D3B75807AC85D03CD09DE5D9AE0B07B7A813F0449786500
+0AE8A7E00080300F0AB8C399057EDDBA273DD2E1B2A0DCEFAD3B332E6D4AC1FFAD846167DFD70E03
+46DAF84AF292D4F424256ED5AC4E104F80697050D50844A708EAC9E7F7784FD01646F3BD0C595CA5
+1EE6BD607D254E78ADDC5E15C3B6AC4940EC865A5C23105B6BE09EA09F2C05D6D76960A843B81EE4
+33977FAAC3CBDA85CDD2F4DB7C28293A77825635992AF8F3B38B4480D9A139B1662345A8ABE1634A
+77496C3F57597D2985E9E54717AB2E99CA35789441BCDDEDE9A9E2106B401D9684ADBEFE40D607F0
+75C179E9CC03E59E65430DB70B441D43DF03F2AA6FF06F224B6E455B01C64FB89EEC9103E48453A9
+749B4D602808C7E408A8903091D85E06AAF635D0D529C3CDD1B8479AC0F4208C284BB678A547F2BD
+77BB17C86D4560434F7AD1937760A6AA55B614CFA9FF8C9C96561AE6C8F2121C4E20237428BC51DF
+2099B6C49E3EFA18E6D439E6E6981E746EBB1DC461259D8EA0F8099C47CCA27B2D982B72C9A07CF2
+1B3C05D6E26E6E286E348B8944078E24809F9C5F3D014B4CBA02533F5621BFBA1F0EDB776C634746
+703C9F73BA89B1960A496420C68F54E5B901A6D733D7ACC79F275FFFB253F389AA480084468BB34D
+A1E797E43B7F6E8CAF5E8C93069A3A2730E57EC39B677BB73E3F07C2055599F7062E53B37A5F0099
+907D2ED87FF7A82C95FBAEB888033BDFD67BA3A6031A4CDC56CB1E4CF5B06B46E16D988BECCEFACB
+9E1C037023D7BF5CCF5D65AA66A17AB361BE7981F132A578F3ABFB97960A6034F052D9D5AFDC0679
+782EC90F240F943A5F9A3D969ED7399254FF67D89DF668F7C56FCEA1FFDCF20481474AC8495D3AF4
+B6D7EE093E369C057F0B70858220693B398ACF8E8143558132E4391405E30A73937C53402E459F4A
+A3539CF7A99A3F51C0307D045DF8B77757E92EA2F51BF0BB4F77D3904DD355665870C2B59F1ED7F8
+4FC71FDD7F0B6C5D3182DB77827CA6A2060D2B8C83C4EA4A432EF43A4D0A952CC6CBBE52A9F0CD66
+1A538973DE41FFE9C5CF55F2506B9EFEE51FBAE5E63BDCF5528499A47C031163C88D3022606784DE
+2F46A9C9235AEE3D4F71D4959B0CFDC5B7E78C8C0A8F9DC99440C2263DBACB343C5C648577F5610B
+50EAB1CF7FD02419EF3941C7CA0B0E64EBAD4B2CB05A0793DBC38F1946D44767BD287F5E9779C611
+CA0DAAA1E7393DBE0683C8D3455CDFEBC0E64B54B737E298DDA605227C0C4BBA87AA3EC7FA6EBAEC
+39E6EF2537D5974391D31739D9FC42983D81AEE44711C823F35F8E2321AC74943871739D2DBE9748
+FE68592263E7713F27E0D49B9B5CB7A4E55DE54E6B800D15856450FFD3AE5F287B12AE4F438B20AE
+9E27E6CAA00F3EAEADBE08432684FDF9931E925544A680182602A3C1997DE5D0630BD5A010535E66
+E1C123013D23966B3545C7431C39B97295BFA4099D14461004C42C85095EEACB9B47C593BC6DB863
+533A8619BAE09095DE8ECA432D4DDD49AA600D277E75DC3F5C6631E2A05382CB007825FADB77438D
+CFA78E252D79B6A196D5164C2FEB85D75ECA25FF80B1D97FE10E87960CA0FC47C41D3A213BF141B4
+8BC3AAA93FA86245064668394665BFD52D12C3BE4CE39EFD8111754398A944C3FD1AFA98EC337BAA
+AF899D35E804CF416AD7FE45FFF13FC6354007501043F98FE8428DE8013901BA6A28711A2CA85A27
+0BB135B72F1D5026E8217581860729E94F2F1878A0E96C59E9F62714FB5F8F25003DFC7347E99007
+8A9A331CB3A6A535BC61866F02513DEB982C4A13ADBFBAC3FF70A7335F40D5489E48E5EDEDEF1619
+1973D932479C62183B0E25EE8C4F76D4F1AE45DAEA4A12AEDD9EF81D248E8D19F8C8A5BECDD1EA1E
+98783EB7A38149170851B1942C96C53DE06DEF80913BFC04E539EC67C110498D15B78268853E5C72
+F485F8A27B768569E54241F6115875E2973292CF48FF91D45EBED627AE9F0766D22201B20AFDD40E
+5B17CF337F2999E0BD15B86E46EB3C18FC12B7DCADCF9DD50C6C7E3F37E615A892DB3F57E250A072
+A49F7277DD6A2C8042698233D35A699B17ECA5DBDA6D250ED4A16FCC893BF0DC2E33FB1EBD7DEDEA
+3C1C39603C8B7E1A5A833A8FCDD5570BD088749BB232615366687962C7E56ED089CD7B092505CAFA
+5A80F503C4CF337F07ADF0D106937E25670839D491F7BFF7A523DB609D126328C16113ECBCBF9C40
+04904427A108618AE5D4ED809F8CCAF72251104C94EC5BEE21F91B179D31DBA79CEEE5EC7FF698EB
+84AB1D2D1A624F58B3622A78844CE51498B2CEF38EAFE259D22C7BA61104651A862008BC1DDDA58C
+C45F663EB26428DAA85E7785363A69D2790996EF5D9621D53042F42F794962FEA46E46F37B8AD1FB
+76FC8D5CF2146843F8CC625139C75FB42DDA71A752BAC48F294E4C0C8289FC46DA5EFD9C91BDA6D0
+27518B7E81E8B21F755A9615627D5812ACA674D1527A1185EED4E3C628196E7D0759B1CAE6B9B7E9
+01E9599A65230F1EE469CD33B9BD9C104C44E3C1AB966C9678BD0AD78111A4E0F2D07A01A038CEDE
+7036D0534D684A1562A17AD64A00F279200C0371B1CBA61747671D2A21D3F9646CA290F6B82418A9
+6FA177C6278277504B7FBA936325F5FA124AB018A15DC18D2C5E8F93CDEEA52BEEDB78A57828D81A
+3E6C38B9FAF3DC4EB7273ECE3EA4482A1C6242A335862C2C3717F9C9ED95F77B140C4E1569B2192F
+C7DCF702D0BC9A50428EC406F8BD0CAF886B4D979320D3E429816D88F7C7146D960AC12E70F2CB7A
+9F4E3E366665AB3F1B4B6440F55EEA26DC9EE0096BB7763731740A537766490C8C174723BF0EB40C
+53701AAD12B21D436ADCE22203C1053A9DC4E9F17AE617888C4B4E6F3A720E4E6366BA628221A387
+D8AB15E04AD69387C310D3528BD2FAA5B22BFF3FA494F5FBFAC4F771C9C7402B95580C5AC4BB3AF6
+92A70CB2C851FA5CF1173EEC3EC29B5A05A0B728BBBB51D3B7AD8B0AF17A1563E82FAFD93F8B7118
+1FB7AFE352874F4EC6D334AB6747519AB8E847B7BCED33EB5458A828E074E74BA621BDCD03FEA604
+7F7B6ABDA01FC7514BA1AFF0D4D0C0CB8F4E42D5A87E395D9ACDD02CCC220C157153422018725846
+009A3ACD8C8CDDB66BC6836B4026FD9F526AA275D06C813179E5924F26A25094E7BDA8BD26AFC4CE
+B41D8964D4FC4AF1DFB0595BC5D6714C32F15DC7194E9A3A73013C45D8FA55CC0550A12D9AAE8E9F
+F199FA28EFC2426D8D1DEFB93A65717AF3EA8E2D5B4AA8EF0EF38E9600F7D4E7D9F1D67A2E63ECE4
+789FA74B159BFE2F91C19B0378BA52E93DF12830D99553B6618645E26126842AB70262D96E35E5E7
+50ECA0CE3458B3E51BEE2F21191136DFDBCA39BDC07939E521E4F492F392DEBD029C1EA237BD89AF
+76BC89F618D530160AB16269FA6B693CF14BDC4EC7C630025703C5337F61458FA09104EB15C7CB20
+AA4C9BDB7CEF3A09F25BC7F3149951A7CD75372993B80CD2112F7674CEFD6AFA764AA3486730D2C1
+897A264D82A91709FEC4A21E30D812F558451804EE6F3DEE2C4C437846BCBDA07C5B6CBA1D94AF02
+9163B7383CAC6E088AB1DC14ED3743EE77E26EA7AD3119A76C0B5F925C4DE305CD7BB3A09A453947
+5B9BD79BE28FC462D8718CE05F9D94CAF3387BA55E6E447BF81A9EDDD3A34E17BE66BC52B0C0BB6F
+86F6F008829173816D205182ED2ECED319864A796AB65D4E3950288BADA94FA32B6F453AFDFC6C39
+A4FCFE60353A64627E2057D4B379D3240012B3BB0ED0C7876CB83C1BA5EFB6E2A03F340C2B576731
+F848F762A7E1CCAF267EE06D621BC33FC245D0E1547ADC12CC0EB58B26BABDB8EAE9CBFBAB93836F
+FF22BDA1831DD01B7346AD377AA298D84628BF1C07433284B0A90FC89F5AEB2651BA2CEA405D4F52
+DDC0E74B871D43F71EB4ACE0D2B401F9348EAC3A2EF0AD295036BF6CF6F870D58E00B619D50EA7DD
+77BC28DEF91D805CD527DCBCFDC16C042BF9B874E3B1567EBA4C1E70744B9E7E5BD1FDA6A5FF6E10
+1613FBE58DC46CFAC1A65ADAF65E49757E9304E2AC9A91E0588600C709A61D4231730073A36D473F
+518A145E141D0A5A494441B9EA99AC23F60F54F8127B477E1CE698BB4129B4B1DFEEDF10D9E665C2
+47A62F112F5CA30B0AE5DBF3E495FF06EB28EB438CE8AAAD84D5F50FB56A3AF002C23BCF66ABC270
+7AC233FC0F2723DB99D2CFE7D3B3667732A531F5DC315CE74EDB9050BF75D29E6430F57CB6778B2A
+CBD57DFCEF896E6766C8FC5C9F9FBD701CD62CACF33EE0FC95E78DADD205B5F42CC63024624BAA0A
+B4DD447832B4E1DBA77BDFADD223989F8E958C8D759AAA37930664C6EFEC708116248A2A7AF3D656
+DDEAFD009B7F5333854608E67E5E588A857167ADF9225CF6C641F5E19C3E08678A281199EDDAC831
+B57223B1BEEADFDCBC8F6F25D32FCA2336C808162E8F381656E847FB6CB13969572425AA05AC830C
+33DE6E030F86A3A85D2A66A77F103C7042C97205526DC882EA9A00EB8BD5519847EB424C15F808A9
+1652A6CC89B66A5731126DEBADE123C63D88A2E550FACDEB3886FF98646000C64B3A91078012CA30
+904B71737CEF6BECABD43DD702880538F5A70085E6CC6015D2163681067C3D513A8C66032C34A0FE
+17A58AD4BC97CA69BF41F11D5E910FDFE9729652D3EA21F8DD8CC19160A8FC77573B1E9CEF4E790A
+79D8AD6723B6804E9616466C935303E063DEE29CAA6C3BAEBF278B818C2EC2F13ED645AB452397BF
+00DB8B26E115026E256746CD0C78A959364FDE6DEDDCD0F441A61A1EBA32C7BC172BB09512148D1E
+BAC9E791B7D51B71CAD2DC9B83B2F99B3726607D9CBE58B499A13753CE87FCDCE21C0AD0528ED0EF
+B9B2C927F57C78C626248AA2B835A0791244C5896686A66173EC9F802C4C633A42B086334D2A4878
+0E53D00809247BE64E529F96AD2F8B3922A6097D414DDE1EC76F9552F9B8D58B8E34F359AD792B2B
+E50C26DB05035E7497162E7C49C38D3CD9B98D620AA67492BE5AFCA3A81A7080185C7F0B5105223F
+1FA77805502A2E8C5FEEA27699858D84A95842C5F2FB68686D59FE24091FCDDE139B6463BC6C7B1E
+0E90D20A83651AF00C85797BB9F53ECEC1675C7EE636D0D9E77DBD8F89670F855EE4D4800FF3F695
+0EFF09BBF8A0DAF6B8242840CFA5BA73BEB95115F4A78BCC02D85ECCE0C0F2EF6F328AD1DD6CC049
+5A3315B414A4D61DA50DA46D7ACCEFF6EE56451805D26B0359AF193531F95F6589CEAD6FA041AF15
+3067F88A0A2FECD135C56682DB2B45A71D1FA737C064EE9A4F404BB72A70B3AF0330359393247EC7
+81512482579865240A23CD8479F21C2C44A119EBC4E81B308DD8AA86E60C3DD8ADA50E0DFE8308EB
+1A7F201EDE8DCFDA405AEFB47E0E6CA7DDB376DCB21D37F7ACC4D3E9F26B03A8DE0E8940CA3A9E75
+963A389DF8038D2C486072F61C0CEAF500753C7A6352B1CD0338D9212B42A4D3DA23D5BDF44C27C9
+4B88A415A3242FFE2E1B332477A21D2B9CE075EE479C6E657A4D8874A8C53964229310E01ED4F3C6
+86FEF5258EDF3B464DD6FFD7F1CAF473BBE722D60FB14AB4918E93878A8AE4773930B8CEE110F476
+7F42A52D9304C55BE12846C911A10AB9B2E036BF9DFD597F5348D42233315FA80D0F563C388BC253
+2103F05E90DBF1923F229F980A2F4585C7A373511372D07DCBACA583099EA972C03E5AA67E663882
+6DB134564DB993CEEB6E7A6659C7C5C05C310267D5F8A24EEC2D5CC3E3F3C808E6D6068D1A57646B
+37FABD98ECB7BAF99E7D9AC4414A491A73CA34C52F394352F6B5A15F0FC4D88622DAC694699C2464
+84ADAC3B1D366AFEDE2A2CD2042C90516A666A19A91C80248B11224BEDDF1A320E230739E755D098
+B6A67315535F4C187CFA67ED817A035056353FC859BF286317996FFFB478A2248B908FF12ABDE705
+402224A3EE5F463DD3D243875C84E02DB968ECA1CC52C75171EA50D6A88CA91327A7AA5795019F36
+C0A19C093A1C9D3723C7568F9D41F2E4FFB712FD47F897703D7A620B586B81936C84AAED61D84332
+B3BEBC4F95B796B93EF7A1F565C494F8A65EDB21E2EE18DC025522EF8E599887CA2836069CDDD889
+88E5862977B7472584303198CCE97EF9F9E1446D1F1F5ED1CFC666A8A0C3A03E1792EFB60A9B4065
+49E0DEDF6ACCDBD98742568B4735A747D8E5DE21E630125AE0C691D054E42199C15B1F80CAFA6E7B
+B2005F374A9A5F9900ABB7409CCD50C3AFCCAB1214E6A856F7C7EBA89BC3291801E1343DA9DAD2C6
+ED075C8ECA1423B43E587AEC67E6145272814B3F191B3C285639F9E2D6E148A02DC2CBC0E054D629
+5CD05DBAC1950400A9189316F0265B86A732D302C5BEE8ED233768F237C62600CBAAFF3A110D5EFB
+6CC7CA3B92D965CA7C5E8D3E64ECF239FE2507FC797FDBE54C1112B28D4DA44C60AB09D994C5BA78
+D663A2591934CC052BC70CD1DCA3325C66C9CB982E2039F5DB70C848D3DCEF655B1C2CD0CEC8865F
+E8E1C0A267BE4F707ECE6F5A3DFCA3CC1EDF92C760439F51AA69A4C1801E96CA4D6EA4AD980258F3
+D15C893913ABCE09101984C61B91D603053E49A97CB82FBA707DAE8AF1D579FD69C8481CB7B712CB
+CDDB4D287BE995E32C02B399602A08B9DD849039B5673F1930BEC7BF366EB082D2CA5DB2385C8CC4
+5BE3FC0E31820191A814EBA7C4F23B1938E6C4D800732787CD2CB97F762DFC85D4B798809B5F2254
+D826CA42B32695428D120298B44CF38494E56240B75DF1E41E46E53C44DC505452256DFEC819408D
+605FF14D6C1F3F152F2FEA96EA0AB3B472D8704E06BE9F8C3E8395CAADD06D6DA033E81ADE5DC3B8
+3DAFF743C6E9E48716003D358DF63CD7FD3E2F727D1F2D0C29962F76D5C95ED44B6F08D052025A66
+5785F264A3D5F5593677B630E628B5EA81FB37CFFD7A30B7FAD226B6FDC82B0878AF4C0EC4F4243A
+807B9839EA62BCBDF7C2E9B30A623876E632E084EBF4A21EDA04FC88A1C07021D0C72EC3E969D449
+FEB08E5826EC20E55B21EA71EA59F6E3B0710B0DDAB3261B4A2029ECAB68C19ADD5174E55D5E984A
+4E5F38F592A302FEE6ECE732DDE841A28672C620CC5D687455A5C06FA9FE688394A04F96312ED025
+B7AA6FBCE2925F3AE559CC1886BEECDB70822E2E5CA3F732A87404B1536AAC469989E9610CFA440A
+CE43875A70CA51F36CB6F629D9424C1E35A88F92D5DA3CD8CBAE6E8425A36968E21F4F30349749E0
+205BFF8D552837D6FC39532525370BBAC833F75F1854C93FC533A4AA53ADF7008173A70D94A4EBF5
+38EA9E62BCDA7C20E0A073BEE2EFAC34D2EF1D03BABD5147659E50B557045B2EB89DB303749B04D3
+F54B43FED612FCC68206E001A7AFE90230D9C12F74A32C7EDB5D0241DC3A5D51481FD7C8FAE08FEE
+263FBCED7C7D911B3A303C835AF5FADFD218F61A9D6DE80485ABCA88200047B094441F7767B97A24
+E8C612590FA2407BAB1E8B56C71914EEF2355DD97CFAFCC192BC06FCE063D3D9D1A629AADC75E3BF
+207234C208E7E30663EDD691043065C9CBC473D97C6D4DD3DFF59D6A9ABCDD4412C3128F603160AA
+D8F81C6E7A4DCAF35F3A99B4EA10A34375B477C2BF846521A7EABD4D28078E9340452A198F3F5ACC
+3DB7E3908939FF6E3709C6A3FD9889439A4AE3E10B618CC92E14B68429A3AD2C80940A1079452EC2
+66F254657BE7D79A2A24084AF73F6DF71FBCD32BF6913A3FAB25F977787F7BB0C3A3E8BAB38D7A2D
+B0B4826950643DD1E03BD7DD1FB149A33862A89226B7CB454DAF613128C2075470E42E70A9444A8E
+6ECA526345AB48E6F5160BA23B5BDDFDA6049EC44ED1461C7E0DD514B16E2FB285F72039DE3C7982
+EFD40D7F6C8E8F4CF35AC71B467BFC578002E8D2239A2FD2C4BCCDD8AF3D7DB1F4AE7F2D2E0811DF
+9D0155BA6EDE50B5F052F14F6AB884FFF244D8806C07EBCB49ED22D85DF696995991A954AA97A1EC
+D86ACD76E061B7541E87997FEF0657A826BD88EF3A4A5920462C6595E7A156F453291CA044CED810
+860C3B0149BCE73BECA713040664AD0591304106129600AF71317B0D2907839CEAC99515D357E980
+B1937B6E1200AACADA205421001F1B2F91753E80D2263C56AA164A74701A8D5FD28E46480B0DD963
+A683A1F355D7FB4463C7347C94EA5E2CA40B60B56297CB22D972C5BB10E56715A955605256C1541D
+9F3BC5768A6F355CD3B863F0FA1A781EDB49368F51B29481CBB41D4AEB07AF9DBE8F52C5D0FF75F7
+FB6431D37D6AED84D78C778871CB0F715B4F07580F23B586C969C81B471FF6A6C7276F7E141E02A8
+584D4B9AB00E7BD643D2C3FAAA299B1F1E25048461952EA42D4882768A70DE46B213A287F8D31AC4
+6D5436F22A796C05D1FE50A9BC2A928066627A0D87DD57A3AD91DB446404B41557D1457873482005
+EA20916BBE46C613F456C849D46BA79D20627B446B2F49E3FA309AE14F8C420CFD94922CBC0FB9D3
+5A0F7DBEF577F1849A1A80E0011DA8AC082A8C6F61658E65AD177ABDF23EE17C8CF0D26B9FA3A6E9
+4837EB9E930336889767A8D7EA3CE980A8EA95528B004957BE6067CD9BD8E02A0F23CC1762CCA656
+D33412FF45E917FD4A03EB6E8C1F43FDB0A8965A33B4FD26BC24A20B304CA817E88495BA9B361A3E
+933717FFB0271F7F70C5D3CBA1E86D0F51BF3ABA194DAF32C35C796627D00C7B2271ACE2463E37E9
+7B3C826CF3DB60028F240F9452CBE08F7EBCC5FDB1BCBB3C327A9F450B9E5671916101D6E3E5E458
+CA31F04D12F592F83BADA2C3683D3886AA3B403963AB5DBE220FEC00037A745839F67A3635DFD3BF
+F08F367482962DED88ECF6322852D643A54D5D303EB04BFDDEE9BBA1EBCCBA7C653B3A613A8E719A
+DEBE3CE1BD7E754E5F4977E863E3C2D388A65227B451D4F3A4F94E06513CBA4AC1F2F511613FF035
+611684CCC461599000E546E4D972CA6960E095A526E4735A23421A4C9B597ECE08AFA2753592BD16
+DED93255A1E33DEECE3C5EB77B94670E8137F2A4A4B98AC193258E7DEA5DB8408A806188F2D1DDC4
+40CCF0E9A6E2F0C78FDBD7B68DD4939D2458C1965BF8BED4564B32462FFF3EC892C03B11D3EA813F
+AB4CFBE8D3016329C5B7E3DFED0F08284D44AA0B7A2F6BC96EA4503E8EF52A64C22BED6B452581AE
+8FF8917D53976471941A9116A2D878FB2541B561767ABD4E31CCD8A590CA03494C62AFFD64EA0A1B
+C779173DAD84999C7A8D844EB1259DE7BB5B25CD023537A474A524EBE4660B22568949E624D8FEA0
+AD37F4CE1EC75955EEFA49C6BF1803BE87E9C9865FF3F6B8525B8C15FE8835CA153D27E6C0FF0CA5
+1029A7A9185D25F0F14D86FC797DCC1F99EE97E2054B9C2A2E06FDBEB8DEF6CDD368BF23A858D9F8
+C1DEFDCEAF1B4A8DE5EAFC604CECCF0D285BE00AA912EAB66EFF4D37AD2EFE34853BBFD87CE09B18
+749B489943EECAE7887B006FB827D10191DAD18466CD1F86505879310A8B171F902EA0C26A388E13
+B53C700272CEE2BFB47ACB58247C13449C6BB9D01232C32517358F1A3DE064D43C18F8827D53789C
+CF3CE2EBE78949A6ABFA1A6B8414CE360A5E22AFB7D1DCE6F5A06182C3B984B4F9BB1A905A9D5A14
+83750A1DE0A857CD5C06945EB7D4A2A6BF1237F32A154FDC06D51A703D44FE052FD3C53E9E8F417B
+35D1C851F9203A8997521529F21AD8498F96930AA77EBAF82EE02A57BC77C792D9F220294B45F48E
+A8FD94E01CD25645D36D168923562F3FDC93CB79DD4760DA0C103C2675722D7A1B79FCB4245ED12F
+A0DB52492C9CCE58B333CFEE822812F7DCA68E802C451B5CFAEBAC608B950386B6C58239D1C62D62
+4DD5D15782FC552222CCA06DDF387B373E32C3C2864C63C768350C37283760F3515A5B0AFD66C48A
+B522EB3E808C061F5CD6BD96CD18C9839D30508E7D4EDB88E8F11E31E10919B16B7971F06D7877A0
+58D8A4944C84FC6CAEDF3341B48B6E0D3C7B85D710E0C35F5B5053CF4B4798B3778CC28B2DC7AE0D
+F3A49F9F3BCD8E95D746C35C3F47D68B8AA35D97AA08E711B5FBE70D1A623C82541EBDC51A827D0A
+69E6C049087AD26F256EB7577F58CCFFBCCBA5A95D093DC29464C9A38DE95BC6B1853963B2DEB0B5
+7AD1248D6F1625E115EEB9510B5772AAE4E3C866657DB0B3BF0E0AC345E116F8D4976B770876FFE3
+748C36165522991F46A36F193DD1A1C94713673C7E4C81582391B636C72DE94CE6254374F99B623E
+5686C13D8A8322E83E11BB0B0A896C6A8C2C4F756C5385CD7017F26D23F7C3EE97372C868C8C9155
+81723BB6B76B4C3CE8998E4FA6CA40B633DFDAA59BA902A4952DA90EC4FC3CF0F2676ACFA7F76F78
+236FA2DE10FD3545357215246BB7E527F277C28B353CC6D79DCEF21BCC8F77603CDD58A2CCDDBE3A
+9802F941CED8E035313875319548C41992A2BE939A17CC109426E33825AE59BCD17CB19F50D972FF
+CBE7D9B4B0BB095303D9DC9D406696C2508D6CE99E11CF00F6461147E97449ED5F486D480A86D3A7
+ACECB7E9A945984724EFC21C5079B1FD03ED803C2DEAFCE3327D2D7827715FD65D9506216C88B0FA
+26935E95C64114A51919D419038B1A7E9C1E829FBFB53275093752DF19891A97F3CBF7719C1FD6CB
+17019A6D2D25360ECA804C4B35172662CC4769D2B785C6C87E5A4ECCE31704E59F71263B7C3CAEC8
+ACB4C7426EC25F11A0042323EE6C3EEB04284DBAE2C770BC419DCE79BD4560AEA41571C3B595F525
+60191DC7A8FBF63D413A77A0905E517441B16C2B501EA2F9E99CC38D052679F288FDF1894542E3A6
+6989A0090185EB2E75134BFA3D9147C3DB8A621D9D35E37786853779E157B47F71626D6B3E633005
+9159C17596C1B87FE2B4FF47ED9D78FA4C2160077276C8B58CEF5DC030B4A5D83CF257096C047FE6
+4DE307C598B815058E72D5F57DF5C369E664E137DE29349E2F9DCD8C9F4EBA6E765B6327D7A20DFC
+B20711273FD8091CBA605C4C494248076F7E03DF65A6A50164980BBBB708741E5BF6056E6F996DC0
+7FFF408C5B8EAB8DCEC315E92873228C805D4440A6470E3EE3983758DD211C9CECDBFAA4C9300CBA
+00608A4B2404A3C7AF017A3B7E67F39F0B51ACF950D3E75CC7BC2B8D3480202FA958E8EE0B240501
+5232EE0D264C7CA02C18CA45CB3C2DE322D3EB7F00F9455DB6C5B1F4E59C3E95520EC36D7D903CBB
+625D70B54BF6F8255E412604BBB29FEE026CC660577F91DB1DB4A613EEEFB20CF7AE3CD89D565AC8
+38416B01B5DE4FFA5550D17FB51FBBEBE21CF1D56038863EE931B90DEC2E211ED42BA92EC244D4CE
+2C4EC5CA87A026992772DC2AF754FC982B94F36EA7B7BF75E0ECE90CBB2A6AA1A012E8898BD679C2
+3CB3827C35D5D02F0569C7AA82615D4AA67518ECF668D3B57D6EF1A8013424AC2268BA0D9A74D588
+79EDCF6382A89D397864940303EAEC45A38304BA8B1CB198967AE23EB81054BE74B16909A405E8A7
+799CEE3C270FE2A6DC50BD7370B6B2C8FDB9A87D88D5D40348D3984E39C693B6F4486D994778607A
+80A3122872DD65E40492107C71C3CF708A9717E9EEFAFBDDC239C53AA9645B711038E59C8B861B37
+411AB2039BEDF9CFD00F08D9C5D76154427FF5DD39878CECC5D7BFB3F1F035087185C0981F3C2139
+BE84872FFAD3408531C4EA9387B89F5E3EC779E8850D50992DFDCF9132BC551E985943B07618AC10
+D1150451F0844C0DC41D6E17EB508DC8689EC726400D5A7F6FEB3CC7BCE05F09228B7CB2C5393664
+D8DD9A4B96B1020EF25D70AA2D91CAE93AFB5F2BF0AA18CA5C599FA1A708EF35BF8F7FFEC9AFC1F2
+42870D028B2B1459063B493943EF1283829783E1010242E5CF4DA39D93D506F3892936E7D6CF1124
+70A521D397438733D053944CFF12D6FFAE8246F20618684F263715AA98E15D72A526383E05C23214
+B78338E5B476F0981D90056E6E5D0DB66B1DF2298E597B2ABE1D817E18BEB056E65EDB4234342D96
+00470B1420C9210419D834E431B82F58608C87AC361A02D0F1FE4B470A3D71E0D21BB87E1023D428
+E23D596CB9E1A2184403A16E36E644BCCF9BBDE27290485057E62827283E7380AF786BF395B3961B
+A5EA469C315763FA59E0F176EF81985F38B882DE56A74D128E256D1B89939728E55A92ABA21A6B78
+44FAC1BA7BBDD8B34A18194A2984B000380FE9F672E83EFDBF276FE797A325815B0F25CC95C97A9D
+ACF56D583486305D7C9E51A7E337D14E3B900333EB38FD93A99587DA2341B10C059C71CE080FE753
+3C0F059FA40E560AF9C4A41A4BE6FB45846FF8F78165E10B4AD40F264BCF5596A1E8EF8CB6EA4B1A
+3A5C69059AB1563843679ECB2511A90E8898F54295649CB73D277760D8D04ABACC7BCC6E777A0530
+E2067CCBC08673F9C8C178F9D672AC8A15E5367F0C5651B53E75E0CFA57C931746AE1A679C246D7C
+9417F1CD89DDDBD1173C2F880B7B3847CBCCEBF99F7122E832D7C9BAFE2B54CBAA1ED48158DE3F36
+238B76B0E67644A28AEA996DDC006F6AC0242E4B667639E7523CBC90A0561193C1AF34481C2EF402
+EE43A82E1EBF4E3D601BB36B2D95CD93550D61CEE7A94E72F6D30C32C8F91A61E964B1F66ACFC398
+7F95D4028F116E9A9A8474AA29C1C1A984BE0E393BDC41DCEF6A6F1018DB60D52024899D8EB5D55D
+324D73F39BFA47377B9E15B3B06A7585589FCF52A54684173E5183367E7B0952DC4BC2767C4C6247
+B1D6103E52BC7B7EA6298F454C5D97AC575F19C10ACDFF4E10C7D3755CFAB4200CAC545269FF1D8D
+B0D607C7AD47F40DDF257AB4E7D0750577003C13E4941960C3DD7B0774DDAC18E8ABAF8F53E03CBE
+F6D57B44F24CF821014C064278FD51B3427593D17694B4ABCE81F49CBB984C5878CDF0C38D1ED7FD
+99B0B9A3BD8D8FF6219588B3B8FA59D0CDD1D9B2F65122AB45E48F1757467B9204926140E3C350C5
+A927A2E700173053EC35D3F1DA2D7258714C97FAA857F0898917BD94625C6D1E2D77138EFCAAAF51
+7B17FE187A2212C24A881A2C6A647DEF6376ED80AE4175C5EE80921F001995B44E49F0D33DD9075A
+CF33BB03671C0BCC34AD5784AD1CDFED3A6D9BA103B3DDC1CC2DE74DBB576A0277715275218CD19C
+A8899209125266D8BF1286F881DCC2C383749D1E768D670F4099F7DE959EDFE852583183C9111601
+2881A56A24AAF020EA45CD5F39660DEBCE30AC1C7B8CFC60387B1B0C3E361BE612FDFA9F01B7E4B4
+A18839A2C7E0E393EBC5AD9A8A4EBC316A740C1C295D9EF5F4DFFA0667F9582C0BB837B142C4CFC6
+B1798E9476D0631111033B8BA75A10FDC800E2AB1E0E829632F869CFE4737BE9E2800759EE0831DC
+7D1195EAF80555771981DD6DC6606812D92CB8EF86447F5F6C6F626D0E265C67E52A6319189EE349
+D48E49DFE6A9E98F76C414A1E3217AE0A215A17E54AA498F4ECDC50242ACC7E2322F63BB2FF2189D
+057E7354E32A3ED1803116176B9B9D0129930F919E2FEC280B2C8924E49E7BB75768A2EE1DA8ADBE
+D4E3589906DF1B923AEF84C1BD327438B731012E69BB0D43A1842CB88BB54EA4516477F704CFEB28
+6E3EA483445AD4D74586FCF32E96D366901084365F693A53C5FB532FBFE7BC0CADC404C4985042D6
+8DBB90A6DCDA3531EE324D558A214F935CD9FCC9A0CEBE9B5FB0323F4B3820529599EF48EE068B5A
+CE85004FEA2984F0A86F5AC9D56163BBFE1142B774148F1EB0A4DC89C3349052533A7DE66729DB24
+41B82F8F7360111DACF69293C9B281A0534F3E9E9224A75C49A832F28B2E497262475507B6DDFA9F
+01CA0A6696E3F5AC7EA68595EBA0C2EB8A47813FF936D84AC1B23ECA7AA2862B793CCBB0DF9FDD49
+31BEF354CEC12FBF478559FEC29F81ADF4452E83963E56541D31F3691C93A50F0BBA5E9552C4F2A2
+3A6E53060729854A3DD71CC4308B91957DB19E66AAA18FA67055A950F1C2CFF78A03BC1A588CF624
+696068068719AFB1001C4581EE072113882D9052B21E355D401ED8CD24D067B99E616BDA5A0A5A93
+36FC499632B79FF2FD0DEFB096EF46B75E2D4E0F48DAEA239719FEC4D9A29818F5875FC5041A9EDB
+D26CAF0ACE14CC80BA49BBA59E918EB3D8F1E541AA16026585A2F72DF7D83541816DE46981FB3EFD
+0C30E458CFAD04C79421AB7C4925E23AEA07F9F018431C790002596D26BD9663B51B699DF53E4882
+CBC34EDE88EB55045B889B6062E35FD1E018BCE785157B85EC3B9CA6C85D4B16238275385B8285DB
+012D8FB7C9F5B946A41D7A0FB878FF72C39683144D8A007CFF631B43748F2D5FC690300F9BC0C837
+006B92ECEBE0605E8C3A4A400E18AE8997D1B45FEE10068E247C647CF82C6DFBE5E881D511FFA687
+B7AEB78546BFD07D5F7EC242DCEF4930D8AAAD8C6152B6642AAC325963FD147F236BB850A9966573
+9D06CDBD7CA79A527DCF461E33F22BC9C5DB00DA2BD3DDDD8C99D99793BC98282AA8872FF96C3942
+85D82D9419EB78B6AE37A5F519397700F75D624A09BD255B576E955A323E784E8FC31131F003B0E3
+024A4F58FEF2A6C043796201FC425482E1155E229D1B2D43EF7B0D22322B22EF5C9A1BE026A1C3D3
+75EDAFF99597E1E5477952A4E8D2ACF5D014BC00DC2A272FA62B6983E27D228881E2EF2B8B95A681
+CBE90C5FDE16331C85222FE2A16F0A3C3000A63E2E21666C0C119F8AF89A543D37977069A5ACF155
+6324F05204CE8CAD50FF4FB630D9CBBFC324DEDA584AA56A99D3A76FF55BDC2C2EA3A021361CCD4A
+83C7A5E2768D210FA6DE889FD48A39D679C94EC3C99A8D33FF11377DA7F6F1B71A2A05B302ECDE95
+4F26773F39AC881542F0D0969C3995C3519A8EF70B4220D86BF01BEECC6462855E7B686E1AFF1CA9
+1FB8FD8B4A69E10EE0C2AD94ADD44449506F9B6EF43641F2026EFF6E605C670560C2B74706FB949A
+A7E8CC6A2D0D6207E457E7FD87EC1B9092DC68B9143947CC8ED14AFDDCBF8FDDA228A76847F96802
+E561F67CEEFDE45AE587673983FC04C96744DBAA83F2DC838D633943C75DCB9E6410474EB27B348F
+26E505F0AB90878940E846C5E9F3C5FE8C3558C3236B1B88C405716949B8506841CABE1717474BB7
+C30DB91CDEE33B0F844811762FAEC535BDCF84C1C747CEF9B1FA61D2AFB5A81335BC42C06A94D7D5
+9B7EDE55BCF6F9867AEE107555CDD084B7684C2C87087475A39A9DA6347BE281CE5635A4D07865BA
+98CE26C1465B1AB0343F49FF37B4D0CA9F3BB693D78DC3B21925CB996A038DCC172527FE57C07460
+EF39C07D4396E7FA970D9F22ABD21A9C794B64AD96762C7428F59A8757C36D6C4FFB23216195A04C
+2A2C2E7B10EF7193931544D782FEE4B91E01119C5553BBC6252270A8D8C56DD62D448F5AD8DC69CC
+B45E1F17F0AA1E445129DD00F000005B23D38DE93A3BE55A4C041947F36B4E4536E307D0180553F9
+2E46B743881CB5D5386C48C7D5F84C2BCD06B9C501F78C7EE61FA23516791FCF4DB278AF688A2E60
+10A56692AD92008497487EDFE4BD5FA083FA544138B20D6940020887E35D46E093B71F7A04A67460
+DC8116B4D4839625D7CA6959D6831CD93F81AC4EA2709036DD738364FDE71113BF22EBF13DFE1642
+E564701E6F0FFE7511EDF03FE448C2B28C64FB7D54B94CA576E481FA56B2B18AF10C71F699B6BFD4
+7459CDE1869D0FD306BF489A6F42E5B2F05CCF55BB6B9526973D19CB134CA7F13F1DB3716F8CC217
+73A832568C16250B5CDB16DF24BF81D49F5B37018BD310262EA7078107868AB0216CEC83CEFCAB1E
+9F2C665A31585CA04DC01879CAA79AAA5AB201B516F7052B01B16BEE5606098393B0E5D9F9E5E3F4
+EB20F63C958E796DF41CF28839F5C62A0431648745D7837B519F3AA36BC6C08EF040CCF53D9B6D8C
+0C7D1A84D707EC57A3C6AC9A62AB37251A01A5ED40FDEC6F5BE6E34C6A91D058319439778A2EE5D0
+363E2E1F33463C33327D05FFC0CBF08D5BC457C7230448972FB9B4D0D782BA7DBF10D3FFEF8BF523
+6EC16D4DD6D0D870D9D5EB5C64C9A46A4F583D4F831FEE74B0E5B33A09ABFD4444929BD8F638CD72
+EAB99CF2E9551DF427683964A592E49D186F285258C5D5F62196A98532421D73E3495F82695FEEC6
+E1952C562D546B28618FFAEEBEFF03A57F4D855021F85B0C7BC37FCC6DA9AECA099B646B99D41896
+09D3FF2D56422F8C37E97640293EC7C90E3380887836F4938FBF495CAC14FBA5648D89282D8D49D9
+1AF73ED36581139D8BD42551E263E830EA3C6EB381D85C42D74C50DB0CCAEC03F535ADE92128A016
+0E811C34748309AF7604919B66CD43EB5CA975302DCB6076FEB6BDD6FF55976FE990FB0CE9ABB11B
+195403FB26E3D6C6A0DE1C5BE79E171A61E21F79EE8DBE7A832519813EF6B33EA098C2C32ADEA219
+AB2AAC8B093F40000995539D1276D5F2EF84CCD099B71FE4269BDBDB6A8D59C86F7D2E3FBCCF8773
+D0FAE97640BC1AD43CB4B992BFADFB09DBD0CAAEB8CD9DA264187C4F97300E9A6C9DEED5525479E6
+05C65AE336CBBDF4E5D7F79AD098F977285E065579B748FEAA97F2A753E1F962FCAB68D72BAA8EE4
+FF6691C23E31BC0F3E981A96FB440404856AE1AB32A7205B17D411D8F21C8C93B704D07EC594422A
+BC368CDA2B1610CE6A973F4474E12B78B532666797F5755D269772C9F5400B3BFC6C58395D38527E
+2CCCF29B56123F7DCEF3BDE5DC1DFC5B0293BB125085B1D2D929BC3EE84F4FAD571A4991C3DEE03F
+2DB3A3097E52B1A7D5C73CCB6148EAC62E8E36DE9A71C57638C6E4D5D9DED18174E8C390E50B4A5B
+913C074EEAEBE390B214B3A68F02862B9A296DB4B409769649E51D738CBBDFB7702E15C73C2AFC6B
+C37CE15171F4E822CF20EFE55D9F061AA43E648989628FF79E65932390CBB15D8E621333B18B11C3
+BDF96F841D7434E01AD501FEA964A75B248A35CD9DF9A37E48A1E5A09C624B93CE44F0042FA00D7F
+9EE89B9F7AB785E9C718CF6E7228F743271C2C9BBA17E5208B920E44E765D99D86650EB454B0FAAA
+112753AA1BD3A24239E9C5FC47EEB1547AC9D23731B8DC48B9707830DAEC60C8D3790BBA1120F776
+4EFAC542CFFBCD5C05F9510B27B2534B704ECD36C8B041FD49A96881302FFF5B0163A2DD09C751D6
+D6AFEA9170A4F4C4AB8D46E62F763FE1BDA51DD1CE4A27E772F3A2869155F762FF26B7AA6FCFA4F1
+292E56F03AAB6322BF867E7710C34D43B5D85B45AA68014AD7879EED051B1933E491496E3E26D9AA
+8B80A07BF2B94F1077E84A9726F08199887D66DE7A307BF33C30DD9CF3DA188088C03B2BAD09A217
+6B110DB2C868B53DA9A66C85737BA66C93C58A259860E294AD0191E3A72C73F40B0BD98699AA08DA
+F03587B78F391F3A4313C58D9F29B53C70785637BD0C58310109C54091AB0A34CBB0C478613A7AC0
+FB8F0A8B4645AC966395D8BA775262CD291136AFFDDF01C1D83DD4EB3B59CCAD18057FE7D92A8CD4
+A58F22508D9FD7CF356571F701BBB23E749BDDCBF8A317FDA0AEFD952BB18545610FFAD3AC143D35
+1B8DB3F66293375E0E50235F0D0466932181D377EDD32A5F0FFA4E22B5A0CB4F343D9A7E4A342E9D
+09DFF6C697630CD3971802C277A5590B8CA94BDE6B38446C794D072BBCCB724D5BC208EEF1B018D7
+39373BB910D668882CAA779C2D686081DE6A2606417B54D7C20E0E7F722648D893E4EDBAE8F00D6A
+6DA3712F91AE860C756D1127D133AB828E9D80023B50B162C5A1C5CDF70CCB3FDD7EA060ED20838B
+E1E50C4094C9E79E1A0187CDF780CAF45A725964F004253E034C5BE46BBF89D94631F1A33BAA35B8
+4FA2A9D08481C6674126CD96ED05DCE48BDA069D902D6836D5DFBA701DC0F98A863E64F0E312145D
+8DC0B77F25B43AEC729A1243B45B08CA228DD6101CAA2AC5ADCC8EFF84A4CA3F254176C2CC711EE6
+C273835D0FD3528ECA2A976B88E51FE347FDB60F32370B66D338931D6581630ED586F349C638960C
+31AE4204E89521A96E1219E696B913DEB2AAB7A3B022D06F34FDFCB810A04E60A4FEBE284C2F063E
+0AE9EDF87704921CCFA193BDC912B747E13570066223A49F1F6E2AF0D4D65DA04CA876FF7A462FFC
+9C0BA2CC545C3BD36DBE762F32B2D6BE5867C59F479195C92440DC165098B74EA5C3AD93CDF2D410
+B04C16BC7801E7956F4E5107450787AA592493171C3628E6B8F49D4F8429EB98DC52EF025F001387
+BC1A7093F7A99F10B5D2D7DD8BBB393BF6E56F08F4F7FA1A343F220D5A1EAE7168C74D41BE1DC1A8
+3BD65B72B982F4F7B34F24F97F9EC9A91011064031FACFF2A14921A32024385F4E061CD07D152E74
+1BF97156D951A342488FA7F5EF934CCAD13E2753A0AB7A1F565C2F7F6B349DF03BBC25BBD972A9AD
+F809BB5C5048A8CCEF9297B2ED3324D18867F293CC66E88B3A39D107B610DFE79A3B4E83A96D3D52
+A17FE8A62C9FDD271130148366942C9CE57558D023DA5F7501319EBFA33DE9E6D1E76D7C20DB8A09
+B657839DA99F3D8143F1EE6253A3295C9651FA4366547893C2DC7ABCBF4BB7609DE5D001E0A36D9F
+FBE01F7D0903B3208AE8547E2E5F14EC1AF4C2535CA8F4EA37E3F3CE172C7A1E8308995B1CC23E6E
+81190246BCAB6E755BF868D449BB02A2AA87C44C9CC0F571ADC72547CEECBE104BB274B8AC16DCB7
+5D5F458D356466B921ACDEEAE384E2EB1DF6EF393B41B9747F0A4FAEB4AF1928D9AD6FB7E06FDC62
+1E4C6FC98CFB43F88584BD55D9B97CC9549093EDE586912161931162B1B1D52D0443260DABA02AF2
+B4432100D5506546013DA703573FA8013685CC798CE501960093DED713FFCCF89CA2B9106390198C
+29A00864108CDCC1984A8BAB53919028C01B26ECC7925E38CBE6CCA8978EE21C2B06E7B3E48FBA97
+8E2A7D186E563C088F84AA23178B60E4729EE87D67B1091F3B6973676C1CBFE6530EB773C62E2C24
+97014AB0E8B71A1F4E86A378AA26591511BEE3CF3D64C94848582E1354E1605B6457823F2C5E640A
+D3802946BB2E7E8E594E8C04B430C2385DD40746CE8534F50842E74D7115F3DB0C72D1C9C607C657
+3B094AEB73B7A79876CFFC3E2F8C9FEAAA07D3BFCE05B61F7749A8793BE90CCCECA2D7077F25E899
+D3331FE161A7E86C842495D584C6E4A0880B2951D8A13B88C4672080A0B1BE36BF47C3ACE7288CFE
+41A8C1BAA6F0814A947FBD6B3AA72B6C73A8C578CA51CCC96F2352316C467BB960E981F2B6485BFB
+44B577E71EFDA16E7405954BC7C9F0759F5A9F1EBCD2FA9CC9648D5831A68887F41B15081A204C24
+B4B992A231DEF9E698D4C3A25B6F5474F5BE6A601F2D337A58A0D21FF37FD91EB86D1D738893A03A
+69F0CD743F611CDFFE69DB2C6ED0E4611D56F803BB0DC06E7FE85A303839612707647B1BE9FAF8D6
+84122CA9E5CB8BDE2936D3F4FF254D31529D7538BBD4D35539489F9E7316F24214B996BCDCF1818E
+749A71CF0E8845AA1E2A58AA62A48E02BA4564625D20AA220EE719608521D7D7A7FCA0BD8904A401
+9819D371F3F59D46C1354E5FC1A6E5F79B20CF4ACA2BF0F2DE73DA193A6F9ACBFE0B4731C4BCEBE6
+D96FE822965DE965232282A3A130361F188B3AABDA95A8A2790D9240BE008B6A6DE4BBFCADA05B67
+86B9BB8E0DFA0C30043A3B07ED46277E07B9808422C8ED16758B9C396F4EA929D769785B2C9568E5
+70A83B989B25CE200F1727D41E2B702E7F88F1784F4C83FA60A74EB26B2DA95126E508ED519A61CC
+151DB6804F61826C5F86D8FA89D06E526FED97A0DB88EDB432FF32C1ACC9B622EEDF601081AF7B96
+3C9CFC1D13E4A9C74FEA0A1C8E3D8653CD92A944D4CA6B0D306619AFD503506D77732D6514F604BE
+4610C2560931BDE0B40939BC1D126B0E97F72AE1B4A9252123B54F7A27E0CFA4425B4546526FD741
+CA77952B10D13E0AC2E32006A903808FF0CD013F936238C74CC75FD915244C56A8412F37F0134840
+347699508D6F3D7F3203A25B7C70100719582CD588590EE34B3AB13E255B613A6D00386A0104CC5E
+D2C646F09A88888D3751651D5646C5227A3C80E8DA1B0A331121DD2429F1F4775D30564DFF47D01B
+BE2C6C72CE4D1FD9A2077C04D2B0274B8916F6A9D1A4A6964A534F47CF241D5A8E34B23F85BE9ACF
+FC2FEA961F277539F215F8728D6788F67BEAF45502839BCF23D8763C3949352F00C579A9A4FC408E
+C625E310DAE61512DFE6844E82D36A2F81709E1F05B38AE9C222ED62C961EE63593CED7AAF73CE2E
+D3667740C77B309B93EEFE1B4BA65D48575A66BE86743DC9E5D3C2FF418D11F7F211B86E827EE1DF
+C3613E7498030F07050524536D1F8A94DDB6698BE7B963C55CB3F74B676CD815A7B3DF4B1A0EA2BE
+1B0B9A11FFBFD5B1FA49668AEE14629316AF436A0821C20BEEF7B3480847934A99F6D85B68F4DDF8
+859A754E009428AF89A90D1852C220A607FF0806E8080726EDC94D691D214B4521C147C4273AEBDD
+BB4A697EF16448CD9B2FC95293305858DECFD406B89B9F3FDAE2AC579E80CF321EBAE5701FB2F7CA
+D8ED04B4A63115886D45D6120F69AEF1A21D80AD3C2D35D2899F1902242B96CD349E0AAADA40F7A1
+1282B6B52BDD97708E58DC5E2D22D1153E5FA3F3B300BCDFAF98DEC2F4E3C82A1C85F985735F3987
+4F557579F422664E07CBE19DA680EFB0FC82C323EC5C4644C51709AC8D674608A8043C91E6C7988D
+430F10BA6CE1FC7FC0604FCD8F723895250AEC36CC35B3FA14FE2A0D24095DCC30B2093F2298F5F0
+A97676A0BE66C3DC9ADACFE2FC0F721A20E945AFC1096A619075D5E9A264C796EC6C90EF1AEEA8DC
+089B44FFC13D27CB2370070A52D4416C53F364393E46EDD7EDE00799960CE6E0D57E4909E88ADD64
+BDD2B0EBE2D73FA6ACF8B40280DAA0637E705C65AABD523B8815F22F23E9FF81E7829C7E4BC980C9
+143AEBE1A04DC0D253396BBB7268BD5AEEA356B610D5DCEE03135E00AE34388251F31714A1C40E18
+2652C48CDA2211A22CB6F02490E69A44CECB169754C53B16028D352E0119F5D5FAE0BD7EA1CDA647
+12A6147374B64244E21E9EC9F0D1381AD22D5B6212B26C3F9AA5F6045F25DD9F5EB4489EA39B1945
+331AC70510C5752557DE21D0A6CFC1EB10A98FA867B76DA6E4249469F591FD154D39E89364A43DB0
+07AA0D7A911CFAE6CE2B557997FBC44F55A27F622BD7B8B10EC9F5D10F2649A646FD964AE1B111B3
+5B46A252C4DEE44E7426EB5739F24E8A390694597DB3A1FE7800C97E59558322F0E49A0CCE2AD94B
+1E2D1026AFA771723E3F523916F55ED866C9FB4A2F759651C613A2CFF362028CDF9D38F05D4C7C60
+24C533E930B64B099FB1AF04B01F5FB9CA6867E6EFF55A772C5391831059987E10CBF987E3F378E0
+1329F73D54DC0484177D3C3C06F67397955FF1CA4EF8AD1606B70455255D631A7D6EB92BFDBA14A0
+FF28B2ACE7E81AD666EA9B3A0F5A6BA3B5DFE35044FA4B3D8ED956009C60E98CC132F2E84967F4A9
+8A67B336D5EE7CAF7DD1F74D1FA08619941361FA7312CF225D89CEF97E864C8369EAFAB94D97F056
+5505D825972B754F6729596EEA91210B75DD8F645382ACE36DE60819A02B3B48DD00F5485F9264F9
+FA926D732E2C267B0BE8CA98526F124F97EFDB86132C5EF16B103908172FC51F286FFE45FF253512
+E0033F037FF182BA536A9EB2DF2D1DB257D9C86C46E1B002FB32AC70CA9462E6EB48994752CEBCE3
+9F08ABD4F4B0889283E55500702185A841E328
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+cleartomark
+%%EndResource
+%%BeginResource: font NimbusMonL-ReguObli
+%!PS-AdobeFont-1.0: NimbusMonL-ReguObli 1.05
+%%CreationDate: Wed Dec 22 1999
+% Copyright (URW)++,Copyright 1999 by (URW)++ Design & Development
+% (URW)++,Copyright 1999 by (URW)++ Design & Development
+% See the file PUBLIC (Aladdin Free Public License) for license conditions.
+% As a special exception, permission is granted to include this font
+% program in a Postscript or PDF file that consists of a document that
+% contains text to be displayed or printed using this font, regardless
+% of the conditions or license applying to the document itself.
+12 dict begin
+/FontInfo 10 dict dup begin
+/version (1.05) readonly def
+/Notice ((URW)++,Copyright 1999 by (URW)++ Design & Development. See the file PUBLIC (Aladdin Free Public License) for license conditions. As a special exception, permission is granted to include this font program in a Postscript or PDF file that consists of a document that contains text to be displayed or printed using this font, regardless of the conditions or license applying to the document itself.) readonly def
+/Copyright (Copyright (URW)++,Copyright 1999 by (URW)++ Design & Development) readonly def
+/FullName (Nimbus Mono L Regular Oblique) readonly def
+/FamilyName (Nimbus Mono L) readonly def
+/Weight (Regular) readonly def
+/ItalicAngle -12.0 def
+/isFixedPitch false def
+/UnderlinePosition -100 def
+/UnderlineThickness 50 def
+end readonly def
+/FontName /NimbusMonL-ReguObli def
+/PaintType 0 def
+/WMode 0 def
+/FontBBox {-61 -237 774 811} readonly def
+/FontType 1 def
+/FontMatrix [0.001 0.0 0.0 0.001 0.0 0.0] readonly def
+/Encoding StandardEncoding def
+/UniqueID 5020947 def
+currentdict end
+currentfile eexec
+E98D09D760A3C22CF119F9DC699A22C35B5B35ED6AA23593C76D54CABB5E942BF7D6DD84F1664B89
+699C74B472DE9F8E6DF925F6C4F204E9F1C639B4DBA988ED2AC419FF2B2BDE605B8EE3264EDD6641
+2D4F21C64AC522BDFC7C5502F9C3F3E5592B3B2093D33C9BFAEDD2D49E89AABAA832E23F062E91A2
+5032519D1868816E44B4E0747795003D7930299D6E1E2A5BFE0D595DC97E140989CE81D8D7F852FF
+9CDC7A1B1B598C69131DEE005B415805A16D8A123E6A208511C6D0C255B9A5BB2FDEDB4D399C6CF1
+94FFAC236883767C0F68F4EF84EE696B677DE704EC3B097384F2E673A1F51692B7B260693738C211
+9F7D90FFDB21EB715FD5B8134FC87DBA320EE54C2CEC6A4D6BB350555EAFF2EC4F84365CCC0802DB
+B3BD0E3F0D9F858647DD637725C2CAF9557FDF842A0DA6A0CA0F1B442EF8EE6CBF2B03858468A466
+AC5883CBBD3815B283343B39205803C02C917D06825C09E2BB14609FA32C28D720C0E14A4B12D4F1
+25FF6281FF324DA33A56FC49987AC7D3AA206540F8127273FFE9A3DACFFE2B1C269D3DB9A811578A
+C7D532C2EFC18376F473FBB2B32EF642B19CDEC1D6DE83643723E3C6DFC87F97A7007B6081894BBC
+45C955B7001EB36211B26AD7A3D07459CFB33F9C54A40A360CB802FD202C8E93D4DB888B325CE246
+D02D1220ABF55CE646DFB45F07CB848406E470362F80CE4C02D98DD845189877732744CC16C7F566
+9F77EF096EA55AFF98AA103EEAEFB971731EBF3782E6AB725D4E9E35B2968689E8007C038CF25B6A
+E69451A4731E79AC22BD268F56942A233E52D71873E83E00A1874E04D3B22E72FB2D0671AF81C698
+53C389B51F4A257373AEBF4DE2DA1E4DA5E2CA88941F81EAE0E32D982064C8AFDD7A9A600D56D736
+05B9463C6240606B3361BAF22AF74EF89AC804A5793BD512DA2D13F4BB1B73EFCA1E621ED2A65D66
+5AAD0AD228B3B7E3D90DBDB6061E172B686E92355A7C7459D83199040A368B5697DDC3B81DDAD341
+6FF4405E1096B1240EDC18A0E9985CA55A0D697972BB11E9F1BC30765D6775BB68C69704BE200EEF
+4E11B78ADDB6229D8FA49A6B1525ADADF17122C0FFF51A08AA7AED158724AC4352EBB91ED0C157E2
+4281BDC1FD610195F495E87062A8C38E0D046DA4067EE16E81BC5F87E583315B973184E474064482
+9B2A52E0D37E249BAB31988B906F891AC904D1BB8901F0673AECE60ACEDE97B8DB7935C6488ADE8D
+FD898027424AA85A11A3DA494498B084133B857017A6D507D70A3421235486EB3CF7613C59139FD4
+DCB92EADC60BB6225D9CD0599779217BDAF4813A453989B2E56903F4DBB83D83DF4837C86BB4C3D3
+CCF98F07A23EBBF7AB5687C3E1E6792E40F92A7A466DE352294064537505EEF3F9C308C9EB94506D
+B02CFAE289F10005A6E42D2DCE43731A7AE368564B2983038DAD6987F67062199018395BC0FCAF28
+7A2B040C71F7325FA1E9A9808979B2FEF19096B98B8A0A728EB98F2BA3D33B49E3C20BE992822C7A
+1BCCA5B4E4D1099D456D8D7D83C57ECBA0FF21428024F7572A1470317CB8CBC8679A974E13D88C68
+1338C68C9AC9557F97784F4E1C8C2E61F26023ACF46232CBBDF3C0BCC5583B935FE9FA09A562129A
+8927AE73988DB0F7E733C6561CA7C9716DCA9B88208A715166F2FAE6D5EFF289A9B2EDCE813403A4
+16F243F1B57EEDE7D81E10C2DA4065A3082BC92A38B2457368EEC9C3C17296CB09819E9E642D7365
+F9A6EF430FC7DD611EA5FDBDEDFA72634AB599EB666A5DC178B0A0BD1FAB042792115EF3B6222C12
+41DCE36CB38B738F68B1B3CB489FED9E53315553F3C5C3BBCE40451E47B7EA53FD3D3ABA6CE0AD22
+5DAEE734BDFA3BF1D81C1B42C6D856A05D0924E03F7627C5EB24D7FBEA3BD85716207F961B56803D
+BE046E81ED5FDC378F9CA52C14FD8544CA7C539201BEE06487EBDC30FF3B28E8264EC7FD5DA7E080
+65B0A9147344CE28DA5182335875E9F8B2347A44E33DFAA167232A5C3E69E8C5B58B7C7216537827
+C936F5741B87FC68753EB0D4A466961D0050DB59DF3195BD3379F5647F8CFED35DA952D7CF2DED45
+EB442DBFE992711D22EB228BDDF36B8D7DBA27062D60D2271EA8E8412F4290B58F5BE26FF06F0559
+872F9DE4DEAABA015EAB4904BA1F509F6D517C6E897312DDD571D769BC474FD378AF4360E8B1F103
+AA75F48721B9E0BA589319E15D74AC0B03D730C3EF708C7C504787483F134EA6297097B46D2680FF
+8AA50B7A255563C88D594B912F5574564A1371463674793E4834AF11D14C7991E7FDB3A6ABF8529E
+1A4F10CAE79C60D37429579093DBD041ECAF03824DF9C007E96F45595A524B27EF8774A83AEEBD3A
+7134AB4435C80944DEFF5C1CBA921B0A41B9651968581DA4834B3C0E6D4DE13C1E792FCEED26A72A
+DC4D9E3903661D8803DDB58EB2B929CE31FC9F50A694116B00AC9F3EEF53FFDB1ACA3394BF111610
+38F39917B022394C75A0D467D64B89A44E5505DED7D9C6B8BA6BA098F140C9C00E09200EB4828356
+A2D6BE9EC1D5524B09C06D9C6FCB5E2808050A339B5E5FD4DD6C2035A48FE9674520901EDCAD107F
+67AC8C8E508E6003011978D77ED225F361BC0F86A98B6120EEAFB73F7377DB1E7213E02D12C330F5
+492511B4DDE08558D75D5B8AA2D56A3111DCCD257EE96E3446EF1C76F000C8916C4CE261425ED9D1
+5B58CED128DAA6C1300466E7B152BCFB5E6FAAB2519B8A98F26B29F98133AF886A0AA7E586A090BD
+A1DC6120DBB5640885C609A8BDADEEFE5DE0DA5B75A8A29E92515E86E7E66BB29581E5AFF8CB6551
+D8D1103DF60D558E7987E6F56126A13DB2C9A04886C655064E68A0A20D1B7DE24DAD22BBFEE1B7C3
+C208D4FD6A58DE78D6A0A6126EFDEE3B1A9713DEE94069A9F0A2B392A2F391C4C75327803B53F252
+CC9EF0323F84929BA4716C50385681FF5B4ED54929821594F9026B7C1297941B178C3F8A704CE097
+60533DBC6CF4B18AFBCBAD039ECB2EBDC7838A9410E7B227924BED7123944675A5DBCA388B710F8A
+F6048B03DFB713F881EA0F3B191A5CD989EA150B979059C8AADE403855815D8F7980CE6288F47EAA
+37C1097D33F13776F08779063C5217D7408D9835AACBE5C071EA40C9AE6DF685F4A9827B828815D8
+F3A672E73A418E5CB15684EB6C6FE0998A386E124D76620446907F993BE16FE5AFCEC681F585601E
+18182EDCFD3024062A3082AF97E803C47D32229D0A24596CF7E03F18229FA631175699E2F0D60FC0
+9C4F1954C5D12D03BFB4395F0E5EB6C6877083807D91D93CA4177A6B5A8D2AA500131FCB670E7118
+73F8A3C77575EC93A3ACBA37EA117DB268CF10D04AD0F079484DB124F6DC14A50AD3B0294F7157D0
+837D8F9A6060FBCB385606066401708C041594E0396A0BE4B8B66FEA141CCE4BD29366A986ADB98D
+9A6935C49C57F8CD415E93FF8AE0DF75E463E02AAC68DF064C1B789B685F84E15E512404E065A39E
+9E8F5568A7D97671AE1602605FC7E4933975189837586FB1A55007FBB0E91382A629277C36A190BC
+85AF49EF3F0F38D4ADD2B5DEE09916B79690EC83473C63E92CF617617A66DF472A49641DA10654E3
+AD3880D060B02A4A6C75B51E4E9917A2B6D8EFDA12D59DE5A8E222DC7E82F02F23A9D3DBF637154F
+719B14114DBB102BE5EB76B441D7E9990EF6420C2E80942C8AED5A1D0B19BCE115B5929AB9E145F1
+496753DD6B1798324F5EC1D0C7F26FC3045D7BB46A14110C99BA07A45EC16002CB754C0BAE7A1A88
+EB387BB345FA70B0A38AB4D532C2DE49274D4F86F2582728A2CC54B4C09D26C0CDEB8FEE6A42885C
+6207D74953CFCC583ED82DD7C0F29D35BDAE5BB251B8A2D4B1DC97E2264DCE035E359DFBADDE84F7
+37EA6A59C23D1A64D963E635769233624F7682EA34636B595CCD064AAFF3887D916867475731BFCB
+F7F96D5E5E1FBE6AABF454C2F504EA4E8EB382911560195295C87793D5F7739AD7EC7176E126413C
+D4D1058EBD7D6EBEE14BB94A1ECF28B686411D91E07373E891F78C4C0A05D2E8D90A8AE2614F7FC2
+63A762D0F43485473A54C31726F8547701D4A38D20565ED1707847AED9C805780F062B847E668E15
+565CBA07A72B0BA99F03FB57D26FA26FF579C30EED0AAB6FEC1B5DBEA81AA88F16F0C9BE869505BE
+18C1CB79657D91D6706E2A3F0BE9920655B93EBBAE2B4D0B5DF6BE622C951F2CFA42AEDBF7AE649E
+2150FE87CDBF5C2685EF36051080BF39D864573A45AE2648AD97662B1F69787031B9BC43511FB841
+55ECDC3D91E2475D072BDE6A5207ACEA1E0D2ECB1DA8A1BC4BEEC335A5C7102963E84B97BE741C44
+58ACC3D72A7E53B1F08C955F33EDC3A0DC3E7308270C0F7FF814B111459985733C62E8863625A551
+837952F3CBF32ADCFD9F345E14B585B23ECC440775310654DAF7F41E56FF45F89701292019A94BF3
+0EB2D65E14B1A1D6BF89D4CC43187ADADF3F6E03A90ED01E5D876BD3AA56E5EE84DBAA4DAD9824DE
+9984BD45AF96FB8A56C010B3C3A3C6139D58E9D69D9109DB18561B55EAD6452497840B9AE90C749C
+155B6329716F0152A7AD52DBD0B8A25B9995E1416681F38FDBDFA443879B5C4C25AA29E0DCC07DE8
+BB161C36D76EF286EC88D57C74BF44DBCB4FEFF771D3BD82C8F4E233357C48E516EFE3DB9E60EF16
+8E2C45B54651DF9A5ACB5F1790F7929BCB16CE5E9F6A43919AD287DBC8E12D9F9E97E5DBAA592879
+1A5A02D39D259F3CE273A870906A643CC18D86E23F115D2A35DE6926053D8C84B940B362E7DB183C
+4905060316B269223DAD309EB5AC96DEBA757BEA45FA3100F77F4765334EDF3D659E09BD1A5552DA
+492BE9174DD406F8353A059ECFEE3709422940A8C369919EE1F22F7C02412C995FE93DC4559D32A3
+155DD22D3526D89B16D9ADDC30CB7ADA6E52D62C5F2DFD142D4D7B6E066671EBAD08F54917E31704
+1F410CFD8A3243F8B39459C418B7B7C6494551C6F6753A94072D09E0D812351D62916383C6E061F3
+5ED864923002007E626089772D269B298DCA2CC1F25D9BE43FD8AD62D554C16AFEB7EF6E5DDA66D0
+5A810F003CDDCFD2C02FFF02BB61344968091F67D3862C1499409ECCA137B9A2A9BE314995B818AC
+CDAE27ED4AD583BE29DDE4E8C2400C5F8152C85709AD2A4737BAC768FEB70CE81A92C9657DDDB2D0
+BCF9169D272A063C75C150ADDFCBC2F5F2503DE3D13231AA8CFB396DB38E80197A605F6BC20EFA1E
+DE40CF424CF221218D51BEACE64A3DC88377E4F3EFE43DB4F4FC0803BF61764104CFF0B618C90311
+98B094E20B0FACFB94240B438B67BA298E31D3F4E31FD190E48BFCE27B1BE29D36E765E7D295E96E
+DCE09094FAC43B87E294818FDE9363FC7DC5EA36A1497EE25762D02DFA00A9BE53F87ABE62E52ED6
+F59818FDFCA643042EC13D670DED1980413950EE43372D31AE2694B83DDA42E1FBB049F7E7B7E69C
+93FFA3195A2462423DD2C022E5141783FFA07E192AEBC5070F08B23AEC9142EED56DA74F93BDB504
+78DA55DDD0A9987FEA131E4CCA0EFC51064E4B37632728261369C3FEDACA100F1AA78FB718ECE7A9
+F56296C5FB43781E63F36B0E1D34BB748EFF35E1953941F94D1A9B0FA474FD68B47183F2AC53A63F
+9F1D30B9B89C5FE54C3765B43DB403D57994701C133E42B950D9BB1CA202F15B5E590EE75598FAE4
+3D5CF1546572770BBA9A6373F100CDC61DB4E5EBBE0A93E0E51C86005E333F69110B1C8E492F2BF2
+52CADD5B73E7D3EBB53E759353F1EF3C9B8B39C230D13AB7158A5D92EE4C452F81F6DFC18803280A
+A023832FD0DCB482CE5AF615C952BC3F7E58F6417D69775FC7C0D5B405AAC632857736ACF32B2EE0
+F2A2C0F3B3CAD483C614505BE94706322F2A2830FC5AB592907D0291ED1873377E7A6158140C2CDB
+1B0E27EEC9CA50176102200992308045CCB5A169B61EA0546778B8D280737319046716604945A21F
+2A1CB9E15E3A5DB31E0FB5A3B0AFDFDF6F3424B7536D473F9756CA3694DEE4301FB1AB1AE47128F8
+D2B461C051C1B999DBB010E78DD13AFCBBA6F7D5226D540527F17881A18F551B3EEF76A7E28B4FDD
+879381A2217EF2FF9F9982E9EA70AD2003B862D7C36D57C5FF9FBEAAB56040FEE973EFC3B34D8319
+1960010110BA10694C17B7635AE03CC1CD087C0B05522A7A791F0CA34022A3F5860B536D9551BDFD
+BF560A07F63AA4E687407E5E48584E689591F1B52671213E430A708C06A34D2E1D51CFA6B328A122
+007C81B5EB263B967746961BCFC8772F8502DD95898724ABF369B0877F3313A167F3F714023C229C
+5757D4D46FCD9B4AFECD093DCABE52B78132CE9AB6225C9A344C4BF8D96F2C50C4272CB9AA0D606F
+013B2642F8C880E08EA2822C8CF5097D2CDB64932FE195ABD5FDF36D3BE123AEDD8BA2F82A8A628D
+BE3ED6129DC0FDC4BE50D5574AE4FECC65062E70F4703BFECB35EADE196294FE173EA57938679DBA
+6D15448FF44C0D1A903B202439DA93C0B0E612110068F8079219AA89F435E44D0464F54833BEB338
+670BD820D941DF4B31F51B895BEDF833F9C43CB7616DB80F988CE72FD3C12C7D49F740CF85B4766C
+0ED398EB837695D102DEC16E24B7475A0F5DDE88FBF2D6B94F126417C811E8362B9CCC52D8891C13
+C10937AACC228D621D4712CB9DE0BAB60EDE2A97E9292BE04E42E6D3425594DF56931A61E1F96172
+6AF6E6891D63B240E6E79E5BF30C052091D681BA1102409874CFD8EDC3EE2BE331676E31AC00F807
+91D1019BB789CA4F5907F4823B002AF3581448C352BB67D80FDFFCD1C5BEEF60523330AA2C045600
+8F62DEB55E69AC2F86369FAB1ECC90D2487954E61117A90D9269A65DFBDF297EBD29C3DD1F62755F
+8F289C42A534F59650685F8576EA2FC5D26B99B8E3DCD3F1FEEC73131000F99AA9868EA9BAC0B56D
+AE2CF46DA6CC1D18C0AB8D77BECFF7B89992175CBA2E22779C13DB9DF53FF5B1C8FE95E164997D94
+202C37175E562C8622989B075CDCDE173452C064274354D5DB8F7D5A78D48AD4A103B9E47500D08E
+DC7C51C1F3CFA7F43C3686A3C24A7EB5018B0F419961564F87E212CE0A0741AC68D6822C7AB9FD68
+85F5D0B2AC249CB7F50E2353CC4B0A6A24562F564FBBC7090C3FDF1284AB0EC615E0B3FBE132F315
+70C8A65C814F93910AA4BB80D516CB70D2E1D11969238E6F022D628FA2F33A0A15C4EF0CE7F753DF
+80A8AD9494885A1B9ADAE6C38AC9DA6FB0A61696AD3A502630252AD7B574C841117D34BD20BD6581
+217D977B35F5D04E02B933E1E84F5C090F6615AF484D63265D28517BA74BEA8876FDA332A84AEA12
+E6CD82B94AE10A778CD3A216ABC08495EF319F06AD6FF8ADD237D911F846A514FDBFAA8A1EC8E0AA
+9F80F11F1CE615519A4B044F3D1CF1A17D7F3D2174222A5FFA8B39F20197FF6CAF250B6ADBDBF519
+1C525070C8D38220FB501C223F493D80F498621A02EBCCD6EFE914F16B2A435D60C0A1A453E288A5
+3D818FE1EDCA7D55A26A017F2EE47A816E90D6C3FCDF0035EEA307DFB06D2BCCE43458A67354A4ED
+B6E5C57233DE4FBE41ED07EE5EC77A5DFADC4032138DA9E1B74428CAD02A913E40152F8063A774D4
+FDD4070E4B8A6C089F199AF7C529C277E902195DB760D81EC655DFFD1BB283F3C5AA8BB58F2476BC
+797B2892E94414ABBE96D4DB93E280CF7DE23EB852E7CA954D6682A6F1A4BE0507884C2A05AC863D
+2BA73F3B54668397B6C54DC2F4183130AB414875F3C3D8792BF7E5FC4D228DF87748BF0B14178DB7
+E3FFB7891D700A1E9520D778B095DA80E4801F53442D5C073EDEB706A5DB8466FFE7E701ABA9C364
+A37169F585C883A83713A61C9C3BD9336A667EA4E3DB5F4DF6BC6A552BE8D3EF093639EC67E5FF71
+8959F9902477F5AA894ED2D1CD312ED82EE417D95C49C96671B23FB0E1738E892ADFFE62EC1C3D4C
+BEB6CD089C98DE8D247DF7ED17DFA2959D3662F105E8386D75AD308480536959F8E6CF8F2C6937B0
+9F2E8137C811327D6B165ABE46C51834A955FE8306D10033F8C2A34667F13A8BA831CCF52C7A21C1
+3DB92F3E77B55CE291F6190BB1D194A33FD73151C3F61ABD2D8A0C9BDE90E796BD996D2D0094DB2B
+E98657E751BDEEFE8A43EE4501B98F0CC6D80805189438872A60047A8CAA9039893530A3E5F6BD75
+BB466B25165737C939AFF3EA59BFF4A7DB09C2A5B36B8A1F0C6C5E5870C7C9412589877EF44F8428
+4B8A53B5B74315CE72D2EAFC631BC4CC2E5B71DC958B5A6350CB5F615C3A4502E973622E3E18193B
+69572DEF1D02303A375ED60ABA1BC8A179FAA0F221A49078FE15AE13383585FB45FF4D5F3BB3D0F6
+D8BF62E9BD6BAB3C9A7D38C8A5AB0BE57ACDADCBD02B1DC7952D73AEF702D406F62719922BEA96B8
+FDC9B879708E794891C7A0A42F2CCD6812C3F4DB030B5178E3A627C3E77621D312CE4EBE815CD387
+7208FAD92761A5396B67E835222609F823728B1C987857CFEAAE21F2AD5EA9D841212993508091A4
+A2C268BF1D8DA1C650F6AB93995E7C13A3F84DB55748C626FD09C0DA1E3325CCB0BF091E996245BF
+51EB486680162BAE63B6513C74CE83B92359938439921950D713C69324A87BCE67B45A030C9CF10A
+DFA0A82781D49FF224AC57A23C6CB321F95915C5E14E41FA852F66E1E2044A9E7B1DC3BE9E818515
+D28B2C4D2F2210098C39557067062BA4239F2AAE28816D999955910298A450741947A9A1AABCBD8A
+FF3530626089978C87DFC73618C044731B6DB8007739A9699ABC354A6F985E03C11D750B8B9E9AE0
+5436205FAAD1B895B159E2C90562B82A62EA1A7FFB501767DCE2B11C51D55A17529EF5ADF0A0EE9A
+96D0E7E89F68E50EED813836531B4B46E9071E84AA413F4135CC882CE832BF78ECFA7CAB0C9F64EB
+92C86DFCD1152BB7D4AB33831AA0C139B555967F6346068D5C3351A7A4368EEBD2933E6B9F789DAF
+37EF536FCF965C397AF1B7F98AF864B301F3F440B7ACF704B59540453678FD6C1504519481893812
+3E2F47B265EC4F5CF2172D394543D84CD4281165CBEB11349B315A85DEB2D1699507B0C8C110C726
+62EA2959C4962FF093AA5EE6F21F89B3CCB0149CEFEF1855B9A48D28BB363416C015A1F4EA1975C3
+D8807F616C5817C8162536176F464A198EBEE6C97029F15F414275A39B8219128B8C8542E9483550
+7FC2D3908BB0EC375771280B9EBE87E827811418EF93E52EF70546891BFC0FB34969FD7DEA4CE752
+4D9EEFF2B46BED908C0FB2E02EFC1D1624642EAEA1CAC1EB4841E020532E88E59AC890E6C3F44734
+B99722E9816402D1D0FDF8045C5481EC055100836EBFB48E9FBC392143032C909853C9BA38A19363
+141BED09DAF02FDF4E7CC9808321CD0708A1B45270BFFCC3A0D7C27F7E781713D5DECE82C72ED303
+86B02D14575A1A6447547ECC7FAAC1BDFF332C92984758E242256C054656CDD2C45D46E67AEC6F83
+9F95D74E222A6EAE12EFAAB723A7C816D4E42D4ED2725A794743F67597F3DB8CCDDE45BAABC25726
+B851E02E56341EBE69E4D91F2A233583EC816F18A1DECBDA4AB69320F55E730617360FCFB8AC2D2B
+737675B406297F7F8C4BC370CB084C22BFEC5FEF02E9AB290282F7B153F0A4B1AE569F1E52371A43
+46A748DDE09336CAD1F5337FC3D7CF0677091E59480AB15021E023E356B0E1BAC6C6471AD53625C7
+0206C338536F4D0D40733AB217E2297F86B593717C61458B6C93A16027CC886A8CFDC01EF19C34C9
+A608B95A84B6A2E31454BC03C10FA55CDCB7B1EB7DC16AC1E93981A46DECD7E7F00638DCAC568744
+69A2D9B45CBC81398727E4ED3DB5DB31965F358D8179CBF934EE2C4D652C9CC211807F070C80E3A8
+222B4C31FFEC8DFB9EE07A94C973462254BC1B1581903EE6F9AD91524A787129A63FCE048B45BBE6
+855826750C586B6B23B805FEC3E7AAAC079576949A06F422FC2C826BDB78AE96135E9E2C20C2B2EF
+F6171D610B2EB8635ACAB7C5C5ED9C9FFC26CD54D2FD4CB9E4294E178CECA1E16CC8E3FC06518BD1
+6F4D63AE2B435753538834CDD9D8AE7DE624006CE688938031336351A6578C304C2E5480A3FCB43A
+8BEE4953DABC30558B7790C6E7A6F0F9FFA557C50417407AC6A0DDA1E736F7070BC89455FC293453
+3DB004AA9070734C8C2608A07330E421A0220DAB99F8A77489132F6413ADB9EA637F3B75948050E6
+67276A55BEB09D4153DC126BBDBE0DB9298AC799A943D72AFB769BFA1488D311BEB86A907EC9385A
+AE4F77835DFFE4389E3D9ADED1B08BBC2B1ED6084B3D1074A326CCBF38E06BD026919107BD03BD9C
+30470DB779508DFE0DC82DFFD2DED749E872EB7EB9DDF509D5319865070DD76846C34E4E43691AF4
+29AA40DB4BF2CDD50B275589987D8081F7C5A0461AA5D1455A660178A94A0BA0DCB69C3CEBF5EE04
+26D6534F6F919D9795AD6A0E1A1F452AF3B4CB2EA54D6011FA809132421D111EFC51174E223AB6A1
+3596411A9723079231B050CEDAE7659CF168C39AEA9C6902C2CD37D25492CEE00096EDD63DC7643B
+667FDFDE5B595DC54F0A72C2650E1E46990584C78A5CEF9BFC3C5F88CFB0C49CD6CADD9DBA675177
+D601927D75C6902B55AAED0E9E3CB52A577C887D581B3CE6201A1C77C9546CEE5A13B92963337F17
+070E2BF9F5C5E86B84225863874618AA50F4DE855DE567BF2AB7163944ED43DBD7F4BBC0E1623180
+7C43DCB47B2EB694E6FEDCFBE26194D2D9943A1BFE32AA1E5305F5E341EA021F91532162978DD1B8
+C5295A5E7551E2DEE46DC2347C6B32197AF430AF3BB676A53BCA9BD1EA88678377DC0A9A86E2AB6D
+E29E3E261BFD5573C66FB5687BA9C0544D894A759866B066E1DB5C66E60AE071CC3A1C4AE40197CD
+E4EC723F7B80137619DEDC99AF57A5497D6E03C1C9E672E74F48F6C213A3CFACF2699CAE72345A51
+C71C1D69348DE5BC5F443EC0EADE1E76A8A33066922CF3869E3C1D26A3B34E540DC08EA4DA2DDE3E
+EB17C16790DA4EF1A3A76D71D34B788A87838BF2A5A3DB8176F9C097D2320050A79EA6C4A94926DA
+11ABCDCD26DBA09FD33F30AEED977E8B5AD928F3967F607628859429DCB4ECEC7DA3411BE35A0385
+1017B535985632639D378CDCD13B00FE537A49FD9EB6DF1E3AAF5C41EBE35721FA6833C2FE08AA3C
+FFC3477E7FCEBF9EF9F4DAE62FF78F319481C3F1E72999C8A493EC6EE295316B58A5CD62FFAB62C8
+96E521B678342F04BCE1613CF7F6778CBF5227BA20504500D743270771953ACBD5C6586432F3FA6C
+0987BAD33B88BC6C15D29C4B3CC54A9DD72A2357AA5BAEB2CB057CDCE72DC80CC98C62B16AC50B4C
+6A7641379B766CDDF990DBB2FC7F9CDBBA755B6E3DEA438FD6699C30A99A8B3178E6D613AA938120
+835E517431D28114BCA1AB745C11FE6E52ADB82B9D3D53A33BCC49740C93017D9531ECF43831359C
+5C93CB0E926DB440B139E3125CC2E069B1CF6D96EF68407F32DB517242C3AE0BC6723E560B0F45FC
+7F87A5E44E1751C8B7F9F669C24AD5CF16F84FB03BA121B86B0694234D8F2C9C947269AF96FCA08A
+78F736E4E04ACEA44C5BAAFDE360FCD8BA6A59724CA86160A5527FD564468123D302DB45173C1B21
+6B01DC5B6D3415B13FBDBBD3121A5493374B3357EFB131CABFE5087AA1D2C7472B0377066B3632C8
+2073C6A846285CC953A8F28E131CF587B35217EE498D9A1DB57B063CE068DAF55D8CC1771C0C3099
+9CA4FDC5D67BE4E7E69418F6334BC6149000821B89A7437CCDF9A6A0ED702D5968F1E04F7E4FE9FE
+C9D1E994885CB624035BBC5426CB8EDF0456828F8EEE75BE491B45FAC192A405EBA25CAA4F4C66C0
+DC234D7B417628DA5276C08260BE512B2432256C401A66E3B583E69D23E9FD278CD5F2178544D054
+16B9B4F61A88A4728AF2CEED07C08E207F31D644E8E3BA1E4E2F9D8E30936BCB9C6AEB54E37DB46B
+D64F2ECC1021336D0564DF0F18E5A6B6BA470233D8D41FDD9D1079706EA685B6D8A740570BFB78E3
+984BB155C3155C69BCCCB41CB51975EEA1C1B4294CB546CFB03DC31BF86EC3BCB1977E8F94A771CA
+B09DE12A82F1D6C791FA7800E5A21DF81C9C8FCDA78622ABE75B54AEEA747AA4F26D563200992E33
+7231A430137C720A17D44F3AD6CFFE63B2DE12D3184BD3E151F955786B8DDCCCB290C42718F3A219
+1759DF76371C2FC177544A6C425CAB14AAAB31628A9CF9D71B5257AFF0D59843989CF0D747375A26
+DC9ED29B66AC2147DA0168306C48C2484C70CA92F33C0C138F92F276F5EAF5EA3082A8A1CB12DB66
+1633C2F71E3B69918F509060AC949FCD52C36498A2ABB77D139DF1EB33E3B846A7C1BBDCEF5DEECA
+4EF0AD250CEA9C2751E13EF7681E8FAE0491CFA6C144DBAC1FC39D39E76EB12D3EE9CA159AA77D27
+94F0C433345B135BA632F544082BBDC9471E9FA3AED3A7D465AB7158E8AC97F68B1FBC8D368E2350
+45C18EFCCADEE98778D894D96301F903283C5AE355A863BB0DC5809158F7E108662D04A5C1234915
+E7BD5B4C30F9EFA55E702E54F87FCA06FB321507BC57A1E55CC117E21AA4E3A4DFB77C1A949EFE36
+6D93F2BD827EF8CC16D387CA82AC039F77FE995BE6D9AEFC87F8D809E90C1017803BCFA1C737DAD5
+F1A631EBE6894AD20C70791665E7BC71F21C2C3F4462F60FDE75C8A377CF49BE99314663C6ECB538
+B1BF021B2F2174D2B22CF6FAD115EB0ECE8A2E64097A5FB0A2AF666E1EE13276AEC59FD0C9D4BFF2
+3F71E835984E5EEEE36490C54E077AD7355DBC98BDD37DF29B3DDF8C55480B7349C4D17322418705
+796A8C521FFF920DD11773FC44FC631C7D6E9B420D7965D7F62EC7385F2BE30A51E2D796483134F8
+40AEC71FA19ED1272C27F98F2CDC9C7E54DAB585AC1703ED08F5F9E825564902EFD08EDF99DFD494
+44C21FA6BE16CB8A1B6D0C8A5ABF80A50BB8D055483176FD0AA07EBAEAD88FD694F96FEBD60751E5
+C4D8F9BC747D4F4030BCDF9B0370B7A5E0A6923FF60DEA16EF47F886F10CCEE6956ECF41A21F7C59
+6F3BC78299A9657266807E01762B2B2878E551914CA312C2A68D34CD91E4F5115EA1FBE801346E14
+AE529049089B6B0273E258785773A9CE8E4B6C4211CB7C2767319576758F811CBAF3A3FFB41B3130
+6C49F3798B698A47BFA2E3CA0251C4D90C0B02ACA28C611744526906791D9E157E54CE4E1BCF5B68
+6990BA8AB7897D624EF00EAB92CBAC255AE9177DA9F0D86447D35B452CD2F337147B5D3EBBF2B952
+35778A72914EB3707EA78294B3A3BC4ACB19FE87C72AA1D982E4B822F07B115CADF4D3E7EE3D1BA7
+08653BEC6F0A352A0C33252ED0630E7274961896D461EE8BF523D5911BAC1C8AC763E5FB11FDD217
+4E1F129675969C195476C7A5E18A81BF9A11ED9F2336D5301E3BD32174ED5C933E8C85D6272EA218
+52A6F7E2AAB174E0965F73E0EF89E906BAFB181DBCF8B1F5AA0C12D12C6272753C016AFEC2EC9F95
+41B8757874D6F2E061ABBE8B29281677246305B3C41E90418426C575BAA216CEE3C5EC29B2FDEE1C
+77C14FDF940792F48A56AE80AA33E370B037CB28A7373F882022AF378F26B6006A049FD3B35074A8
+65C97D153352ACC156992C00DE26AD21C982C71F0EDCFEB61593BB40FA5F2CEBF23C4FF34A4F4BDB
+73CA273C269242D1C6117262B7C47771F2619FE5710855134A80FA8F92BB2425CF88940CA3450F81
+234ABF2B11775929B12CFF86442B2AA0F4243D324A5983E5D1829775B3C7A111D5622D1C4E2B2A2F
+982FC8A95F789881416DCB34950A393F4F1720D2212F3D343A17683060182355DE9E4718506D76C9
+184F8DAC55788D7E603CFAF4907DDE965A49C323DFF425FE88C09AA4A4D16283F9B14AB9EF1BB885
+A954034710B4A9DA4C88A8A0932B18D139A687303EE562EC9F656F12F3E8F27DAA9C75DB0FA946FD
+0E1A982BB58E040BFC0A49A4AD8CD668493FCB573C849EC5474049A693CBEBD4D79AC7515047CC34
+7A9A7570C90861F3ECFB57B9F53AB9C0D6B05C8C570A8F3C04D58555A45524C98FF091B8F8A422F2
+E0E9E5A7B7FF69F1CEFC13E42F1CA276BCD584516D266BA6838D5E9CA9E9854F50C7D92CAED61AAC
+AF758A7C7BE59C3BAA82BF32B691ACA3E8EB171E08AD22C39FBE586A54E6E4DE2CD86B31138546BB
+8DA5834B2C6E4838547A1B67E651964E43988C8036931088904BBB589CA901E7EBBC094C0DA81E09
+1915D9E46828AD8596FD0FCA39FF12A6C27A359337F973809E81B2E9E3D43B3146F2516667E607FF
+EB9AC80FC95A7B7D4DED551FEE0F3561C70DB2D69ABA96673E39E3397F1C3F8FE5F48BAB8AD6E0ED
+8901F90F6CFF24E80CB5DCAC498506C4D01033E497C1241E413B022227A3264DA68BC3F91B35781F
+A2D018475C199F43CBA7D3A0D5697B45321BAD2C394B207136E1E16B41794975E8903EF2B2E1C33F
+87CF72C325C11EC0B92FD3890ACDF60B521DA32596763BDFCDCA837ADC6F26F129B23CA32F9CD39B
+33E64576970DF3C05B8DCA4BFE2F17E6C5678B84D69494F1DBA9FE0446AE6AFEAA1FF245C07916C7
+B7569E6267C42B459435A1D116CEC665B311E404171774C0ACC8DDE96B0D9167C8CC7D99C4240559
+2D745C4428755500EB4719340D2FC6BC215B67823F69FA949C08B5EC985D7AA87C9AC1F9BCC8994C
+6CBCE6027B7D1E0C22A83A5DE61DBA05D4AF6884C95F46BA7F253E0B2337E312916E163CAF9DB2EC
+56C5425990FE73EE53E42B3BCCA1CF642F02B0C5ABD529B568E9ADFF865B9DC190240AD78AD226ED
+884BED3C285B4CB0E3929E805C67F1318D186504D92085764B70DE6AB5AB6990F181BDA50FC31262
+348D980EC76608CF08176C2502E065AC2D8EA5CF9E2D44E2B70A7DDC7B922047C471DF8A0B2087D1
+106B5BD8A830EC0E53223CE3C96EF56E5541191167860EEA58D696EC357EC55799438C90156BBF2B
+13A0D5C9EE93227746654ED73EA5B9CAB61DAC5BC690F89C87FECAF9AD03BD39E438F43B81D39E07
+E0422F94E8B096AB38C88BC2E1A043811D8141C1A35DD3A6DBE41620E83C8ED3A379CD80D4F9BC30
+41BB44B933DACA7C5D4427AE94A176829F24B5968B713431CB8BD9F53080832C6B784CEA9B515687
+F121983EB9D9C9CE8BD4FA3BEC48AFE64E643B7BD86D8383D07521FE5D091392BE124CCC91113604
+3824B686988E7C83AEBF406D2DA88FD952D0FA9327F4AD04C55FEDBFBFA76ECAE8A176C516479AE1
+467125B7EB3C9E7C5B103BC0C470946346DF271F8EE19DF7E3FF7478C35EE059297F4BF21A5C7B95
+993BE6202E897776952A7ED0613A5CACAFA731FFC633CAB62963150E86EDAC796026CE02EB235B9F
+7A54E0B0C5281567138A612BAFE409A818C216DA8EAC5EDF9D1E3A1E3514AE50735A111B4D2AA083
+4EC6C11E290D58FF340F82F0E079F1C7B3566F2336EAA45BF72BCF88569988DB5F65D4C1E59B50F3
+41E45A899656A0B522847ED567B49CD5284FE50E5F8652CDAC1C076804F2B2185F6A51ED19DD4941
+2E65A0D2DBC844B75E2DF71B009776D9F97A4C6F786EFFEB87A307FB6B912BB659DC2BCC6D509A9F
+BDE87DE8D716040A8551B6CCFB7743978AD992D14D2B85CA052E87326138DB196C24593F8F7ECD6F
+486F85D1666B9DE2ACA6C7900044EE369D223524664A2790B773F9EA26E0A4CDFD709942A44298B8
+249506EB9B77BC887DC0EF947DDDC7CB3CFC6B48F060DBF032A11884E6C226D9D447A5A458CBA325
+D57E144C6DC295262763E7BB8FF6A0CA473EB7661C12E0E8E23EA37E8AB3387B9E54686F3E57765D
+4067E521BC1AFAE52394227793C737C19208803F2F2DA920B553E2AAF94EB992AB17E31B58C15CC4
+AA8A1B444DF5B3E7CD937CF03E1F7FAC63342731B4589F16939D16E8E497A74CDE5686F529E9495E
+1603D74875288CF53271DB9313A4511B104F80B179FCF213558970A002E945281BF3AE51E668DD6D
+13D9E85152747F562CA0B75DDEC8FE9FE31F8D05B0F59E802888A7A4F19B29954A31108D2F041367
+DEBD6AA1CAD856BDD1427E9EFE89956FE28D500CDC6A0CB80A76902A08D0BC6705583243F1DD8020
+749B257EDF4803BCAA653F7FD6D8B91690995BA5EA3EE92FCD367C11601C6B8ADCEDCE67B16C596C
+5D200693AC5FA15D4CC6CE9DF7A71C8A925E99F5085313D60FAD25C1BBAAD28D4AC2B69062D68F39
+0530A976319A3904CEE44DC9451E441AAB4780425440F8C499B81460B5D3E268974145117ED843B1
+71BB14AA84C3A084A7D8E07B9979260675D5CE6534DC176DDB60DDE90F6A3674F67462EF78195F8D
+FF74FB5882B079DEE31FE92816F16CE1A70D07752EA25FAF5000ADF79BBE7D17EB1BD2F9BF6CDBB6
+F078CAF97986442680A8FC4121866F9CE86C385DE34E30D8B9768A0136D9EEF79A4B38EE99CBB9A4
+D32316564C9D56996E2595753EA71BEF684834FD030D38BB100E2332B026B046316A53270A96DAB2
+182E994E91262FB03D1AFFBAD623F1689228409884F91DBA153030870A7BEB2C7EE2DEC51875B137
+33B7929041F8D23A94904BD54DD4BC9B432DD0C78DD81639F46D686FFAD39AAFBD1B6C1A37E248CE
+48F23E12464D5379B4AED0D50B5A41577E6ECB75270E9AD3EA7D0FC09DAB271FB18B51DCFC0069F1
+5D72546E6C51049F3425AD005F88FD7F02042DABE9F097F9D6A076B30D8CD777B1EC12BD163FDABA
+5972EAA61E3C87E9AC007A052B1A3FFE14D7D43C7A0ADC89B1DD4CB4F9C762A84A6C0701494B2D8C
+4E4E1A9245738BE4111805C2F153A20ED9FECF2DCF4C8F7C3BAF84D60454A7403D4F5F81C6404173
+A7BA81BB0CEAECFD493D877465DC5735D43E3102CEC57B8A589182FC65A4704661A9E351FCCBC731
+5A87E62F65D24EEB9CEE979C6E10DBCF5C162ADB926EC8CC9BFFE381F6B8A3AC0A19D1631BEA2938
+731AFC99E8EAA39BC75DDB3A39D01AD8F0BC1838F4D674B9BEE9F6F7BE4D9C8BD97E8D171EFF330C
+15B76614A1FFD25B3BE19E4A201BCC850F926ED51616318C965AD2F0E56F9433B1247C6D5B72EDF3
+D408A3E0674A509BF30BE813A5E669D72B978794683CA8B85E3469EACB167C30F7666DB5E081B81E
+E99ECFBC1704B9646B1A29E4A4CE5654CA8409ADD60145DFC54225BDB8485E39CC98CBC3F38FD0A7
+97E5DFC2099452A2418C6636BD2D5F6B24345ACFA65F4E7DBD2D0AA0C1776A4920B4466C509BB5BC
+7D6627946C4DCB38A27098B7B5BEEDC2B3BA18F927077F71E38644597719652037621BB350BB5369
+DCCC073954026E6438FD8393DDB3630C4473F06D9FB9E422E435566C396B12FDCD5605DFEA232171
+CD8EF298786806E9159B84599C26D4C7D8C3BB064665CDD072E2083190372AA808B2268B3FEC8878
+B6420CA829BCF995DC20E067EE6B8E44D2869D51BA3AEDD1763F7F8D2CFB8EC41E6E9E0129DE5343
+1457960CC51D546B10B8B6CE08A1C2B79FBA448DF9783D815608A16C55E589DCD8EF6B04C66232F4
+7A473973A35618000D79B8173258B7365C9691DDFE47B16EEB08B28F881828B946FB5D6FE10ECC6A
+FC4EA1F762E90B3320403382E42AF4885B183AA48DB5E4DFC9A54E0B4FFBF7C26EB17A4F13B4BB93
+12234434FFF05549E7587BA0373ACB3E31418BFAF400D8938FC6466B94273D1735306AB912AAB13E
+31DA3541C1733E2A7E4DA5B82767D37F3084AA7A7C488CDCA7ABEF77D19E42B4448ABBD346E9BC28
+8ABC4540C0A1CFD0BF46C5BC7454B25E27E9906A3E6CBF678BFECAD1B19B4E42398A210CD567EC35
+FB115D5C0DF0EEECE593982056B0E1D14C292F70B3E049984F8881C8B477956AD3140B4AA22256DA
+AC0D11C4126808B5B9F922BCC5F24A77FF352E2C621A3941AC07A20E550A69C49B1B87D116EE6F2F
+970918F0F1A501166AC4423FC212E4EC8039AC7F9C212D864F418CBB92948FBD588228108FAC1AD1
+837070512305C110F0FC3FAFE6E1529C2BD0DDE868A9EBE5137DFDFC5C12A3D08014BF0EE27B1080
+02AAD6B607F5C5C0F1B1EED3C552919C9A2E97204A8127F97B1066607ECFB47BA95EF2B51F007C29
+3B2F6A63041A9C1120D9CFCD5357222E5B02DFC73CF94CF9B5CB00EAF073E9BF253E30E09B50341E
+57BF245A746EA31BFFD0B00201C34CF0881BBD1006BC9BA7D420A48E53686B598BEDB3449924EBA5
+8D5DB1B1B01AE2BA281D5758C99EFE38ADCE18F7B182FBD0D0622A6EA497A4E7C00C7D17299A2765
+EFD8DE376C214D01A21819451FC04A0277EC84A151FF93903D61C78AB7886911E36E12526ED855AB
+43F6289C1890222602B8EFBF15782B374AC1E580B6E963403D6D15A051DB8558F2E61C0B9476C6DE
+5D4861585CF515CE951732F20D32969F39192FBF1690D242AC04D47E0C53D467D0FE4656B9526C0F
+7F852348B0437737CB0F29ECF9B54A5E17185236DD0C16349C3496F3ABA569EA20E343F6D771210C
+39DC932DC65ECEF94575C6E76902CDF6C8C8361F9C757A2577DA535187FD526699917CFE0AD438C2
+A758727B306BC7979547E68B94E87ED820614BDBC649D469EF6B4E4E3DD2EAEB5F80B22FE576CED2
+56495467C76A75F589460061E03F3A1B065121A5ABE3E2C51148B3DDC9F624C97889AAF7FB84B158
+C015EDA5670746C6359D27B0C2BD65144F2B88A64331816DA904572BE398E015A9924218B3EEF951
+23AABFC3AC8217B7B4F691219A1C9DD0A3EDD5C04E63ACBDE71B423522532561F4B71B7028415C34
+37E346BE728A415596AB749015C1D59BD8328E39A850CB98085B34B57FB52DD1D154F98FEC49B3AE
+BFCB1672762E4D2A1ECF02787F59DF1EBF2625C3631BED849B298C6D226BE4E6EA2AB66A287D2BA9
+2A6C9C612A5F849B3CB3C25F17164BE286F6E4F5E7E4C9EB17BC68AA5EF0190B64696A570442E1D9
+BDD1A30E7692524E30E4B4C3DF84481DCEC6E10E7308E65DE9D90099F3FABB3F4F766BB86CC98594
+6D2003E21287761A7386CD8461615B570BDA015F5EFA23D18E83C325EE444EC166A1A32D9818C2A6
+5A092D44156C06D3FD079B92450B8A491CBB3529DDAC7D95AFE8EAF33777FBB265FEB8A4B9AFF2CE
+CEFFF49AFBDCF6C4197497D3B448866D70EF28D8E4B17E7CE95F43F64BB48C4A73EB84B26650F62D
+3E5199D64DB0B5B87702650ED0B850FD5D16C848D096E4C7E61BC63B2A3ECFC099CD713E12C91A65
+77A88D6F55D348617C7A49890A86EA8FE2045704B5ED529DB128C9B19EE129E5FE6498CC97087F6B
+DE96007C9D01CE9CAF75646E5A5B32BFEAD9362A52223D746943A2D09C536CFAF78E601BC2D2F0B7
+63AD722E3A7AE7069D65F9F2BDED7278511D0120F5EA071D41A69F8C2A2D720D3B24B4BE61C83FFB
+EFFAE21B0560A6FD1A44E53E42E0D10E0E93F421A8A7E167BB65F0D7F1DDE2809FA3CDFD931CCC69
+B119C83238C1C00EC100D8E7AB1C7FB02EDE97073C8A5860371A8132BE391EB1C397B61F93876FEB
+438C288EF2E38DDCD182A5CFBBA994A94A1BF818312CD8234215FCCD7C240A15AC01A885E1179E5D
+7D6305DC2F534BAA141F25EA6A5F356486E5FA0AE3C6980A9F5E8E99E7AE5B95AC42977510970245
+4FC951E4319AE4B1DDC9B07D0998372C0A95ABA6985A4DBE6DC633154FAA30ACE689D36A7F17011B
+F29CEDC58A6692A8B3B0A5742E6CEC2F69B255BCEDA762DEE72F125EBA98891CFF4D88AAC14188A1
+8D81424979C9079E44890D94EE094D4CADDC1C7AC5F6791FAB8849CC0240A579ABD800EFE3AA4EE2
+F78119A3C2806C05C2B1F17940BE73984982D1C0065433A9BD658EA31AC819DA9A11B87475BB565C
+C294B6F302FE3F7752ED9B963C5279B5F1196762D0E12E6DA46FF9A0CADE3876D7DF695D8965CB4B
+47B351FA3F759811269376B2C3134403633FDE27C9B024F6BA81F3E1699CF64A426618428BA6C326
+6BF016C5DAA5FA4CC82FB6DC23FF2D742160518CD3A65ADB38E53F1067076CA1625466E0C64670A1
+564A54CE14DC5C57D24A12283FBCBFFD0FD594AC2A56EE58B552F7586825E4FB1EC23F8221711692
+C8C56F42272B87EBFF3865191F1C11943BB76D8C0CFC53ED452AE49404D2C8193ECC2A7BB8CFBF24
+870ABA38D2CCF7869E9363DC0AD94FACAED5922B324DC3B6FE83E7B34FE29ABC1EAD62B49FFBCB81
+1ADBB5148D5AC2743E3A058386036FADAB6FF071BC1C3B8023F908B6FF48DB0AB1C9C67487C35211
+D40995E1892C8B66AD6C9C6203F6F8B513B11117B10DA8725AB45B4437B5A88A96AF3178D856D601
+196E8162868A83DA64E408FDDEBD14D6591881EA652032CF2F88B3FD6C0479C8F89AC68D14D01AF0
+CEAFD95AD146E68FAE01A07F39E7A0C5E4FFA6D6A91D710827CA5ACFE7D1F946A8D7B67621D60F53
+41F32C12A6EFB03AE5AC5373A382C044A276F6B41C173D0AAAAE0C1DE4C3CC71EC2637225CCBFBD4
+5EAB92BF39357C57195B410F74283585B12B926438AC72AFADAAD2D0FA2CCA728C8E86BD3FE75D47
+B8BEB96AB13B5480F7A3D5741EB51E3E40C21FF2ED7D9221D9877C7D1A8CECF394E4023FCF8C4EFD
+B38B839499FF5CD96A46AB4FDB46F35D3B48B91757C0159328120E93CF1F2739E936E28908FB1947
+1D3AD7F6F1AD2BD1EC364986A411CC1B547D0CA104FBC10B1CA7B638A60E75485574034561DB345D
+DA68415146AAC632DFA34769B6ED7D7D4694E92CBFF4EFB16B55495908102E85E827FC623CF1BBE6
+A13CBF64E878E1A2A159948B5529B75E071744A5F0E50DF18C110B0AF117CE7F33F8C959D4C98CED
+5A9D492AE6F56DA57B0F17495DACB130660BCEFB064FD8309D965ABE8D2BE98F6898C1B7A39CBBE3
+E75DA0FFEF6CC3945CE76DA3BE915546FE8A5310130AE0ACAA9AB73C7E041C00533B4BC7724657AA
+649B9388B791AAC5EABFCDDDEA2CC67A0FD0AE9BE37DF9AD40636538EE55A83F60E9E026C64FBD8B
+220CEB46E67410144A520FCEACA252E8165448F84D8EA083C793AD09B90B3EE83B73FEFC3365C729
+E3C738894B8C01C2F8AEE0CC8B114E1175EFB44CC4C6CEF5C8754B1CC7CEC200AD8BF1189D741CB7
+5BCA4E88BE959E32216AD33F674F49AB20A354CF3969F1611A95D3934E148831AE7C81A7EBE3C524
+4F743E66A82E10D16CC09F8194EA7A596BC5981D833318AB4F7DBF2ABCE543E410B649D18D146F01
+486159683DF61A3F880F9B21EBFAB77E908C6CFC79F89BA5F51114F0BF7C3CCEC7BF0F3B057C3195
+CFBA6908E31E0DF10DF69163C9DA7BABC00E9A580FA7FAC202910615BD479BBF76FB8068630D1EC2
+1CD2926D351E869E16C2CF1E023CF04D4FC61607DAEFEEEDFF5593E6023492F00029E2AE4B4A2C14
+50954EFA2792F32B4934A768F892171245A1E2F034E2B9F39833F1B331A19A386BAACFEC8C929BA6
+B67CD8922BBC9DC005EC3976575D5B0508D0717C6BF11123EA36D8FD37FA77A6F1F5AA84D4AD8D25
+B2C11D1877A6E2F9B74F3B5829FAEFD4F7209CE9785AA6FDE68672554A6F29D8BF03FE108ED90A7F
+58690FAC399A8AD3A26899072B832874DDB629581A51B3325CD9EDFD49E890EA8959DB937DAB83C7
+77F2A426B967AF5888C33A3635B78D647AD6BA441E222C958EA58D61945F781D7EF409771B89B202
+42AD7D07C2EF592CBF413C5FC89EC30FC9EBEE4BC63709AE33B65EE3091CECBE610B847E12C556A2
+79C8B114C3E460822D3330ADFD72BD69F54C08A81848C2002A08326CF3B09B1305490D35AEE59179
+08E1604ECE75BBE811A715AE8AF7EA9C371B322D0428EDF4C893FDEA607E70E1B6F6614947326101
+EAEF18E29BE0557D2A92CF1FC1505E8B434BC368CE07CCAABC0774F8A63E1073FBBCEB3F4052462A
+A9008A1E53F188C9EAE339FABA74AFD6D60F47282CD9FF721F64BD51787F3C13B5A6C5A5F7861171
+0111F5E0471E206D72520F1DFA465F4A23C71DCF99A04CEEF11B0E3BDFC35B7461A60753D3AC26DC
+50A5956C9195A4F5226388E0953DDD03AF128A98F03BDFA0602CBBAA20AB9ECCDF7255962A332E16
+D4380762E498FDA4885C64FF5F9B480DA487C58E78943DF62616E6E2C69EEC8836DFCFA9EBF58938
+A878F3E792E8BD8C5D6DF557A5D82018DBAE1CA9C64BA5AF8E21BE1B6680FC5DB22422220B776E9B
+A0BF1ED2B7212F8BF111EC8C8C77B223C05EB5E5F1CFABD2D037F4BA0F9503E2CD83F4519D180476
+63F09E308883F5DA5228F83045FF41214D2273B2FE0A9017D5E0557BC2A198C35D1E7E81F7965444
+5760CBA1D3F05EA4B90658E53FDF0823BDB1501ED51DA75C47395073D8980D1E3504E3F67DB3259E
+4EE73A87CFD96F84E221796573958D364A51E635FC55478C9CBF9AEA16B7D8C25F2115CFE4B7F598
+54E24968833BA0D64D1D332A666DFA2A3FD71B05A26BAB7DA382907B13DE0B80871DF184D3622B62
+3D7E09BC32A4F6EA2E6DA450A906EAD36D53FDEC7F83E101FEF32F4FAEC581B000686D86A0D3861C
+1E67F18A4C4647F51F978484D9E3100B37BE9D20AE84C085461C1FBF929C669E936659050C2627AC
+1B019837BAA75757F5B0A82E8AE9CF2111931A38BFC94744E2FDE3F8710342AC615286E4ACE7F269
+743AA05463AF537D9416230ECCA859D8C99B7C6E70BE7FE11DB698589BE9E11900C8E9582A4EF5EA
+94B5F62820C90DBC022A620EC536E06CB8BE7526A789996D0E741AAD980880A33800A6FE92286CCD
+02C9CB407EB31FB95D9C9F4AFF38B37087AC582C1F7B64A7C3D2202BDD62E9AEB31BCA85C4CF323F
+03DA9D318B91F78FDC0D266630F7444ED068B55C05461C97552366A82C2E743CEC353D51028FDCF5
+403B3B74D379B82EB69C4380ED40239E15A86B2E5C860891E26781CC111FB5705E3B7C7AF1946006
+54B5FA1B5FC54FD0BA43666E7BABD2C91C859F393ED49F7123EDFB648A3D6152F2C17F7E438C0A63
+8968AC06B4FB3F77F64F358AE063820BD33F0213C85C40E4D97ED100EC2DA1C2E1EA258BF107AF67
+5A9D995F60BFA37222B9C2B325C0052BB8537D2B27DD43A129C7E8FF42757B3AC9B447703D382108
+DA520B8B3BB3E8C7295B776B44ED28F863B8E1F81B0BD1DAEE8A171525D09D2620C04DD3219D880C
+2ECC79282DD7B1772A9CBBCA706909AE8BC7798E6EC7375189B6CFCE8A875849176E5913B85A18FB
+197A33CA4B5B4058603CF1FA79A56856B43D538E9ECE117D99AFA73B57E307364F553644DE01EDB4
+6234EFAC13046B6E047ECC8F63942F20097AD7ACF0A45C0501A95263DE9439A880D6B5C5214D2918
+0A54D7FE9B2E627EF49E189B59FCC78745E878E45B46C0A648955D3EA8C935113D94F92EC963F66C
+F3CF3A526BA71CDF3CD4CA69EFAB08B7389E3390716892A4872BD29DC1E0889A42D7FFB4190E9A8D
+05D84EB9C5741BE6B02716BC75E0106F5F94BD3778BE985E03860D27E44088C3CB2A059DEBC420DC
+E3A8F4087A9548485E616C409AC400DD1C411CE4B6A229D091B253EB68F06E43511EC5AA6ECA4D6E
+4818D6AA2068DA1AEFCA377611BFA816B5215182432D5683294D67A7C1FD76C52233087CA44943EC
+7280005E93145F5E7AE50100C18364E1B36741E9647C4DC1F68A58EC44095920FDCF05532F603717
+80F78420077EF5C24D63E26040CDDFF8DFD65D871DB943F50CDE84900C1372EF33FD8AB9889C82F9
+4F61A0E6842219A0F39EC7B232CBF802C4A744F33159432E827006C7CA77E480A48A9B0E6A876158
+8A3102E3F98A77BBD62A3A23150FD140D3941773BF7CBBA2338FF37B9EB640558A2313E8824E8E62
+0331568A9B76F4897198A709F9313F4AC40827D8C3A71F2ABFF02BFD57D30D0B14012FB5C39B85AF
+540DDA0ADC27A85B31694E8D7B61F9D9B476571022D98F2D768246550A877293F3FF6ED918A498D6
+A600223E1A61890C49ACFB60265867CE9464F9C32C59E94F7641C3873FB4FA6EB237F8ED94579957
+270D6FD640BD9543E683F2372CCD7B60AAD269E03A72C5CDB732B128818D41A6DDD2BC139F7D3911
+F48E1B1D263DD4AE8E4CE1A686F3A00A2CBF48978631CD243566E22E68F8D7397134A3530EA3745E
+4F1EACB4D6A5FD84C3011094F37573F7F9902305020C53926716D4780C6B0A257BF711AD94C83F1D
+41A02C1C7DD203A3E6E4B14EDA2FDBB36B063A3E074495F626B0EEA146D22AC33457F44F41675967
+6D2A0566EC2B726D2F0540ABF225339F02F406D4E7A62E5233DDF20AE7C86CA0CDD561F33C422654
+BF2DC3685CA91BB9D4B09AC8B15A24A99FF56E2894F11F7BB4728FE8F0F5B799F74F475D2D01F61B
+7E9E0E541F7FEB8A557486D7DF2CE50927515D833BCAA1CD9BF7A650BEE9E003A5951C98ED147C4C
+52F64F692AB281984EE65A47E44A4A5FA93D6F18D276D3B01C5E5F6135AC6940524CD713DF4077FB
+4943E8AC927A68489EA52ACF7A854393CD027EB52EA2DC6234EF034F3DC742D6DB5A67FC21D22B97
+146B9C268BA97C30161CE01EDC69A6A1F05EFB0E06F22644E1A368F0E2C0C6C1C832878E0614B74B
+D645F5CB293CFDB7618B837FFF14A1210AA061C8C81867244305B80DAA73CB25A417228E9559E7BD
+52C119B0CCDB7C4DCE7E1B9F7E8EBBCB575E5BD213BDD6DB88769DACB05E5870232F0EF82F448559
+187423409EEF756BA6247493BE24CB1879B5DD822E03D0ADEA1EDBDD83D3FC46759C679B921F0616
+F27212903F728AB44C1784E8A7DCED0DF5625A7D3F48A20FCA34008184CECD145CCD98E31B79E174
+CF107E8F35C40C19D86B40BAEE6164353408801EDF75A619FFC5B6FAF3F3A95F64795CC40C1F8963
+4FD8C13852D265FBCEF834C800AB46E3E8167476B23CDD8AFF6E2F997C99A86A9CB30EF8C853154D
+0D89EEE9B9CDC1B4F27BDA32432A4173B55CA8D9FB50ACB2D886AD8E5862FFD5DFF224BA13C8B8A5
+4A7F1A9F987FBBDBC5A3C3D762A5BE309D5D926AE5093C40AA47B3B1BD828797CBB9BC9FEC9D19EE
+A73D2A39764816113A8EDC6CFA6E605AD578FC8E30ABD600658A49ABCD5AC54655D29C50FDB72070
+169D1B389F114B7C71EF95A80D82AB537AC8C165D47371FC142A51625029A990A577EB1618480D72
+6DA93C98E5C5F24F622A850CDD94BADAEA91D4BC32CD50CE69E9F00E77DEA8EC1D37916398FB7092
+402605359DF08AFE7B99C76C2A7C70383F28A7C000C696F45291BB8F074791798197CAFF1544C76C
+EEA8C9E6D76EDCBD92A86DF889481F3BBFF0865442264F0EA40D3CAA69AE467A08003F9C30FF7F2B
+77E767580575398462D5B1171DD441D8986F33BC7BDA17D413EBB6B7A32642E33F20B284BF3EDED0
+02352FC66C6F7741A542155F4A159CD778BE56B9492CD95115C1A06189A216CFD2E6725965A13DE9
+73765A05114D9A5A4BE0615AF8BF6A5EAFF84468B849954D15BEAE1CDD57C435788B331905C01421
+B50F20B184506A0BEF746330BC98E9C89AAA8F9D102F158043BEB6A682059A1C8B8CF67B2F3D7AF4
+D8BBE086254CDE53765E3226BA2F95AE8063649F9F94BD9519411DAF8A0287307335668190638806
+E29484A4FFBC1E46B1800E03B162C23B1DC0B4C0DD3C7ABED2F00762972EF06EEB9BCDC7B3F39C70
+BE32789D366F073AC3280C273DFF2979507671B3E1E7685A9A4F0FD3867F96DD675BF05F25ED986A
+79249B75F182FD73CDA2A6A66D693E4CC5AFE3402431B2C816DA1486C34BC9DCA4E2D51C868688A7
+787CD10ABB9ACA14B7181369DE89913CD8FAB58FC84519EA2AA14E54B7A8CE474F213E07CF2DE2E8
+88093DEEC937526816B71C96ED75FA9E2EDC0F9E6E84569C12BB8E39AAEDBF546630745553D6084F
+F9524FEC6A7264F88CEB7EC3358E923B392474E3A48865564431662988FEA768CE555AB0DA48BD52
+6A84B0CB17B4584066C1640C1023D91F7869EF0C4D701BE121A6E3C832010427490758AED7A2B30D
+6028F2215AA44E86D852FDC67DA5CCBA79EEA863BAC9EDC2535B66AB0E54EC4D4411390FDEB8D1FB
+C1743F15C3B68DC92A8659E7A892D5E53872EA51EE8CA7EF51103E87C29A2714E907C79DB9CF3744
+1785D2F73A1EE58550111A4D9BCCBEBF2E39CD3B93DCA300FAC3ED1ADD8215301E5766C30C8CF296
+75746C5A77BF1FE3CD75D25CF193DE8D9AF02AF8F7A6E8F84B548058CDD3C6998ED13463FADE7391
+26D83D3CE2C7201F955382832E32C10DCBCCA35835985B9A93F8E3B0208BE6E92428787C47D3808A
+0F77B8F1D76E6BF6A17FF81CDB065180E03809D03638307BD7BF5CEDBF64904E918FC805AC905379
+928B816480F6E3BDEE47042CBA98539DA0E113B1A5F23EAF1A3210BD18561985E6436EAB90395DA4
+77C7A6D7888D2377B3FC4169368357D880CE041E1F7C875E956600DB7D9B35D1EE66BE476E9DD806
+4CC02230276829C2C0A098F051502E828A0CC505AFD8C3DF293DA1508AC4D25866BEEE6BBD5A230E
+9C2DCDD4F06883936381F476DDCD86CCFE15C2CE3C3243E148CBE603B8513A7CE7A6910A66A90B70
+89E5CCD4368BEFFF2BCF8E918BFE0A1B069AB2A914CA7BB91A0AC3B3C0B060FA1A0316F6135E890E
+E549315897C8464496CC6DEA0F7E3AF43FFA4C3281156067582CA255B1D2E80F999A3AC0402BBD17
+01824C3BB524130F5B82A45275807BC2F3A0655EA208F968B297F98C369192C8ACA26BEBA7DC4506
+FBD1305E2EFA4DBE5375281A88EE2D6FC88FC0A755E72934B4B58F6DD3BDAF7171A4A3C776576735
+2492BFA9A7758504750AB7F38754683B70E9E293CB1CD7B23BA62BD7397ABB84D7EDB22EF6C3F58B
+3EEAF656E361747ED04020163253D1CF3F905B5E85F83FFF30AB2778CAE43781667C0F65C8FD404D
+6B9202A99EA76AF9AE1236631550B66B063847180B6DCA832EA8DC4A6EFDB674B5A26552A7C7D54C
+2799C7D4E03C24F661A91103086DE3A90A774A6988347656344CFBA06065AB22476BB09FB68F9928
+C0045F2764AF643CFEF0516D87FDE6DBF93BAE2829B176CB507BB99835E01BAD5E55C2F8798C93FA
+35EB3FEF02CFA31D3D21B030547F86D27B9448D68E2B155A65C742BD2999DAA0C3AED64447B9CC67
+F7AF33B63AFAF25F3CF7EF86657FE8F952288CA4B691D369E8F1935CDA44A180A6767560C2ED3F2F
+CC38B6BD7991D4170C7C566D690A8A25BE03212A80871108D18CCEFF246623E653107631F29227D6
+4754B2208D19F84E547799E691CA473780DDD56AE620CD953D5133D135E3D51F237078FEEBB73714
+54EE633CFE238AEA63F9999E32850E6C197687A0EC4E5908D2A18C5349627E336AB5E3185B218228
+603A4B1852069F5EE849D571B8387DCE1F8F8E9FE94FADEF128BA83BDD245F8C1C27C11F2ED1A8AB
+2D6D601726842CEE744EE7AAC6B6FA16CCAA39DBF5B3B1D47339F31DFA562671A9CF7DDE6915FEF9
+F19B3E068A464DD350A3AD146D1A241673B5112A4A8768F976723E6E184790C0604506C46591BEF2
+106C40789B733331A80740D59ABED39868F80BECC2AA21C400A0BD0CC326D186FFF9EB37680F1EDC
+32AC78F9059280D07B5FF2E354FED545129FA5FA8F3D4317FF21E027602FDB2522F049BB545FF4DA
+60248130F81F4E348373142F3148DED038AFBA818F26D5B49FC02DE9800D894E9239C88EE0EDE431
+F8083697CB0BE3B497473473E5714717C914A1A926730C249413FEA2615EF72BDB0906933387A892
+370F77EEBF62D26CD583EE643B02E323821379C0DC966407D36AE3CDF646B95DEDC7D7FD0F28E950
+78F12DFC0D6400B327B743C548A0A3517A175A7ED963ED756B1E107AE7087E2446BA702CD4E26E2D
+CDC1A8B697108B5B5E81E9F03105F220C72D4AEBC57665887C8C7964089FBE9424120EFDB14D76EE
+F8C6F7A30B13E1AE90CB9D93D2E14BDE47F4A1D05ED5B18D32AA39911B92D24C93976ACEB7EF597A
+75161923A73B2CC761785493D0EEDC08B5AFE95F3C006B41438A0785C962B070DE2BD096CB63B847
+C87539880AA3D3FC5C345E0992D7BE77C6CFF4948617FDDA784CC55652192B0ED775129C4EA4245A
+41BCF3875BE319DA0EE2DAFEFAE920CD2B6C6C2001762F88C0C5C05053025C0349DB17104360FCE1
+5D7F3A8E30ED13155A74FAF91DC77B8AABDD6FBD5A1EAF255DB209D7F2B90822296B5603FB5E2CC9
+5CBC5F7A6044058B8044ADCE73ACFD896177F1F70EAD2F6534DC3AD755AB2BA87126D63CA2E9C441
+DF0965BDDD6BE494E58D6B5057A561D1E31BD38E92CB73C1465AF6B9C001F7229059BCA4104847D1
+639E124E082F7364B56548BF8112D0EB461B316B2449049F6A476D36D6B7C0C1126C08F2E9A1246A
+3B5B21E7C8FAC6E23B82E33A7783E4F31F0240E96E69C9444E7D7A928636CFD086475DF1E0A28464
+81387BB2010655B9F81A0744121699B4905AAEDCC84BC5D5AB3674601DBBB651EDE7B5DF05C8A463
+DAB41F79706D285C4F9063997F7AC8CEF35CAD51FBE5F5BB1B3FA6DA2C3ABF2B3E925581349728D6
+DA0D59C1EF6444539742EE9A23A5727F20CF9377F4F84DEA420607015A30FB14632D084A2DD181BB
+02FC3A84FC499B318156B675B9CA3CCABD87FDB2497C6705FA70EBA43ADDB6CF961B30E8F6AB9F84
+E1DD8D6DB3314B34B7F7AA3BBE19D5BDC75ECADFD8EAE19E07B387A1FC586F0F30DB695926764B54
+0D89F1D854B0FF86528AD9523CAF56371E29498C11AFB2F4D5202670C834E930103F039D13348824
+16A49BF93B84FD3CF1209EEF7D4994C8302436C0794497461C11F5B8BA152BACBCC08AF8A15F4A4D
+F3EFFB7227CA97FC21D2D0356C93390C749CBE9750B821F1A7BCFAE2C8BC6D9A27F844D8AD088320
+79ABF0EAD8ECD4EA72846DFEED021857F33C1ACE4C07BEC90398B629814C498D33BEB375B9A53DA0
+F926FE6E89E70322C72CB2DDBFB16B13EF7A4F50DF783316584C6AC2BD7D9029124933133B2229BF
+74A228868AB30EA5C3E87C78C3F0962199480DBCADBEF53BDDE45849DA857A4FD85B96682F1EDEB8
+5384929DEE4AFAF84C51A09F5D572705673D885070303FDB47DC898F874E103A9E7C1E894115DFDD
+AD81549C7375D4AEDCCE2E52C13E5130B47F206F7C5AFAF1F9EE83DA8188D70B473269CA280A6A02
+DE85300B93D8A4F6B402FB5DF58F1327470CE11CC63ECEF2EFAA396A6680A6746A20382D9529B58E
+7CE684B39AC00F7086BCB47C2230DF0343BED9B9152A61C9826AEF9E00A1452D91305CF05490D4BC
+0BADC9C6FCBFA93FAD52C3A80705A1956890497557C0873EBDCF61CCDD2219354A4F5621AB33B119
+32065C1D990A9B68858331EE7875CAC855F98563B14EF9E1060BEA90F195AFFF94728AE935453438
+DAB35123D0E2699475884DDAFC7307A5CC06920F35341728D85965F5BA86F261CFFCB1E29B429F97
+6970D42D10E6AF6C4B792B4384122AEF2448E22A58D3AA007743C71324EA08D06819FED14AC1F22A
+4F0BE4787BC8738E1CEF240677571C65804ED3E748D72E89C94B6F310BE748FAEA31EE246859CAF7
+A1EA17CCB5B246C87EAB771E2AC5D378650191081514DDC2C66878E3766CB20DC49F630F2743A7FA
+ECBE9DBE9E815A3CB57DADF2BFF5EF2FCE23A56298A30A2E052FEAEFBD698101F9DB992613706693
+CB0EFAF6F60C8BB5E7D0A50B3392B9831EF3A304A846CD4AF431E9F018FCD3A5B16387552D55DAEA
+683D36257418AAA0E7BF8A03ED7BAB114D7C15119E6C71C1946BD7903C1C42E115E954619051B853
+BF05AE316E15E619A7DEE498F771E809D9435969C1056402725EF40C0200E083F3EC6E0EC27B8ED3
+8DFE32EA0E5E156AC36C4BB9AC5ED111A11678339703F1B9299345AEB1F251FCEFA11FB3101CC499
+907DC862B4463D5523B9B25C5B69F70AB6B29CFC1DF1ECAB8227EB3ED1F882E90B12080EE003714D
+403EC43B7B54491446B6A3DD6EB641EFBFEF060C45E873E7398025B1CB7065441F1753028F6F8C49
+A96801C0D598E098EADC96A21117F817B6FD6E6947642F93E22425A00E8F6B592AD50B317B69C0F9
+4047386A45E5EBC9504FE55451A01EB29DDF9A41D4BAD85FC84CE280971E834F06CEF49C8C20ED2C
+EAC889F158CB14A8C070900478804CFF1D1637CC880C81AA287D8382837FFA8F41FF3C9DF2F22CB2
+0044C171E4815D0D0F6C22D19A52114E780CECD71DAF63427782E85E463DCB333789F496340E8CFF
+885A9D9A4250118B439C71C6BE51A9338BE29251AA794EDC67DEEC6337FA63CA9B03C1C9F75E733A
+4A918646E7BC9792486CB5A4BCC5F84FBABDFE338C3792254A3EEA3D88903C2C47B91E076259DCCC
+8BD3DCA90ECCC832C09C45141C6242026BFE309029A562C3EE0FCCDCD40E5CF265ED9C3DE582884E
+0E14819DB98B3AF734B1B3276AC41D43384EBE73003D15CE39FFCC04109583390E470F431B4407F9
+8550E138F96C4564B494E5480F47C853BDD237E27301F55E42A3BED18FADA152572B7B465A581DBF
+E7DB2619365CF16D71BF8F091862B9FCF04BF8D0859A76F46E7B5712F2757EDCE332D3213B8A30AC
+2CE7D7797EEF6F30904906B0805DFA7CA36D32A20D989858497A66CE72491393DD79332003D55C09
+5A5AB5DF761C4BE5C041FA8407263D604E53091F7B6B15496245DBBEE96A63F10FC2978D99E65731
+28689366FE8B0BADA48B50185B861BAD03E3600F22BAD4274F2542B635F6C7944BEFC3BC741BDEF1
+1A8DD659038CB40FEF2E16AD1AE7EBEDB7D9BA15FDCF26355331505A386DD7399FB999535D6061EA
+BC61DD76EF3EB457446F29D0BB6EC2FC0AABAC20B27A3C123C27BC27A76336D0A0A6D456DA070367
+4D959A4AFE428E2206A511BFC80039ECD56E75F69786DA0A8084D81A66644DD98B6018681F1D70AD
+E09BD9BF3D16D68DD5D0A03AE26DCF1552549E459FE190B310A8776B2C8468C14CA8B1B9A7AF2956
+507A3B705AD75A17A0EEA7FE089273353CECD07BB8563465EC8DECA0EB42F43FE3664EB5F31E1D13
+24185539B28D508BCD065ED576D8814ED3FD637D576F027927162344AFB0255A91FFC616948E4E35
+8867E9FC76A9AFFACAEBFFE110808C1532A2BBB0DBEF3F010E45FFC73F228D28F12E98478B27397D
+8F456781ED9E19711DF2E9EECBC3FE61F7493FDF1A59124668A91BE51F122F93DCA4BBD22DEEA339
+E6EDA3D6EBEE03DF958113E1CA49C8398D2C59DA6764882EE3663F62A55AE50A7E91B4FEAD1B11FE
+0D50ACCC5D75F1A515F0C53616A500F1491381DFD0E2477E402AB0CF9F67D501A442629C8593ED5D
+25A72EDB9746B02F2B0F0759CC9CDCB4C9D8B4519C8C617E569B432F0CF6890372AA879CA7DE46E1
+10D95E230A4F0E52CF65811C54365DF4A3E40D819E2FD379B47DA3233D0DEF0EFBCE04AD8BAA3888
+4F6A69FE5C373E38AE0FD0241480F2BE7CCD18AF85916D2703A049779FE7398FC47D348454CF03F2
+2EB3FECC064606957898B5643464845445C25C0C7D685C8DB042AF5D5882174374ACE90081C68678
+9BCA96AC602EB41D317BD652293EE628951875641661EC86A2C40A42E8F0813A861D41A0F5178E55
+43651CA0E99150462DB5EE0010F00DE6D55B0D7FD7EC5BAEA24ED3E90A7D6A0589761922B91A6A91
+3A7FEDDD3B68254D89ECF767CE8E27F966426A8B4FB1B4085384FD09D63E288405B78A646F44C87E
+EE22C8596B13188085479F75F63D3D97A28F9C8306FD207DBFD38DEDF0FFEB7DD80B2A3292DFBF1E
+D605ADF1B33E85B010309E3EC058FCD922B1325FEE71EFF2DBBC2E68DB52D513E024C01D47CF657B
+B61C9734649A4AB63C0AF4720EC3EFCD82DD3CA6E80BB63BCF1B8DE810A0C6C517C63B76FE68C0B2
+86867BE102424FC31C4937048B6F323D039618586FC21731005D949E7D802A430DF8D2F0CE99F2A2
+376C2953EFC4184355E4D12F422C9E1E25C4DF38DEA334DBC89B540E14C61A7769D77115CE8968FB
+76B27D0863CEA2496783114C24D4CC816DA884D953DA3F9B9D3AF8938BC607BF26A071956CA07E6A
+5509EA2F5D80E5CBEB98041B197FAC760976EE75B470DC20AA023BA3F63C2876EB281FF5173BB490
+D6815604517AA1B1FA0631401B3C1A04CA103E2CA4ECCD83874D9CFC8ABC134CC0F9141D9AFA5684
+8BF222342016C556C14B3482482DCE5D0B6EF1AB522AA1812BDD8DD3397E05327EC12748FC480842
+9B97202E24E1DE0C7C0D272C046BA73B37D30930C5DE5A47D96955CB0F5DED8F3AD929A8B42D2839
+0458F5910A0F93610F79EDDB27078943DFE17C716D65F96589769349F3B66AB7B8C004CCC59EF688
+1F745EC7129865A76F9C2D029D4660CCFB4D5F9D412BA3372A27CB175E9D65F759575CF14A5899A8
+D31FF039AC02DBD8391C3397428AC0D5717C005200790785354813C8859BE90E0E17914F6CB9C674
+F1E9A9648657B54E5E1F52756C4F982DF74E73F6E4D40718C71D1D0E2420FB7462FEC9E457C0414A
+96E475C6BE2C10437096FCA0C942E995A9ADA789AB637B648781D32DFB68E62E91C2CE7E13680F8D
+31ECF8C824885FA7618981CD05FB335AA111B409C59EE337DF4E5F9DCC920A5FC0D620DC07F20DAD
+63F4FF5E0EE5A2F390AF1C32122BA7780F210229E5A5E3ED97BC1C3CDDDD456E739CA782EDBF4B81
+0552368E9C734B0C78B0B8E3F8B2DD782862B74318871BB1EF087828CC173D7B049811FCF598B8EF
+DE4D9BC5447F4848C98029C854F3AE461B9D46DDAD8CE67A521F3C811A81A396CB0F80F3C8D8EC88
+30532FB7F9624F7CAE0F8C6DF875073333DEB28AAA90AAF486AB8C932553CE697B885E71EC8E40C7
+835CD5D59A2C695DB9E51216FF9B77A15B0DA63717FF25B05B939E45CF7FBE490E51E9344213B32E
+115C2DE14D76DFD5845088DE645B0E75042A61D82FB1753C445AD0A956A1263E5A096B681D3BC51A
+9FF32EBAFFF7ECA8B59D40F0937EEFF38312AE57462C7BF3B1FE24D2BA8DFE84515270E09063CE3C
+80DF4935E409F62EB4F54AF16A186D4329972B9BDF15FB08461B688ED49928429226CAD9F67C9D63
+6D1375CBB7B08A5631956B7FE29CC9EFA8D75C9E4919C8C2C54F401D2E0D7BFBA40C50CAE214D210
+C6F3EA5802339F63FC4C1C1995787617F3EC2C806CE44CF8E29F76606CD5836F6E5A2E423CD791BE
+CD3F112F25657DFED9366FC4ADF90B685CCE4A5698E5FE16D7542B913FBC01B288DD13F43DB2B1ED
+8CCB80159DBDC90A8132125DF8DF547C4851CA609D1F6F4D647741260E845B457937787827A89E37
+CDA06BB191669AC84B8608EAE132D10177F3FC384980F3A6E439B048A38D0D6B9CEF09F3F2D732AA
+71BD058169D6D0F8C9D146D9DA046774027559A8B3843F6116B418427E78476AD8F0F81E8A6B1209
+8060FF7DD686503F972D6C42FD6CC29C083AC3D72E3751F21D2E44A572EEC80E81EE44C90FAA7AFA
+BCD3ECEB98FD4068F6C3A4DED0E6CEC523C9A0054D1FC2A8D61A4A26F9BC250B8F302416924AB22E
+722297888B85B9C12F8DFD2A744CBD143F9B2514C1CBE988D9CB4E77D90B2EFD5C2A528355A35F7C
+4AF039C7D1D756305967B847D4ACBB81263D4992C001E2A262B9FEE2D1F5022BE5B15E1D8F1D67BC
+52227344EE912C018CB73E5F47CED54FD202627777BB77AACF3EE6B22706FB2FA9062BEE87E22CD2
+802E7706322648DAA0C624EA885430175F746E1F536F9A8E1C610C4A761D07248426DB63C9319A88
+A3FA449C3FB8AC94C6003C745E6BAD717A3B2EA3862D1E08512A98E57772A62F85F1E2FFBA40E2EE
+43AEC11203DA9CE5AFBF673436F2DB6AF85BBE89D802F7A9E5FA25A408DB69E51F0577DD26F94CF2
+BA2FC53EDDD6FBEB534AF15F74F66EF8D14E7FF77D8A5D284C8202DD5A6053CEAA606BF925992382
+5EF4EFFAA8D878652A4CAF2EE43ED26BF3590402686C876F86C1AE95046E527617CDD3C429BD4CC3
+F9654D2C76DD4102471FF746FA9FA379B16DF96BFE3836D43FCC0B8E95120C27370049ACA4AC313E
+1D50D72D1814F2566B8B29FA9C9C20D0488743722A766436776783B939171FFFA00E04805A8B5821
+4D4F114F7B9C3C17CE7486AEA2BCC895ECDE809502BDE57981318A93F23016F056A421B733C4590E
+34AB08BB348DA4A48F19B6BEFAA1DDD2A49A6C440443028333CDD48C85CD698ADAF3FD8676739E44
+400A98B575BE02350576F96CFA54D4184BA47555B8D12374B86D038D085F7FA51FF4BE2FF5981408
+999B48B2FAF305212ED54B2E371F5A0074CF68D1B0E5CD279BBC8BBAEF694A89A6C43F518D01BB4E
+8402AADF34E96E9B3FCCAB4CBEA2741D3FD9ADF7AF32388F7771845AF99965A6078F4DA335EFA436
+BE36903E33A743C112C0267309F266DD44FA998C9A139704E400B89DAB952EECFE2AC09C82D9F497
+5371CCC27DA37890EC84123193314D8A7A707C217FFC951A547EE5B6D1B7C8ED85BEBD9D3F4B9B09
+6A78E5F7DF88C931E3F396973974454E59340CA51DBFEA1A00DE084B64630E26C6D6A3593B828814
+E27DB0186BF2A87EEF268AA1B135AC09B52CFE53051CBCC88CEC5657BD47F603C8E1A6249161684F
+D9084AC279F57A4F9BBD0A546A87E147B62AC860911969A29B8AA20E3AAAD0079D64E6BF1B0F2CE8
+F0C54C9019207E1B403358253C2FA93A662F63B9380B65C5173C198D86A3D0DC1800D1F5378DA39C
+E8523EB62C6AFAD8A0D7AD1629F2CECAD82B8FDE38975303768C7D3A08B91478EDB3C45A8C6B7725
+EA8596A8ED50B8355FB852FB8966479D12E1086223B1E6523A65FBA81DD106FE254F7309718768AB
+009FF7714A8C363B09DDA73CD3F81BF9C0CD3B0C806CF3B7BBFAB73E46FACAD2480EEBA97AE68EC9
+4D3D79AA01ECC22067858EFFA9D7B7F997ABD2CE5AAA8781E5499E8580C405681CC63EEA53BB47E5
+5ECC5BA2A7A3C5472DF034B022F455C60FFF971B01583A29E211A87F7163187B190B0C1083D696B5
+86E9438FD8BAA45101A5EDCD1BE5AB9A585511089DDAC8DF1B1FDBE582ABD945E67F99ADC4452988
+A9859E39C90EF794C5C4E62997085B7A16A0D90107D08610BA175AD66377345662DA7DA4D8FEF847
+EE5D57E3AC54B928A0957CC1C944E7FF14658FE4A641CD26C61105C0F136A75950764B69CA17509E
+3C19351D456B22C87C55E8DCC4ACD3E150D936333FF36499AD6B02B6403DE0F12901301ECB2EBA10
+324BA72B58206A13B8F37B0AEB12115D0C12879C8EA8A2EB70E85C95434564BA3DFF481C8972587E
+FF74EEBBBAB14FB32B8A84B8FC42EBECA65D25E8C32C19CA5962832BF45DFDA4E871508AEC318495
+0D6DBE89019CEA29E40484C36E33D76B756255531ADD1DB24C03B2A64A47BD8FBA3FDCB1F5B96F8E
+ECB60D5834AB001A70740498720AFB6EC03445CC35B51F7987109618C6C78CBE3041BEDC69B6FB12
+8142CEC5C8683B558AFE3024EFF7A12D04EF59A72E156DF11D33ABA08A8EEB16259DD9529CD003AD
+4EF4137B6FF1654236473DFB93F597331A5E26C7796F528F65C94FE07B3B4F4DD49034FA0CC189DF
+CDFF70C2F1C6D3DF30AE103E2AC5CFF20664AB934CE5C19693292071C93BD590383E0A1931E04D1D
+DD18071DAFB628F5D7472E457BF81D6064EDFA8DEBFF91701C5038CB30865D6122076A336732DBCD
+B0A625548773D0013648A76F07BBDC9C16284D158EC7A105AE37A62279419C3A2F360D0C7A74D6FD
+D0E36DCA2A8BD59945A4196598F690878F84C894852C1811AFEA4BE3B9F6A5219E6628C66669DBD8
+FA9A0CFC2DDE7716A356FC4FB271D8A2CDDC8D4684DE447355BC7A287DC56852A638C5777826EB6E
+B72FACCC86F80BEDDD0D649A883CFEEF4D74750172A90B5DD8252592FCFE19FFAAD868E99562DAEA
+E70514F5DE296EF7B57E6F193737ABB6AA317956584423817E11664A67389197AD9F8F771EA59551
+98C9EE40A0761639E638CE9D890DF468642670235F1373D3AC6B1F43B5777FC0A91A96E095E89BB9
+FD62614DE456CE7AFD6B855112367573FD9FCBBD4A4F9C676E672D62DDD34A9BFE8311B6175A003C
+D143C0DF15E4C0B48C735404086E48AEED6B6FA21FD9F40B84215DFF287F0677904E2DDFDA774A40
+19DF45CC877F553E95A1C65DF1D67BC0C60E0BBA4D205C0DA3DA80229FDD71859F65AD04506B308C
+2B783839F31CFE4425263224F08C5C7E98A2C9D3DC8EA5AC1920F4E395413262E0836BC019A092A0
+DECA104EB2DF6B63392AE8E2136379140DE5FC98B0B69860FE8E31DAB5C5DF7807D19BEA34AC14E0
+ABC6F6519C51247B104DE7D912C5BF6EF11B48FC6DF84512E9F5FEBB48F72FF1B722BDC3BB2E835B
+2E7CC6324BEE84893996B8DC2D4DC2793A4F69C18E63DAF04A7BB5C0A9076E2D5A343E134CC3C89C
+4712900656FFC202E1988526D80C7FD9281FE47FBA8AB5D025E63A84051F6B13167BEC15B346212C
+BD051AFE7A98BE3A2491F3C469718A58E783ED91F90E274FB4978F8719E92A99A1E8F142EA7E1F2C
+46AFF0A2FB50F4D105130CE8EA309B0E480DC8F80D506172B609EA4BB4E2BBAE98D8882814FB273E
+690DA990B60A9CDA20A2418246BD10AE67D846A0FA815AC25858145ADDA106A6778A11877FE59A2A
+BE300D7DB9BBAB31CB5B960B7E4EF91D4600886D8795DC361CBDDDDE05EBD54B1941F426F7FA8399
+270D2F54C998BE92D146227270A8E89AF90C48BAFC4ECCCA01E6322AFC165743475E752F39BDAEC4
+9297290510FFA264342A0AFE2985F85DEEC66C36EB4A1D46683EE7C591A89B81569A8566AFBCA268
+10DDB0970577A76EC8A066622606B08315DB0F2E6C671F3259C73637D773D1A180AAD66ADADA2A65
+95B5F481E5F59E51CBA876FA06D21E1D674CFAB46A02D267E20234324D0891E7847C13C69BFCEEA3
+AC55F2EAF753726BCEB0DE1EECF42ADA964BF9E475953302C2FCA804B70B779482DC9319B40381E0
+9C0096460AE113C19A2DC9157FA138CF0E7758F71008E71D0F7599744D647B09B16E3C795C56EE5B
+D14D8D63E7A512900D67487975EC9CEAEF69572FC3C2342AC5D365E8A4BCF462006B5268ECC15754
+94CAD9A9E7A9E8D9AFFE49AF647C017743EC7CFD5E66F4E4D845A6BBC836849274FBD270CBF263F1
+67DF7E26BA91F21C60F96257C07523AC37A2193010E976965CBD75751E312817C0564E1C5AE0CBA8
+BD12B01122D07020A0852120680985A8AC987BC33BE863EEC52AF13435B6E4048D951F5BCE36526E
+07A8661CF2538F69D1F223BC53BF5896437D1BD46F57D9698F642F0E99C7392D8EE47134E34DCE94
+D392949B418D9821E12CAFA8337323E8469DAC24DADC6AAD4A0DADD7FF65694BA3A27964D28D8EB4
+1179458F91CD3F83B8F119BF5E76184DD29CC4C0718CF7945DCECC993A7A78739363136CEC7F2FB4
+95EEA8CEDB3EBF14373A058758C442939D36774435554851E9519B6F09C31EF26B6CD997DAFA11DA
+91FA9759F17B7079164C5B47B99CCB7A876FBAB1D0D5D1E1A2683CD6914E6B3B755939CEF1C9168D
+30B2738C4349650CF86C90D2542FC9B90F36A494C035A1C86DD716014AA16E6B9EC7AA03B16554BE
+C436511DD3097FAB1FD0CD49EDAB96F74E8FD26400FC748CBD9EE1EEAEE24DA30DB6F8734B52818B
+3A5E510AA5C14E42060898033E7E36CBA9A64042CF94A74E4B52E37AC027C0DC69BAC4944CCE12E7
+AD81AEDCE642EC34CA23E3FF07B8CD35DFF19F33C8D4DBB56A52534F8A827BE47AD4AEDCAD83B273
+38409FD1101C4DFF3F12D3DF79AD1FCE65B2F419451DD059C88BF066413E23DE27D3621DAC2DCC8F
+9F3620DAD0F4B1A6E8C9E6E8ADB552E1EB2C4B2A3B73986AD53ED9ED8911F82F750DF05CD2EBA3E1
+B0DF208A87FB5ED44C3296B803881C1D9776D13350CD29C3F716F0B5A8B8557812024BA70069BE65
+89AA579EADB1F657712DF2570843D7C5FF7F4009D4D232D3547DC8B92ED5C4DB77B76255E661FF8B
+163C6F3856DE5651B597EC7C78B84F0C6C1D6EA3A82286F1D3BB45F708D564E139E81F473C705AB2
+56346328DAA64D1EA8645DC10FD449092E0634D9D7344B2AEC3C75F6B6CD8B3F3867FF3CBB0F556B
+186EE9A7C26BD2D17C8A773055D9D5013BD2F937D697A770C57BDB36D922CB911CD14E7FA14160BE
+19C1A052E297B1A2D682D4BBC9F1D2493BCD7CAD2FA75D904C5F5479179DAF7DC6A4E0D269BACA2C
+4F2430B4C8CF1572FBDC750A05DCD5B09FA3A9CD6F2F2A386E2B3D4D8E257BD43A783B38E63BCEE5
+03EA96FF2C373181744A607F0CB8D281D7DB1A6F4076AA3E2C61914BD796EF8A0873F79F964FDE28
+B792BA99A20C3F1F5ED1FD189FB1867C84DCD6AF43D49420C8B1F3DCE7DBAE71DEB17FE45644DB24
+4F44B1011C7C768EBB7254F4DACA64E9BA87AA7CD0F0C4B2228FFB9EBDCF3DDE4DCED39399FFEB34
+8811547D025320A88B480943A339E2CD2FA3605AAAE87939B1D7901465A1879BCB4C5BE1A179E7E3
+71F1BA2E0844F88AFBAE9B78DCCA47AE8AEDF5BD3D458C7D4A7A08ACCBF880D1F1DC69C636628DF1
+EBDC5C42FF88FF8B66351F3F72D703E52F3CE91E4E00759753A599FDD863788E99858498B66B93E5
+083BC3501C39A9BA928B0D763C28826FD237E949EF0BA85CCA9AA20C405DB6D5612DB718F7B4AD31
+D253AE306E4D7CB615C59AE668D347A4E60FFF7B103F8BD0E7CBDB142A763BE88AB40EEF6B8FC200
+458D728930AD0F94FE52ACBF0657C4907CC7942710AB1FD8BD149A9C9DEF6B8DCA7DB9062AA7B1B0
+11ABB5AAE8B77893A023F9EEEED4A20FBC30F922282A7AE2F1ACFF64151013D6B8AC2EAAE58171A1
+0F80BC18C3BBB5DE1E22EBE6033BF83040629023D74CCBAB3F1923CFA4A6735E1DFA8A1B261FBF1C
+397E26F3BA9C2629CFDA84DFA3D1087EBB19DDA7E2D76E30DC2E15B8821D5291DA1DFD73940E5560
+A8A6DC91BE0075E3ED8D9E8CAC85AC20768D868CD2DC45DEADCC8B59AABE6EE5B2F891E0D7CBAE82
+0F83479332BF9707486698FE196C72EF72B52F54314329FC498171782BF160E1110A19B8208FC591
+EF0F0DA71AF657B43A7CC649A8488B759F7B69134B4F9DCF79DAEBC1CE52CC8015F324C9D46320F4
+4E1551EDA6D86139DFD1DB814CF38A22A89FABB4F75FB896B00E769820F763486E86668253CC466C
+1529A5A924CC337C48448851A381DCEF63A0A302B65203D6571A1DD1FB9DC0C3BD6AEF4891497033
+109CEB5A481BFE442249940EC54096F1D0F2436D9E60495D0ACFF967A741B30467D24AC6B0032213
+18666B951EFD45324987B10BEF4AAA0FF1DF6887377A7F70F555DFB9FF1001C67438A167A00B05D2
+C37065655173A7ED9AE342DFA1497FB1F2FED6098901249A085D31B66DBB6AC25EF16C106B0A6FF3
+47CDF66434DC3F0012DAADE80B942D522CD59AF4C31C1C062157B3D000B9CB86E2AA7B4A5BF31605
+8A0D5A148EAA2C67977FAA0966E4C3454E08DF14C2498AD76E389AF65D2C139A6D8675298C46ACEB
+7DBE6904C373C06E5F71399B2EDA0B40AB96E8BE991DDC39F92F1D24797F9EC9F2FAE25669B43754
+E2498E8EA5C44B176C3FB3E8F7A7A1481275A461F2549AFC4CC73E28417BD8C5212C13105EAB967D
+AA679AE822B9B75B372A99C7E82D6BD83AA2BA00314DA4AC51B9CAA30D80507505BE24BAD0A87C5D
+5D7336EDF60CCA4CEC8201D243C3932F74D171E2409D789AAD0D04A7BB22FB6DC3AB92AE33FFEA89
+7C484D741039F38C317EA396A0FBB9F15A27D87FCBE007558799BAB73212B6E5FAF2080BA074724E
+AC87D88166DBC1464CF5D41B99428851FF1D99246944511CF42C3F9248513E9E51593F253D89C604
+388AD7132D6A169E9DD888E020AC1F8BA606F2E1EBB97977E505D8C40853653D8F398F71CC9F8F9C
+540C22A1E6195BA578AE7262FC845FCCF77B33F33EEF266489AF8B81A615D6A13464BCA58BEC16C2
+3F31D678F14A938BEC31272DAC3CCB1B2DAE577A26BED852FC59843176A5FCFCFA0AB7FB00D2309D
+E55C82CB9049F44FA61F1E313205A76317C4CF529A4456019D970624129681F46A9CD7950B8B5C40
+61853040113C8115319E68B37F88D864C6957DF813B305D09E6A1716B10F26F2EF5C727FC77AABBA
+73E12B5AE6416AB19F6563CE14046B715BD4CB2B1E4D315F42D10F74CDEDE82BCDD524A1A5460921
+9084CF1CDABFE72CC8375478B41614BC18A914903596D6FC2F361EE519F875385F4ECB50F7053127
+4EBDEB14A5DBD906A60817246042E3799BB3AC647CDA7244B7998AE4F3BFBE5C767FD2142E48518A
+4217599E0EC2CF5E86C8C270FF8B02F949EE001D6A439BCB4BC7D7F7C8167C3AE0A7E59687FB8BF6
+F37BEAA164541B8EAFD92E9D152E3FD0F413C99CCC34FCD8AA455A0B55DEC846A5874B94FC95CFF1
+BB386B2A1E22CD1C3914264B6D5BD1746972857C9235052D77A6C0DD3019F8A307FBEE63A3EF12B0
+39B224108276FFA84021F1AC5B745C54690B3FF587B4B1710AC3533A67BCEFC503ADF1F4B62B2910
+B31965E364EEC9CC437CC40181A7320CD52BE9C546B8F1DC824312216C2FD8232E2BB8D40EE2E314
+54C09772A387F9520E331456C269F51A078E6ABD9FB6A68BFD5F557215B0BBD2227B8959CBD1BD4A
+EEAB094DD18E891C61FB00933C0A0D76174D169C0B6445D34C00DC9E06D85EB086C18F3BE27DF734
+EBB9CF078AFF6514438549CBE92A0C0D25EFE4A527D86F158B4E9D8870C7AC5D6C059643A3298079
+CC20398324CA87273B86ED801057D797D91BC3CF2F96C650EE1566CD3CF8656CC577D38B830201BE
+718DC9A494268177A5019546EEEDBF101996BE593631654B638C75A6BAA648CD1E7AA9AC1EA60F4C
+D604071C89DCCFF8B3E430A57ED6DE11C5837E78956ED991058F3646219BEAE94E4D9381A33D48CA
+9B8FF12B54A73FF869D0EEED7E098D80152295E6016CDD809173C57D1F5FCE908A37010AD4C4471A
+53451DE9B4363B63437C374C598F548F145D3D288F42531FCF36A9CDF72521F1C0868FCEEEB1857E
+A983F6B75CE245D875BEAD1BCB8819E5464518E04717B78BD6E335F0AD77B832AF5682062A1E2AC7
+7CD5EDD5DC372EE456C96D38BF8BF348DAC2B4EBBB2440F2CE97B4B337F2E23247E3E8423BFA9237
+CA6CEB6FB93F960CAD894A96F0371168A33222052DE9B3BE04B022AB95C0C243486E35197721FC55
+311DC55F87BC72D09B6C940CA36E6640AEB66C394A5949A604E7F15DCE3A008BB41B0EEF2840A357
+F348443B4DCE064B4C15E5EC52E448C985FAA1C3D6526270B1CC691009959A7620C9A6202619A19B
+E410FF7BD535A8B2640AAA459DFDCB8F2BB35112626497E8A397D4F9E04788322A738DC8907CB643
+15CF63C95809E90D06EF02F72AB04AA61FE02ECCF7E9049FF9F3EF2258A75656178AAAC9F3C2A26C
+001341862D526CC14E92A81BD63502F959066E0BCD659CB9B5A45606153DD77039B8C5D5B13565F0
+0D95A41937CF97089F3938E39659A64DC3D6046D0E9EF66544CAF8A206635DF49926A3EEF3FDBC9D
+CCEA2886EC855F1821C4B9CE1D02A19A11BBBEF43A7D4D536715548A62802F64AF30BBCBEA8C7E55
+AD56C801D8A569C8183615A78CD393CA42C103F155941E845712C335F4ACFC7807202B92A983111A
+ED241BBB8501F15560E8F2157C29752BDCDB274008137277920053D6D7DCDC626A574A82A8A34F1E
+77B2FC8CF7C1A7322F22DFCB450259EB450C52B70DF3584A7C54C813DB41E3DD81253A03B02BC252
+346AF0160716355797B6F8210C453DD7E1E756FF08C7E6A5F4F87605E1DFF35A130D79148A57B7AD
+12D94A129FE3F055CF974EBA09A2B13DEECA2E02EA818A58B81E8743004646C7746110BC61B86ADF
+2D5D8C45A6A5461EB34497FCCD09E711F47BFA742C73F87B257B53F30CB68D151424DC3C210D3E8A
+C67C2495A8236EA2D7985A5E1DEAC699D7B700E6D38EEE2E93B191BAA5A8A2C916D206C63FE63427
+AAAFED2B5784276FC21EEFF2D70E47C8540DCCC3E00134642B703795CD3702631AE2A90E063A218B
+61E5B89BBCFFF84F567E37A31A9B349717A8CDB9C9377215BA838FF7469BC486B64EF2B6D92519C0
+BF0826E3652903F40E400689F5749DF86FE3DE178E21E20EDF9053081F6510D8F19ACD021CBA481C
+484D30EAD3B84ED0190087EE478A17154B243346C3938FDD5340CF6E47B185E64ABDF44F8CBCDB82
+94492B91929BFEB9DA2B033C3ACEE554F0F1A7F8A56DF7C06A3583C1E9C5CA458D40E550FDF3E2F2
+E7BE8312D5FEE98543388EDC8A04CA29F1B82B7AB4ADABBA3F2C331EFF3521B2B92F99C4377AB827
+A989B423750D36ADDD2E286E7F3B694E29B8BC403693C6F7CAB5FE34F1E48C8D41B47831E8C3F5BE
+5ED5142E3C44ACF5180CD41FDA149B1F4AED36812E42BC184227F5034220F74F67830255E1CAEC12
+66DEFA358A87D2E3B4B4E7EF30181570D0B2B43072EE0311C2C157D32EE2BEA8EA4251B59F6B61D2
+B4FDEB654DEB67AA3DFF4AD65B727F0D6B7D61523E4B44D99BA5CD33540F340A35DDD466ABEA4E72
+E504FC9BAAE51D231C33A8CE7DC2970DE4C1FB5B096A3D9C641EF77DC9039886831DDD01C4F21E6E
+168E38BBDDA5F4308C959C7BBF36A42D042DA6862937EB20D4FA2E5927741A58DA5CBFFD9553BEFF
+BD92E6D64871D8B25D9049F4E71970A8FF5557D1DE83DD24286D6C3E4770EE00F9A1A0B0063C9999
+4AEC75E84D6F9C488434D1F3DCFD0A8BEE9ED8257CA97E75E8B1285747184D6D2228EF95D4A0B8DA
+252318ABD35C8398FC6568B294D90AB308A7675F9F160140F0A08C88AD0CA1CA2CF85E4D031CFA3B
+87635F1398EB7DBC666A259F02DB6741D13E11B230025DD6DD64C438409AF109090058151E4DFB8C
+0E9CD65935C4CC063CC6100FDE70896E23E3661C7FC1B8228B26A55903E997F80207EDD8863FA074
+EE4FF23BE585BAF708040C9F8CFDEB42FB8EB71D4CB6D7757E973E4D8C9DDD082712C23F868E1135
+ECD91250BB4335958B07C12FDA75EEB56BE19D1644C1F76A8811C021122619F751CBBFEB1D3DC912
+999017FA163672A1EF754C5CB78962BAAB76EC48461B492FA88F9897170DE857CC8374C8BAE417D4
+C78A56047024731F4A45145F0393A27CAB614A7FF747BBC28E6880D4D01C0A6CF317A1DE5BB5ADFA
+4B5FBFE0C57598C79F25AE57BB797A489D51F85A9B9CF8BEA64293F8FCC43B0D5484DF99DBE19152
+692CE756F6FBE8CE5831CF4B8A5AF47524E272C45C62ACBFBDFE7E60B05BB1A1A6AF0E9210012014
+69B3DBB49EC7B23A363FA68417B7118DCEA71D4ACA2E36F88C6DDEFB70205DF3AB7C74CF65CFD01F
+F85FAF99F172689737331D4C6CFF7A29029772F487FBF625F17BDAD89B4AC076948277B4ED687840
+301016C2B7AD4C6D02F81E88C75B7A04D724E234E38A38269351582245E361A42C75B8256AFD5624
+B558ADA2190F960A896BBAE7A8C57E76DA10DC29E69BBF3AA86214C001A27B39C1D17C548DA5601E
+86A5CF53E7B1896BF003AAE9387ABA9B102EB1E9002DD3754A378F3E49F2C6EECF47EB1BAC2CFCE1
+1AC0C5CB063672D32733563F3E1E891B6073739BC53AAA0043FC45E90E413DFBD4548DD320B681ED
+70A7443A233D79E3F038D26975586E5CDD2115AA614727B1F6DD4024B85CCCFC79D10B7B6AFA789D
+B37BD0E8C423C1A4A8681B5FF3A9FA1F61A46E46C4B1836D1AA41A89264A7F4B1C259E4B10ECDF37
+5BD26A1F412FE01FBDC03368FCAF48AA0EC28B1BD603A6A0D0DADE66D14C9B7285569230FAB76803
+35BE104305E4B748FA99FA31F23991608DFDD2097DA292551136F255051C9F7EEF3FB7C7FDB4E651
+C3D03A4CA357B587245236F4FF3252563F6BE08EF8A3EC09BE2BF27B9120F7D37801F6999EFB1C8A
+D1A08698CC59CEAE2CFCDBF6BD8F94DEC94F7EBF33AF05F52C85760C63950B455510C6AB9398D09A
+C288EFA09E8F631A59B03FBBC75BBDAFD675FFACCCF8ADF71E815A4A49F14BF70E42DB0B7347B528
+4E234C24010E2177DBBD57648E398FA6B54571A37BA8C989503594D03C6E60871A7F964599022154
+02BA168B8D1D2685F5CF8645D5E11A1769473027F42564C2966C10C0DEE1EE1B6975852A4870D492
+83A470E623337544A7CDA5C16FE2855BA2A548511FB4D4FF2E3E78D108E4C734F64EE2F12CC9562C
+BDF363EFAF5201B673AD00583FF108AFF6B68055A5F299452D176EAAFB92C84F114C8C22A05EAD65
+64A3371420EA9E646308DE97D40705E1638DF08704FC90249CBC0D2D3E884A4562CC27370B1A9738
+9D8EFD237E644A7370B8B38ED1C377F522C75F981D878A5E87101E621DF9D85C7207BBE5A87CCB60
+7F93A2E52F660E05C83A7A6CE6D01AB4B62A1EF8DA47CF97D4BBA0FA8EFFA9C0F61A325A97ADA694
+45F23AB1FE27A66C271639F839203040D44B11ECC6E805FBE88843B34C4FD52D1D3C6C70FFED433F
+C04501FC20536ABDFFA429B8DC8192B2D45DD9D646049CBF40719C3D674773F9676F9FCF32817DCB
+55402A72C56D74AA4CE4035687C730B6B44A9CC614BCA5A3FD17C170ED949E588EE45E89E18B0766
+2A6327FB9E8475C43E5DA1B0AF07C23774B19C9EF59281F5D884990D6194170D8293A86DB52A0FE1
+7E88DA82209A00A16BD29B8B2F13FD60AA25FCFA9745F57C8216283C1D6EA1C119CB9B8D57C00419
+5210FFBD56395A3EC2D3098ED38F389EFC0324FD0E55EA339B3892568229D8D3E205A821E8219FCB
+1A7713FCF3450F8BEF976CA0BECA47376A8CA73DF85B340C67EFE4534D459617996526B5E5D3D19E
+17CC5449E5EF2B82B2C4C2131FF8A19FCFE6A186A9840D872D85C40665A7A04E67EE26B8BC9206C3
+5B44C8F8A1AFC3867D96DC6D48BD45063BE25B882E9BC0D0948C18DC870E6925818E1FE17D336217
+F174EB4481F5C0ED37A3BEAFAF4D46F857811B6728BEC461AE6468D87A736572F4FF95B58B04564A
+9D3C22754587DF15495A319D822B838461764B73483C1F7CB930EECC6F7424841EE10E4087E95120
+2FE88A391375C96BEC4480328A54740213F741105B12A39F19808F3823507B88115D468C61B212A8
+ABAE7480E39BA52390A1892C7EC50271156B4E8076FC3ADA222695DF372385DA7B117A29E04CD2B8
+0A320F186D61C963FBDAFE9224E537057C49E82E405196AAB621B5FE4011E1782A747EF935ED8BB1
+1BDA39A141CC0BA42D04AE123383BC95A1D03A85A9440010C3B9613064FFECA76197E10919BA5006
+F35837ED9BCD7DE5E6D968AACB6FC91178091FA467EF6FDEB728E17293DC89DDE5A5261FAA95A2B0
+000FC750E7073900D4D88247DA464613ADC2B3903A6132D96AC0E1C564385FFBF6249DEA76BEA2A9
+9160632DD2FC2B99133E9F2F470F72B45D6F18B45020F604B06CD9174BA3805DB60EB9C5E6A9C789
+ACE76AE9C79C1BD34434E95E501BC968633AF93FF4883C6A596776254C0C74993710327086B2886B
+02FD3E42A725A03459CB36EE34A094139AF5FCF487D3DFE63FAD20BF0DFB60DEEDA2ACCA3510E963
+189D1256EABD81253F7FF9D11263FDBC1DCFDA3D1EA2E52005CE3C605C993231258A717423F64BFE
+EBC34684EFA676358B9B543C2042BEF954829FE3246A879845B30EBACB43D8DD7A20FCFEDF763AD2
+C5D20A798B69E08722DCE6A5762E249ACE3055B650D9E110599EA30DE5C4FE7200D5A8DA9E1FE268
+6350D0DF334877D0B9F6524C552D0B6DFFAE125EC4C18F7547BD51C14288E4ABB7F8A1A00458596C
+390AEEE6FA308AC1F788FAE30D7F8928AFC91D4DE6352D20B19D8D8AB122B7378CB379C5BE7E3CE2
+922FE667EA057B5D7B3F0B51C7BF0C85F87AC2F360D82C38964F4DABCC9104B32F0FB8802235E8E8
+D9A5997D392259074C00AF2CE1D2BF7B8E90E2E2AC34185C68A03BAB8B267778292B227245D7FF86
+70786E3F746F86B9D4D17190DB859A0E144B2A61E6AC9254DE5DBAEF20E2E9DB0B2FF654B996E962
+F55E465DD238BD1643CE59DC2B5A58B1E6E4AE2DDC2D74D79AFF3C34E4E593E051FDA236B79CC0DB
+268D2A89B1878051223BB8F33FF99BA87A4811C0B3BCC01171D0A731EB732ECD8749D27952C27886
+B252F9C3D190419FD2900987A0A255B9753FB7AA70C37462134C467A2C4B7920BED9F9E86F8F98B9
+6D00AF8B05A4BD5F14C2A0D914A9A84160D554FD0718F50ECB5DF5E76623065852DAA74C9AD6DA07
+A119DF12C3577FE276AE551D48B1C5CD8A50E84DEC9CB0840520D78FA7F9A7C2071E28CD20EC7649
+B991F3818CDE295CDB6085F24FCF93147E9F4DD084FBD32525326D2EA147ECD5B6C9D9F4A7166663
+AD18BF234E9CB92FF72138A8A49E73E527E9A6488A4CA808AECABC94D693CD2C0C357D285F65006F
+A2F9197F61FBCA6EF07B013E2B558AB531D2FD270CEE7FA8E467FAB885E90C5884843AA08E2BBFEA
+0AA575643727BA18ACC499FF34E3438645BE2AA71EA491E54687CD305E12BBC94FAEC848311AE816
+495B013BC5075A2D2AE54A7AD7C9105B64356CB51F18C2C28E3A83B9D81A4554DBEC9BEA9A660CF7
+E1BA89E6D4DFB3EEC6A3DE3FCDED9B2D614156EDAE8CFDAD5FF0EFEE31DA3E6A54D94CE9453A1CAA
+D9756D91BE85315F6514BAFBC821EE810BB5D8E1B8F05F64F3F72C4B35D424F7E4DC3AB581B74ADE
+B6D6297CDE7AA8278909F269FED79B7DFD39B1C0338E01D556C4DB9CA3A8578ACE3EC3D743ED4B9C
+0145E4525E8C315F7A1B98584B975C70F0D415708C8CCC13F848B1D36AC8249B73638F95DE0CD27C
+7EFB52BED4339EBDA4812564D7A77416DDF4CC88CFB52D07A252D89353C6826CA1832A153242979B
+6CEE783ABDE65C8B40CF4EA7B42B8DBCC0E02423DD693108006F6A4AEBF053B666C3CB63D1861F86
+EAACD43BB9BB6F2C3A17293C189331D253B447757EE7CBF4518BABB73A1D44874D7F0625E6A013C6
+08E991B4AD17A9ADB36740D25E3E35B459B422F7370B134CDFFF3F3BCC4C32B4E9EBF6A2478013F6
+6933A1FA9403A2F1161EC632F1F04EDF95ED0F33DAD9665D54DD9DB2564E51DA7B65978CAB50D6DC
+1568976E83B056EB0E3A6758518B6E17E9EBFE49B72EB148B472BA144BDC2AC95744C9BF1258F0A2
+E47470AB0EFF90E190A41108914AB8C1ED6B11E0681778521870E80C16AF2AFC723CAD8719ADB62D
+3939D3BC8CC1D8A4E07E9D734F54ECA33D936D2C39D5C8055739C33E53359BD40E576C11E93B4B4C
+122BDBC9B1BBF44243AF4F0BCDBDFADE68C526B5CD74E29CE3F70D62BA83C489034111FE8E4DAEA2
+F01F9D938ABB532DEEAC0E329F42453FF5C15DEC2AEA8C198323C9E8FEA55B3F5DC4751D2E2E16B6
+154E7F2ADD46860E9CA71DC114C99D80E7EA1DAB51E925DE161CEDD678EE6282AFF38E3CD0E65954
+9C970613209955A3F581E1ABE485E56402A3DB0D1E9B8A9DFD05C4B0B7F97FC6D0EED0B69AD6F182
+B1D028ADD2F24463834B13F5C1307F91D363891824E81108E57CFD5211F86400D3E96B107F3B1FE8
+9C4908649D04A46DC3CEE0DE66AF03A7FF9F4DAFECDD6DF4D93784CC899B527784DBE0718050FCE1
+85BDE3F39DEBCDD660B2488D23AB1CFF87B0546D02B48E7B7724C9E87B71BF34B5D6640E0F6ECE47
+B182D41C89461F712849C6CFDB7E3F5EBC1ACDD12D65A422BA362A8FD6CAAC5104CCC5AB5FC04A46
+E4309ACAC83D659DDDA256CCDDD1BFF9AB3622450C4FBC89C82214F00C42FB0311BCB1B722A691ED
+839CAF9024FB1671F18E4639C96D84718C663A4341DEC037175C6BBD288BBF5A0478298CA726567A
+9B74C32A527339C666A294A17F6821CBF243D13EA4B1603C292953308B566653423E7301A032E5D5
+E2B93F1C1434893633DD19501AD12728B5A1D9D36635B589FA2E151140B543D7C5E469AFAE8E80C4
+FC1D9CB6C3823CC1BB7EE40AECB58CBC1465792226B19E0FE79235115F6A3AFE19F98C5DB63D372D
+D7C041CD940F4F79F2474D9CEEA0334FA04A97DC9773064895CF11CF73F11B4684F06E48F4469F6A
+1AEB2CBBC52994DFAB3319DCE3A0C8C2EFA9627496F8CC84D3DF3BDC4FFCB61672780F294F453278
+AEB9262E66486856D37B7647141A82E049364ED3D03F925284A3F1FA3DDF4C0B48B3FE22E7DF9ABA
+239D33CD300FFA8FD4B96192BD568FB18D325CAA8E1F1FD4B27527417B034841FD49E4A77F217062
+3CC8B22101166D80361EB15FA9020D24F61007B0A8274DF9DFCD8E97C85568E76D34AD5DB1779B02
+F034A69CCF9D4EBAA188EB3017EEF5B22A0A552696A574907F695098BD8A4849D5C8311F129447CD
+7A3CF88B8191AEC0AFF30A38A9AB8135608A7829207A7D242F6E1FA7DDA19F5E4C28560D42DB4405
+77CC0C5F5803EEE897103ECA0BD944E320AC26553BEE7852EAA733BD13DF760056B2F5BD1243BEDA
+BC3C1EA0531017D74B47E18F801A60074D6DF849FD0532234545E5B5E112D1E7385341D39A89551C
+80DC2DEAED5D5DA2A4BE5015D297324E92BE64C68428132E6EC654DD4BDCC6640C68835FF8A05E09
+9604B8CD43D3AF2B2FE10C8AFEDEC5A70AF8509D12F662338CBF166D9452CD36331758AC4F4CBD7E
+DD52139AD27DC52569877FE709F297444C4F31899D1945C81B14ABDECBF31DC463A4148F04EC4FB9
+703C158216C0FBE65CCD450043ABFD4E65BF8B28CC148252E9F3E797EA0B57B8721C94CBC2EA602D
+F2C57E87938C887A382D2659226463BC7D6A1DA87F4A341A59BEA458177D3F18D1213539DC0E301F
+6EFE0111FCF6921368BE17CCBB7428127E0C059C2C5ADB2A3F0197F0CEAB77FF7F3C027A8EC3EE76
+CF5C986EB47CB60561C773B3A2DA47B5A35394E29373DBD5C3FF4C9213A89AED77CC4F3FCFC49EF6
+EC7557C521979A546983C106B3627B5FD2D71CC5F08A32BF49332A89C5DA71AFBFB94C949A91220A
+B1F885C981423AF93F73BC1CA4D92D9DBAE3EFE6A76E2DE3D0F74FD3255820636E3F1A6B7C185306
+23C12AF90CDCD2C0A728521E9B639EB6345D1DE8FFFC3B19C72E7A93823DFE3115E9E7BBBEB28CB7
+3DB121AED8920D47D8CC08EA2E472E39A4CAD5881B5C4204F2B732AF9D5189D25ABF413CC78714CB
+01B1D8CA5565169A919DC481F6D2E67F1D490AEBC5CC62A8F62C1A323EBB55ED35AA5C8D6F8B970E
+93205C2701CF4817BDA994FC16197B469ECC5F5E9DDF0FA05640C2E571849571CBD26402B1EB1E80
+3FCF423345007B9B52B13E3B034E8CB3984B925EBFFE719ED4F39F3D0E3343316A6FDC26BDBEA88C
+4366D3B2F851D2B244CC4408251AE2C77348CCE9DD8BB9C89800B572D38C5D1CC34C740BEEBB5DDB
+0A8BB251655FB989840D23205D16311A9FCCF7C85F6DFFEA9704492A4E7A8F6C0BDC29745AAC2ABF
+AEBA02B0E7AEFEB92BA63AB0DF844EB09D505C3DFC1058CE42CDD8043B76398401E1DB862FF9F76C
+05E8BC6260A4443CF494BC1755913D51745BF45ADF2F8C7A9546D7EF4FB11E9D94E4539632C2A396
+06D04480EE459408D7A2A869807A4C01881C1BB21C296A402B5E6E07093D833C3DFF075F4DD426EB
+87B1B8DE16C146DE79F52F5943015331EEB852809CBB8E1D6460AC4D176FE96F8D19F6CCB22ABBBA
+A27C4497D91312C3CFB5BB913B314E43D2EC6AB6897BA7C34CF2CAA6DB4BD69EB5DFCEE0AA917D69
+50E36A68A4C22A60DCC69379D47544A58D640EB10DFE120FCA843B588CA8B94F7869F97609A6FE03
+AC86EC1F7CEAD2EC8E81977D1B946E459DFCFEFE65A7BFF67E66F5F78A45D8DF65AF0146DF74E024
+FC042328886CC1DD7779F49CDBB750345CF83CD678A6A8897577299DEB38AD665DC4F21CE1892A18
+C256F318107DD3E9245C1AD3BC93CEF7B7BF057E33EC9A3F953251261AA3D1A8347261E70A46F777
+3A84F3D4D1A0DF6DD22A96429349DE0D180310E17955B10FBF53220EF6483D03C650A8D5C16D63DA
+F65C21ADCD6C2D0B5D4ADEB2F5526AACF7CF42F9A8BF4832FB2D4F73F3D5FFD984B572232F87BD3E
+59133ED3D2FA19F7856AD812515C74F7D851574019C532C25F8E163E595FC9C83E3E820C3CBF690D
+A62578A980FC0803EB6DB9B1E90E3256BD4650816ABE5EA86CE65C2EB418D0ADDA5F3EA04E17AA8C
+4536CC471AC20236E66ECA3619F161DFEFA485386C30EBB86A7AD930FD0AADF2DA69DCAF26C0F677
+206E2030E3B15B3662C0AD03DBC1636EBFAD1F2F2C37F5FA9856B0198C5B1D80B69C5EFFD94CE071
+5135C649C26B9BA1266B0A5B270CD08A706166C0B320915C87B27DE21DEB5D7E4806F6E700B7A06A
+4E29B629CB40761983E9CA8E34E869ABD04DDA190BFE5A6EE8B22D7E511B84EA584A84211F27AF89
+18DC5AF8A1FF2D360B6BE3CA8E66BA4CD2CE6A25E7E89406684DA83FFBCCCCBFD0844FE3BECD7DE6
+7764C59C022DB1168D585FE25073FE00E30218D1DFE115CA1FC606AFCB04F2A082EF91788B6BD096
+84DEA31F20034A91AB9D971366F97B5009FEFBF1EF0AD941654081B1E8F0B2EA495069A1DDF11DC5
+6857D29533DC857958B49D1A0779732819FD22E437084BD9F3C4F2CDA4D12CA14431937AB63A03F9
+C040AF1D801F367ABDCA7302E18A9050D6026FBA5A5A7FAD44E31593173CDF277CD737D1CEF59FE9
+684252BC0DDD00A80E023B88222494C1C8C0884230AB11D1083225AFDCDBC1E24D4AD5FAB396D2E3
+70E44A7571B230660D510A5076D8E35F7DB72C0566DFC119EE1B8AC3C0406950A3C4A4DA36BDE297
+040A27F70753A87E6CD593DC6BE9962261A99AE5949340C5D45C94A9AA3DD636CE8B497BBB812345
+7C824F443A53B3EE595C38983FE3E07DBDC6ACD55CAE8BE1081AFD4857A5F52A3C925143507A3C37
+F1992CF72ED0D4C48D94AE6CADDC3BC87AC3A3EF035E02181F78449E4B063B0835E827644051551C
+1603E2EAB5875F28FC77BEBA6923428D5521C698C6B7F133B0F689F105FDBAC30A8ED2F29F0255DD
+F8A037B81F04EDF004CBE639C8DB0F94D0C5DB92D34D66C2FED66CF8B895AFC4E659D08388EA44EA
+E83CE459E5BE306750A682B627802990037157339BF142BCB9C08FAFDC3C3FB16DC3544F62C6C7E3
+3E20CC4FC7CA21E2C3F6C546CD78DEE348F1A4C8CB548EF20C049678916771D83ACC9B7B22784AD8
+580134471A3C79BC86B5D6D0D305C32E6204274351C94F9DF45D9B2AD5B5087A89F90D6AA033E4B1
+D1BED022F36147C7ABD2B73134DFFD50907258E610C3B20949E141172B1C6A76DB238C375021CBA6
+645CDC26B717428B5A9B4D3F32A4B1E22FEFF3BB93FD889E1DEF8087718D5E3E650FE4A3330DA9C3
+7E9EB499DF5A342D8BA4C0A033C3347CB25A31BE143ECBF91384F2381E323E7FD3A82A3197C18905
+3200AE2C86B9D01AB0B289841EA7E9E9A26966E0DEF54DE0B85D8DF084B8C590081E444BAF1E1F60
+670FA12AB97159318624F2AF1B5EC7DD83C1073A99398D2143A52D10A13C201FB356BC9E90C63BB0
+BC2D4C42AF4A8B9C8C4D58A1B32E0597C63B3F8B3E893BD3BE8C60231838F1BC78E73A6C8CDD5E7F
+2907F897FC8EE99BFFDA7338BCEFB5AEF950E5549ADFD207AEB15846B509FC57989883642498A381
+1B8E5CDE69C05924EFAEC232FA4CEF302EE3251366ECAEF57D25CFA3B4A9E6397D996F421C900BEB
+CF73B038FE7B16FD0A1172AC2F40D19CE0B02FCEB8BC47DA5344CB933C7FEC950184F78ACB32D3E5
+E290E84BE753B9E7A7BFC4416CCF29D023760C06CDDEF2505806A65E1508990529245059AFD301DB
+669D41BD72BF7A80A9DF66B876B3553FDF4DD38D15289AF7A1AFBC53FFFF135A6348DD784AB42A6C
+0D6AA330B069607E2DF3CBEFCE79D6F63E274C9E73A33EB85246D5EBB986BFA923DF68B2B8CF82AF
+6C33E785F35B25B1D1D614DE85A4F4510ADFE42D75B5FA5408A59ABE53859E28B3D000EB9C6A7D2F
+67C91DD14C895BA87B9CB57B851E5193FCC2A443AF85FE28DF6F39537F23A058BCF81DD8C04CB2C2
+5040300F4C55975E856DCB4E21E2B5481BDCC05601942FB25BB8A6B6F93E2C2A33CD478B44655657
+C557EBB080179EE5D98C5CEBE0B25BFDD952FFEB258014D7A5BC4BCA4F1A23BBA73C454B12960451
+CE1752401B0151CB2E01D5C72595095EAE91D8D3BD55A54A2AEA89239FA176FA7CD6F16BB0733EF6
+CE6E77763A23AAC77DA88C8EFA7BBB2991E472FF2075FB25A75ACFA70A04C28764F4AE4C12051B25
+B120CAD2E3044DA35C1F94135DBD69B10DE147321CBBDC814CE99982AC1D76CE3D3330E41AB31F3C
+76BF89B95EAB81AF3464C732D5B1411D97DB36C9063537F64756F205B16ED7058E2CB1D6946C00A1
+A0CDA9EBBE924BDA6C7D7B605C514A98133907B793C74CA858E82DA3519188CD974B34DAA74265DB
+5BC8550D5F0B1173ACEB87458BCE2AB1F96996C811699A0FE4A9B849D39023725E2B1EE7E426D30A
+6C5C75AE6BCEA6DB41E4EB2035F7F924E6B9F0DCD00EB2BB014222E55FE387FBF5B9B7C04F4688D5
+AE3529FDACB38B5EB0AF5C3A874C1AA6B17CDA8D1E22EEE05A3DA88449200D3D0D002DB86F6C51B3
+37C8E19F338E7BFA01E1202612D50E210140947D5F350E84F790286C3F679A5D7E43BCDC337265C2
+631527FD62D598B7CA1F5835C0441881B97F5197901ECDC4F195BC665A846823D2E41417373F8639
+567B228FE7B73D781F07A361AA49C3E9D80FE5B2A32C4C1E575D194E841967B08D10405FA44EEE28
+47DB9372C5CC931E50469532F1BAF577F680BAB4E30B7E1CFFA8574ABB679789F69A8A1BAC07B7C6
+4EF5CE5EB00E97B36FBEACA9BBA4A13B0293D34BDBC77AD1FF88E5744AF009823BC262511C4724DD
+585E7E17D90F230F7A5861B0DFC42F0B4E49A04EE0EE4DADB908479DEF8372F334C53D2BA5D855CB
+39DC7C9550F9D0F7F77E82D5A59FBBF34BFFE92DC9E6668B68FEEAA4F20053433D6749162BBAC5D0
+D428DCF2D58D49B127FA2E674EDC7D3613B1342F4D0ABD7F4C5B049FBF78E804D5F16505AE7EDCBF
+4D6FA08D72890F5D55199034572AB4B0C9A7E7F6F5A403198864ADF113CAFF5BF9D4AB5B16F81D0F
+C2188FC80875E10034D12E30C0364F8F72797F1AED525A2712A40D44210B813DF5A29C84E9F6D51B
+1D60A5F6F938FAABF878D29E6AB252D95D05FC1ADF5D4CE1C9E585219112112BC6CD5C766411FBD2
+2731794B5DE0A27AC57D3C57926807469C360372BE529098C350EFE2154B87F1205A57A0B04C5206
+CC4FA66B8793BBBE492CC3271FB4F90A28D0066E0D7F63B8DD01549A05AFA5482C29560ABD628568
+75CAC16100087540162473498C14087B29B86B7BFAD693E81765CEC781F3FC80E9C7B410E9B55B88
+114191A1703C638DFBB469ED1DD8254B1407003A319CE74AD419B077F17047A01F0BC0AC8507191B
+F72D77D9333C9DA8C9DA733EFB5305F49CB8C7BC451321ADD7D896395D269DCDFDD084EB3AA70338
+6C0697E962929651164135C094D9BB1C9B949D5EEBD3BB17F02C98C813CCBFB23C2C26218A2F4C63
+9A8B9DFF2C29406037F91938A5E1227310728428B56F48108CDEB33BD3191ECA89F947271983DB77
+6B2BC897A30EECF2601EE3B2A6F0E135397622AAC1F2DF523CE6E6BC720E13CB530CEF4AB9C8273B
+D3D81563AC8A8E6C44A195112DAF824BC7A72FCDC4E129A480717BEB01085DEE65EE4344D0B41EC0
+BCDF842566B1D9F5353B1F6A063FFA6CDB06EF634C8BD5A7A63F991D178F56EACA653DD67685CE49
+E98C7554745A4AC533217662D23E1D6937135D13BC2208EB8D50560A2BAAC319DFAE478B6BA4CA5E
+DA20222F0E9BDB0806320ED1665B54A347DE0C42E9F77842DE4D188E7E824EB2F0D7AD163F05480A
+7FA99C5A603BBC5DBC843774CA66E889B945054C0ED0B1A4BB14324EF901B023C208CB95DFCE9284
+89789690CC45BAB97BE449F8E2F5AA9276C0571303E9788C46E7F789555BFCDC3FA9ED8DA8AD9BA4
+8B3AE09404664391E63A989EF1E24BB464043AA099E4F2D796E352EB277106D8D81BAF2F8562EF46
+BCFD1E0047E8018CBD973021DC1C1D821AF03F083F0B088A62EBCF2BF6C5B0FCFA441AAD1625FDB8
+34F943DD47A5A42EB3E9A5B49641F797C288B799A64897F1346070461B6D535E0C4ED099199C387A
+3176AEDC7DA7E7D9E118E55565092A36F7C74ABF281720C0147F4E4F37D49436466C61FF12764E30
+43D8A6D027E70537164F0E7942F4ACA42BB2CB136177EF7197E76F49AB403F741C0EF902FEBC471A
+D6C627424320A8C3A1F04C310C511B3F91C3937D9ACF459999C18A33F2C852EC38CA806599C728C5
+43714018C65E2C5F430F6270AF52AD71ED38813B60440779455F9529A4A1623CB9F5422B9216F9CD
+BA913B9A1CD95DA225E254E8101216085020660509D03A034B5D7E32E3DB5E5962A9A27711D4C3E2
+9CD84057F7D0D7E8000947AFE896F8523253391D2E11FFFE523366B05C532D5629A90741EAB3D4A7
+31D3F6D4F03FF93233DDF88BB1913ABA22EB9AA6311E3144381DAE29BCC8639958EEE59ACCFA06F3
+5DCCC63E0609F542F3EE5DFB1CF718CA3F328455726F8F65E23ACD970E4049225998371B63E35AE9
+8DC54D8329B8DB0901FAA63129EDE21B158776981D4D094013C096E9CD020315D123C03DEBA21E97
+E4B584B4BC0AF25F5DCE53C2DC0F3E61F99BECAB40799478BE7F5AFD7F68E23EF50AD6645C967EE1
+1206B6E791769428ACDC370D64E4F2B3972E0E4F442297199350663D6E772FC6777A9B9DE215273D
+082CCE4E8678FE9948DC8D5B0E459CD02F1645AC5620F3571A40B4D5A17DF5CFF48B6C843DDEAB5E
+BF58FE13D7DA08E8AA7902119248B3B151DA583101CF80853B0150FE05BDEDBFB50A7FB0F65728C9
+3B9DF48CE8AF1DF1FAC25C1D58E1AD30274A00EB54CF2F16029E1AC0A0919C0655474B9A6936AEE0
+FB74BD185FE7D70BB84786997D34A40326A74356A4AFAEE67B6B26D1C1A7BCFF8697B55C816CCD77
+312C332A55315DC54F9BC0A0F12500E0A76B3936292A3DA2DDF5AA8CBB9B5DC32EDACC4827D684D2
+74E65B8B76FB2C2B19F7D5607523FA953E34BB39032C05B1C1244304606C55660D3CA8607E764EA5
+B03DB7FCAB5CF7788C6E60EC8C449BCAFD90BCABA4132B6CBCCFF16784FB59B36B77CF0A9EA572E4
+CA0A01C725A6CF2E4500CDDF5BACCB9094D48925434F044118CFDC2696AF5FC0CAB3884107ED17B9
+BDE0C0104B1292A1F8C99B06FC4A6360B24480BD59DF0488641899B0F42B1311B582717BA7ECFEE1
+4143654B5371C8B9B2D80685AD38D897AD1E64875C28C7020A84FBB3A3BBEE16617DCB9BC822B7C5
+9C5A18C0CF7E80163ADFB7AA03B7CDE8497C1697D90F2ED90F813095C5B91657FC294EF0E341DB33
+92ED860CB2E0AA09293D0F99AE9EB54C761CA2DB1E51E1CEAEAB276C7BD916C68510D72D9A67468B
+09B3C39A7815628FB126CDFD5EFF59CC8184C0D35A5B5960F824BD175495DD3EB12A4E96008CB13B
+8C5745303E66CF8608FF27C4709C1D854EB79608E52F068FEC0151A74C125EDEAEA555C198FC0802
+7BBBB802835E1D435077AE4B1CCDBF722354F6C572BEB1376D3E342195FA80AC9722EB2F46E44DE0
+5F5A227B731B8D4A4B6EDEF04AF2C5DEC2EEF8FF48C5B18710ADE3DBFA0C956505B6DA9CCB7CBB83
+4DB6CC754948855D833670FF0AC42A4773FEA8322BECEE04CA74AC2D66855132D11A51524488C547
+71B5B7A512796D7D7AE0F9C1FBC9CBDBA0831074F4D200349D0CA40537B92496692766F020AC43AC
+01DB8B2AA2EFA9D21732BE3A315F6CAA402BB2E61D40DDEBDE11276D90C2C601A935C168BE600464
+76ADED15087D54A14C68EECBBBB590927C1E10D291C9285334CB0C80EDBD392BDE4D535EB61F8E76
+41F58AC1DF5B1C5A5D91E3E27E05CAF7EC97ECF0C85B6425197AA856521ED701E5AEB82A7F52A8BD
+7DC97D5B3FB5C99A5DF84D1BAFF89072922509D76BC6EDB15CE5F9EB8F4154BEE1E82020240283BD
+C83A8E49AA9A2649B7955D5C058F2818A63BD0BFE7EACED4A49063C489A626277AE1246F721C9926
+E2A2B6C31045FBCD235F3CC58BC4DD6C57FE998EBD1E9FA5154652BE3A1685BCD2EFAA079A3293F7
+8142A6473822FAB627927EACCD61B3E99C3077103D2D19382BC7EE15BAD0FDE489602D055A01DBBC
+F91A566974559D1B477C209416887053169C3F8F59955BE4DE82B60558CC9AE15602A93F029F6B43
+29E0E62A03982DB32F5229714EFA1491A7B24AEFE18FEBC2C93DFE50B3F641B51BDD33DA38871BF5
+243C17502D00AEA2D9E9734E80A96788D4CF5BC12A42BC386162FC88A7435EE13200C1C2C6CCC5D2
+1A03941007B4C4291BDB711446CEAF27148104BB240357D5EDA0EA5A5CE27D4A83909D75BFC05D75
+F10AA74A6DE37D7DE15C1DDA3AC3045DA6CD48323D904E716B445E5E096FCB379353ED70CF4B6FAC
+102C762711079EFAF13FB74C9B47AF75F3F6BDA2A4647D2AB47ECAB64DA6CC01479F618E8D2D0A36
+45445E8744683CBBC560D47C98078B84206E90EB839B02D37C852B8E284463D4E4D890203C3D5B20
+352110034EAD6BD7F41456B807E1DB1631A9D499E52E9D9853D86728B1A2E511F40F8CA1E4724A0D
+17ECD640B52FF6C66E28693D89765FC391612E5889E77423EC85CBD0A038B6BA98B607701DC0C4B6
+6B3B28C7790A1F1EB8D051DC98276DD9CFEFAB3F65C1C928E48A060C992B392A43E56EAA6DED896D
+EBCE71F8245BE4687F2F1B8FC0F43ECE8DB0BD0AB0811C5CE73CBE336023A0D66168B34A95B4B0A7
+50B3BF1D197E3C042C7914FA731D7831AF798E9429571CBB977E6258244E84701E5FF91D608F98FC
+3D68A4EE5B81D5FF38B6C184F6118B875F022B4CE207DC7B37E1452DFDC591A3E506AE82C7E7BFF0
+011B0A3DBD616A993FBF878FB03B6C9F2055A2B095D29361F8253C2623653687FE0AB98078F6AEE5
+FC2C2BDE0405EABEDB3A33EB7F04CB6837176245F190C6BBBCD64522B12FE7F9CDCF201A1AA8A19A
+7BBC4AC064B4958F44AA0F8DDA23835AD28A1FD0EA105DE2F395385DCCFBE2261DC5A89A23AF606A
+3985E5038706B1FE0910400E16BF008F250F3BDE3AD806C735495D499F16F99275010478FD2127BF
+7CEDD6B5BD505FBE9BD0065B4A7090C9D27CD5B36C3AD33E1B31EB6D44E375003B51B909DA50BD18
+218418B3CD22B43278B144BE78406EAF16C7DF6B6C1C6238004AAB73736B38E168441DC16F9A5CF6
+0793A18633BC43D78674D12D38CC979F7CAADA6EFE807CEA499CB9FE616496682A66E04BBDACE1DC
+112B2156B9B0B20A58A8CB43FF0EEDB99805234B9A5789762AC7D65F5A319C33F4F7438CD15E06BB
+80A7A97E976E8CEC23F4C646A5821880A82B2F1DC27767F090997E91488BFA15064B702F864FCE65
+05D6CEF87D2A0A12B55BA189AF269811E3B8B850C8401F3906C080D32618D9698A766732A40A9FC5
+A94E5BDDA3D028D823D6B603B6D17DD046DE181FD989EA0F80B4CA62F7973E4DF5E032A31FE6BC8F
+5CDA678D4A72787EB8253EA5882C337CDF9AA3E1E7D9536DD09B047CD8962E773F72F6418A3AEF5A
+289B3406C152A50CE7BD4B493FFFC27F6AA52F79EA67E362FD92559AA4F94A2F787F6C735DFADCF2
+F08AAF98B80C53CA5607A94F25F04AA65A70A75937840E73055B3D65FB054C63E2E48E68488C9315
+A13EE949E03E46723C11CC759D222CBFAD2E1A87CAD779B23D38F7E2F660DE1388EAF1CF4D18994D
+75C6CC63F187FDB949940C18B537A0AFB12AC5F67B0283CA5EFE2E764C4369104B9D3B06490D1244
+C41D6085C85F1106082EC9DB84586230511C05C82412D2CDF3DAFBF4759A775628878F997415296B
+C416AC8352A6C6988691FCB831CF95C10BAE691ADB3BA2918B35924BD5C3ACAD8B137397B10AF82B
+479800FE16D472CD0CDBDAAB4F882A0649CF561004B8CB7CA32EC129D0A415BE6CB91DA2B65F44E8
+0D138808A127E851A7FCF927E99DAA0EA2D626B77A16C72E37F058A3B882FC4955DC8CB6312434BD
+3BCED75780B13590BF4FE8D64ACF0371F9FB1D361B05025852AAB9EDA1A0C997CFA58052C454FD45
+1E6C1F194F4D363114E312F6DC35BBAF357A32CD200A3DD9654155134259887D677ACC44F89AA401
+CA27282DF7DC3F2F04A108CBEF2558DCCE28BAC2D87B8D5B7181EA927F61977764F882626D4AB338
+D95C9477C54E9C36012A3CFFBE199EC8120A99D2D70A21F9D9A0354E4EAC7947990E8A6E0601796A
+AF6F14E758CABCABDFBD8204A8E748A3E5FEBA570D36E2BF474C0083229A63F96114182321B2EBE1
+BC76DD193724C4588C1D39D184C332FAEAF4C629F2B3B2F49996E46AA6C9F497428BEA52D58876B0
+DC07B460248BC85CC16773A5DAC36CDE8B152D96057F4EFAAF8B1DC10022038577368057699B3A37
+178A9F1F6C6CC60BAE820B7ADD0717911BD23A6DCDADAFA32473491AA80CFE90F2A77E24CE2826FF
+77B18B869C33FA292FE01D6477765044C7D14A548B28B1360125C6933F05C58B0889390537CDD16F
+8E967E0B38579449DFC1E07389B7069AA8594C5103465D5041CC929268DE863FADB6925B350AA94A
+27D421FB7FCC81C6B35F906F12246B7A5140511A97211BA9BD6831A508E963FE8BE961332F557808
+488F06EAD75E86D60DE3FA2425AE8439ECB9112BC3E4D73747C1C8E87A649919827049832DB0BF6D
+A8C85C9A2592AC002809070900ECAD52A56F1BFD456AFE066509694EAC075788456B0B0BDD7C192D
+321E9FB6AADCAEF00F570F22CD4A5322FBCE8FA98FAEB681940895426270BB4319C11DA67D88552A
+7373398AEC5DA7C9CAA9F3B34581C6E968DAAAB2751CC012199DD897B448986CFFBAE4D412BF9ECB
+F46742715A9569932516259D3B3A5431CD7028E42FC751C434E2B714C718202BF02CAF9B8A2075DE
+922322EA7CFA605C8376FA958B8FBE43031E1026FBE6126A3775F643EA67EBBD97F239FB3C435526
+75CD08B19CA5EBF53B40D728556B4481C7F73EC71CAB0F89E34D60C69B272FADC22E8E7BDC6210DB
+09FDD913E209F49FD28E8712B8508904620250746CA3B21B026EDAE60A2822F59E912E626B93E0D2
+BFB3230DFD0E54E91A1DBA25A609B64D41ABD897A5D21764C351E85F9E87BEAB9E645149AD32AEEB
+B3B1161032C701647115F98C1C2AAECE871862D91D321AB90F3E923B1FDEE00D927F897AA9812373
+6536E2E0700F10053D7E6C589BF66029D794883EAE4C8228941CE96565B50D48887B5314A2E55379
+59638222A6CA54C77CBABD460DAC11B063519AE4F50D93DE41763BA7CFBF4C7724360E750478EB62
+8921DAA065858341958E4F3EB5966C6DD77C05EEECDF4B5F6CF19AB507589B4219377959BD258EC9
+21C34FE1DB003F7D0FEA3E2FD6F5DDB0A2D62CA5A2CD3C7AB457DFF25094EFE04A9E1B9CE7AE3F30
+026B1CB039228D309A22899F6E9B9BFF922E117123347967D7C62C670E2C74579C35989925603022
+C17B1DCE378031ABC9B4B437C7B6E64620932E93189754C01D4B280B8B08699B2CA953AE4823BB9E
+E34133C5C95B3290E1BF010705AD852C72BE87291E1034B09F44A95B6A2F83FEE8841DCF661770AF
+44D0AC7F9CDB280939FC5D953D525E0B41B7BE188D5C794687330CD770D24D9CD53B895A253004E1
+8A31BE4E82B384
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+cleartomark
+%%EndResource
+/Times-Roman-iso1252 /Times-Roman ISO1252Encoding psp_definefont
+/Times-Italic-iso1252 /Times-Italic ISO1252Encoding psp_definefont
+/NimbusMonL-Regu-iso1252 /NimbusMonL-Regu ISO1252Encoding psp_definefont
+/NimbusMonL-ReguObli-iso1252 /NimbusMonL-ReguObli ISO1252Encoding psp_definefont
+295 271 moveto
+0 0 0 setrgbcolor
+/Symbol findfont 50 -50 matrix scale makefont setfont
+<B7>
+show
+370 271 moveto
+/Times-Roman-iso1252 findfont 50 -50 matrix scale makefont setfont
+<4D6F64696669636174696F6E>
+show
+659 271 moveto
+<6475>
+show
+738 271 moveto
+<66696368696572>
+show
+897 271 moveto
+1 0 0 setrgbcolor
+/Times-Italic-iso1252 findfont 50 -50 matrix scale makefont setfont
+<534D4553485F5352432F7372632F534D4553485F492F534D4553485F47656E5F692E6378782C>
+show
+1898 271 moveto
+0 0 0 setrgbcolor
+<E971756976616C656E74>
+show
+370 331 moveto
+<434F52424120>
+show
+543 331 moveto
+/Times-Roman-iso1252 findfont 50 -50 matrix scale makefont setfont
+<706F7572206C652067E96EE97261746575722E>
+show
+294 433 moveto
+/NimbusMonL-Regu-iso1252 findfont 42 -42 matrix scale makefont setfont
+<23696E636C7564652094534D4553485F4D6178456C656D656E74566F6C756D655F692E68787894>
+show
+294 476 moveto
+<20202020202020202020202020202020202E202020202020202020202020202020202020202020
+20202020202020202020202020202E>
+show
+294 520 moveto
+<20202020202020202020202020202020202E202020202020202020202020202020202020202020
+20202020202020202020202020202E>
+show
+294 564 moveto
+<20202020202020202020202020202020202E202020202020202020202020202020202020202020
+20202020202020202020202020202E>
+show
+294 608 moveto
+<202020202020646F75626C65206C656E6774682C6D6178456C656D656E7473417265612C6D6178
+456C656D656E7473566F6C756D653B>
+show
+294 652 moveto
+<20202020202020202020202020202020202E202020202020202020202020202020202020202020
+20202020202020202020202020202E>
+show
+294 696 moveto
+<20202020202020202020202020202020202E202020202020202020202020202020202020202020
+20202020202020202020202020202E>
+show
+294 740 moveto
+<20202020202020202020202020202020202E202020202020202020202020202020202020202020
+20202020202020202020202020202E>
+show
+294 784 moveto
+<2020202020202020656C73652069662028737472636D70286D794879702D>
+show
+1050 784 moveto
+<3E4765744E616D652C>
+show
+1276 784 moveto
+<944D6178456C656D656E74566F6C756D659429203D3D203029207B>
+show
+294 828 moveto
+<20202020202020202020534D4553483A3A534D4553485F4D6178456C656D656E74566F6C756D65
+5F766172204D4556203D>
+show
+294 872 moveto
+<202020202020202020202020202020202020534D4553483A3A534D4553485F4D6178456C656D65
+6E74566F6C756D653A3A5F6E6172726F7728206D7948797020293B>
+show
+294 916 moveto
+<202020202020202020206D6178456C656D656E74566F6C756D65203D204D45562D>
+show
+1125 916 moveto
+<3E4765744D6178456C656D656E74566F6C756D6528293B>
+show
+294 960 moveto
+<20202020202020202020667072696E7466286465737446696C652C>
+show
+974 960 moveto
+<9425665C6E942C6D6178456C656D656E74566F6C756D65>
+show
+1553 960 moveto
+<293B>
+show
+294 1004 moveto
+<20202020202020207D>
+show
+294 1048 moveto
+<20202020202020202020202020202020202E202020202020202020202020202020202020202020
+20202020202020202020202020202E>
+show
+294 1092 moveto
+<20202020202020202020202020202020202E202020202020202020202020202020202020202020
+20202020202020202020202020202E>
+show
+294 1136 moveto
+<20202020202020202020202020202020202E202020202020202020202020202020202020202020
+20202020202020202020202020202E>
+show
+294 1180 moveto
+<202020202020646F75626C65206C656E6774682C6D6178456C656D656E7473417265612C6D6178
+456C656D656E7473566F6C756D653B>
+show
+294 1224 moveto
+<20202020202020202020202020202020202E202020202020202020202020202020202020202020
+20202020202020202020202020202E>
+show
+294 1268 moveto
+<20202020202020202020202020202020202E202020202020202020202020202020202020202020
+20202020202020202020202020202E>
+show
+294 1312 moveto
+<20202020202020202020202020202020202E202020202020202020202020202020202020202020
+20202020202020202020202020202E>
+show
+294 1356 moveto
+<2020202020202020202020656C73652069662028737472636D7028614C696E65>
+show
+1100 1356 moveto
+<2C>
+show
+1125 1356 moveto
+<944D6178456C656D656E74566F6C756D659429203D3D203029207B>
+show
+294 1400 moveto
+<2020202020202020534D4553483A3A534D4553485F4879706F7468657369735F766172206D7948
+7970203D>
+show
+294 1444 moveto
+<2020202020202020202020202020202020746869732D>
+show
+848 1444 moveto
+<3E4372656174654879706F74686573697328614C696E652C73747564794964293B>
+show
+294 1488 moveto
+<2020202020202020534D4553483A3A534D4553485F4D6178456C656D656E74566F6C756D655F76
+6172204D4556203D>
+show
+294 1531 moveto
+<202020202020202020202020202020202020534D4553483A3A534D4553485F4D6178456C656D65
+6E74566F6C756D653A3A5F6E6172726F7728206D7948797020293B>
+show
+294 1575 moveto
+<2020202020202020667363616E66286C6F616446696C652C942573942C614C696E65293B>
+show
+294 1619 moveto
+<20202020202020206D6178456C656D656E74566F6C756D65203D2061746F6628614C696E65293B>
+show
+294 1663 moveto
+<20202020202020204D45562D>
+show
+596 1663 moveto
+<3E5365744D6178456C656D656E74566F6C756D6528>
+show
+1125 1663 moveto
+<6D6178456C656D656E74566F6C756D65>
+show
+1528 1663 moveto
+<293B>
+show
+294 1707 moveto
+<2020202020202020737472696E6720696F72537472696E67203D20>
+show
+974 1707 moveto
+/NimbusMonL-ReguObli-iso1252 findfont 42 -42 matrix scale makefont setfont
+<6F7262>
+show
+1049 1707 moveto
+<2D>
+show
+1074 1707 moveto
+<3E6F626A656374>
+show
+1250 1707 moveto
+/NimbusMonL-Regu-iso1252 findfont 42 -42 matrix scale makefont setfont
+<746F5F737472696E67284D4556293B>
+show
+294 1751 moveto
+<2020202020202020737072696E7466286F626A65637449642C>
+show
+924 1751 moveto
+<942564942C4D45562D>
+show
+1150 1751 moveto
+<3E47657449642829293B>
+show
+294 1795 moveto
+<2020202020202020534D455348436F7262614F626A5B737472696E6728>
+show
+1024 1795 moveto
+<944879706F5F94>
+show
+1200 1795 moveto
+<292B737472696E67286F626A6563744964295D203D20696F72537472696E673B>
+show
+294 1839 moveto
+<2020202020202020>
+show
+495 1839 moveto
+<7D>
+show
+295 1956 moveto
+/Symbol findfont 50 -50 matrix scale makefont setfont
+<B7>
+show
+370 1956 moveto
+/Times-Roman-iso1252 findfont 50 -50 matrix scale makefont setfont
+<4D6F64696669636174696F6E20646573206669636869657273>
+show
+370 2015 moveto
+1 0 0 setrgbcolor
+/Times-Italic-iso1252 findfont 50 -50 matrix scale makefont setfont
+<534D4553485F5352432F7372632F4472697665724D45442F4472697665724D45445F575F534D44
+535F4D6573682E63787820>
+show
+1672 2015 moveto
+0 0 0 setrgbcolor
+<6574>
+show
+370 2070 moveto
+1 0 0 setrgbcolor
+<534D4553485F5352432F7372632F4472697665724D45442F4472697665724D45445F575F534D45
+534844535F4D6573682E63787820>
+show
+1764 2070 moveto
+0 0 0 setrgbcolor
+<706F7572206C27E96372697475726520E0>
+show
+370 2125 moveto
+<74726176657273>
+show
+551 2125 moveto
+<6C65>
+show
+627 2125 moveto
+<647269766572>
+show
+789 2125 moveto
+<4D4544>
+show
+937 2125 moveto
+<64616E73>
+show
+1072 2125 moveto
+<6C61>
+show
+1150 2125 moveto
+<737472756374757265>
+show
+1370 2125 moveto
+<6465>
+show
+1458 2125 moveto
+<646F6E6EE965>
+show
+1642 2125 moveto
+<534D4453>
+show
+1809 2125 moveto
+<6574>
+show
+1885 2125 moveto
+<534D4553484453>
+show
+370 2180 moveto
+<726573706563746976656D656E742028636573207374727563747572657320736F6E7420696E74
+65726E6573206175206D6F64756C6520534D455348292E>
+show
+294 2282 moveto
+/NimbusMonL-Regu-iso1252 findfont 42 -42 matrix scale makefont setfont
+<202020202020636173652034>
+show
+596 2282 moveto
+<20>
+show
+621 2282 moveto
+<3A>
+show
+294 2326 moveto
+<2020202020202020656C656D5F49645B375D2E707573685F6261636B28656C656D2D>
+show
+1150 2326 moveto
+<3E47657449442829293B>
+show
+294 2370 moveto
+<20202020202020206E6D61696C6C65735B375D2B2B3B>
+show
+294 2414 moveto
+<2020202020202020627265616B3B>
+show
+294 2458 moveto
+<2020202020207D>
+show
+295 2575 moveto
+/Symbol findfont 50 -50 matrix scale makefont setfont
+<B7>
+show
+370 2575 moveto
+/Times-Roman-iso1252 findfont 50 -50 matrix scale makefont setfont
+<4D6F64696669636174696F6E2064752066696368696572>
+show
+370 2634 moveto
+1 0 0 setrgbcolor
+/Times-Italic-iso1252 findfont 50 -50 matrix scale makefont setfont
+<534D4553485F5352432F7372632F4472697665724D45442F4472697665724D45445F525F534D44
+535F4D6573682E637878>
+show
+1712 2634 moveto
+0 0 0 setrgbcolor
+<706F7572>
+show
+1838 2634 moveto
+<6C61>
+show
+1909 2634 moveto
+<6C656374757265>
+show
+2080 2634 moveto
+<E0>
+show
+370 2689 moveto
+<74726176657273206C6520647269766572204D454420737572206C612073747275637475726520
+646520646F6E6EE965206475206D61696C6C61676520534D44532E>
+show
+280 399 1 1451 rectfill
+2125 399 1 1451 rectfill
+280 399 1846 1 rectfill
+280 1849 1846 1 rectfill
+280 2248 1 220 rectfill
+2125 2248 1 220 rectfill
+280 2248 1846 1 rectfill
+280 2467 1846 1 rectfill
+showpage
+grestore grestore
+%%PageTrailer
+
+%%Page: 5 5
+%%PageBoundingBox: 18 18 577 824
+%%BeginSetup
+%
+%%EndSetup
+%%BeginPageSetup
+%
+gsave
+[0.24 0 0 -0.24 18 824] concat
+gsave
+%%EndPageSetup
+%%BeginResource: font NimbusMonL-Regu
+%!PS-AdobeFont-1.0: NimbusMonL-Regu 1.05
+%%CreationDate: Wed Dec 22 1999
+% Copyright (URW)++,Copyright 1999 by (URW)++ Design & Development
+% (URW)++,Copyright 1999 by (URW)++ Design & Development
+% See the file PUBLIC (Aladdin Free Public License) for license conditions.
+% As a special exception, permission is granted to include this font
+% program in a Postscript or PDF file that consists of a document that
+% contains text to be displayed or printed using this font, regardless
+% of the conditions or license applying to the document itself.
+12 dict begin
+/FontInfo 10 dict dup begin
+/version (1.05) readonly def
+/Notice ((URW)++,Copyright 1999 by (URW)++ Design & Development. See the file PUBLIC (Aladdin Free Public License) for license conditions. As a special exception, permission is granted to include this font program in a Postscript or PDF file that consists of a document that contains text to be displayed or printed using this font, regardless of the conditions or license applying to the document itself.) readonly def
+/Copyright (Copyright (URW)++,Copyright 1999 by (URW)++ Design & Development) readonly def
+/FullName (Nimbus Mono L Regular) readonly def
+/FamilyName (Nimbus Mono L) readonly def
+/Weight (Regular) readonly def
+/ItalicAngle 0.0 def
+/isFixedPitch false def
+/UnderlinePosition -100 def
+/UnderlineThickness 50 def
+end readonly def
+/FontName /NimbusMonL-Regu def
+/PaintType 0 def
+/WMode 0 def
+/FontBBox {-12 -237 650 811} readonly def
+/FontType 1 def
+/FontMatrix [0.001 0.0 0.0 0.001 0.0 0.0] readonly def
+/Encoding StandardEncoding def
+/UniqueID 5020945 def
+currentdict end
+currentfile eexec
+E98D09D760A3C22CF119F9DC699A22C35B5B35ED6AA23593C76D54CABB5E942BF7D6DD84F1664B89
+699C74B472DE9F8E6DF925F6C4F204E9F1C639B4DBA988ED2AC419FF2B2BDE605B8EE3264EDD6641
+2D4F21C64AC522BDFC7C5502F9C3F3E5592B3B2093D33C9BFAEDD2D49E89AABAA832E23F062E91A2
+5032519D1868816E44B4E0747795003D7930299D6E1E2A5BFE0D595DC97E140989CE81D8D7F852FF
+9CDC7A1B1B598C69131DEE005B415805A16D8A123E6A2261C63C769D2F4B60FA2C438AD7D199D8E4
+5F7E7C9A605C8CA14E21FCD81C9A515FB8DB6F99604534D06EA9D87FE0FAA852899C9D0595C7A97E
+6C55F79FAC45CD38E87B10D210CE7501E88C8FCD3444354365FB893A12F596AE2C1E70D5819EE0D0
+87D10BF8DA96F3DABD5405D28C4228C6C31BA4052464859640933FEEFD8071C0C84CDD829A9B1D0B
+A01F25A4D50EE2EA2B45160CA6333B2D2800306ED2BEFDFE155E9D9F9342EB8D5B0ADBF2460CCC98
+643FB1287CCD28ABA7B5CAB92EC39EE2E918990372B16F8487EBA30EAE88708B6CF33B6C015D8096
+C7CFE2F139F52052E3925C0D50FD64CE68236D59CB83EF56BFC584150EC38065059F3308AD6F9A99
+F83EF4E6CB13855C8175E31417D190D036B387D3952344A950F4D8C7781B307A094DF1ECAEE4D2C2
+FD747BC6F7F9C6BD0E90C19294F96C8C5CFE88FB34C477574A1B1630B8CC591529E59B20794DA32E
+61DECDA8ABBD1AE956CF74012AA01D42EE01E861B0AA6897C864788AE59DEF43C493246FDB1ACA55
+4C12594BC7B33657A9ECC9E3D1472EF826073F632BE540C35FF6FB40566773F3BB2204D3A579A08C
+CBC844C14B18C350F003B9DA23A570C362D6003893CA32F86F59B829C78EE3188B6E3F7FA81D7F62
+2825C639638DFB78B7AF1F500F5B450FA54DBFA5CBA277C794ECE93275A3DE0B452FDC8DDC2993BA
+A42F28A636008CDCB03EBF71BDCAF35019778993443F88412AD2AD0D7155A3944606463266322DBC
+0244B07DA1E9C27A27B59664E8566D7A54CC03E995AAD008B0A17E2C3EF61F720CE7F7788599C4E4
+4C709CD5C31B11107F16AD70B17B9AFE2E8CD922A7428DAC171427FFAF51067307FAB0ADB530E701
+FD22DA22C4CD3064067BD4F6089C4B2C87937DD426E4E9D2F60E608288BAC9056554D04947E69200
+61E379CF5E81BFD32FD37EFAC1F61CEBEE551B0851516471A7472C60DF89DAA9EB1DC5A67E479745
+3E69B9E22BAF4E3CCA4192D603295B018C4AB69D18DE52DFDF15E96B557F290A4B8C5B1E7A6CACA8
+1F2351B97ADFC36995ABA43803A6E5AC04A3C93495F6D38106B8B144449C07D1358210F9176E1565
+72363CFBDE576BFDF99FA329DD1346E83F79E06CF68250CA57A68931BC7F342AD295D0CBA17AA95B
+B8EEB53EA6E8E660B814E9F857CECB14F44A43288B69A9E7908D55BF19E844359879D28CAEF1C38A
+36420185D20DFB32C2E002202800E8EF3D67C5D50E919657CA958B538D537D503444865331D79BFC
+40312068D72364503BD0CC84B5F30A74D8B5B6A26AF2DB764564FB65A6BA8F9051AE2B4EA458D46A
+4569F30C6E77DC097356770362E6CF3F1661074778EBB44FF7D1E3B64FF75E77E11FE525BB121C65
+46CFD13300CA1F02D571B82A5825E6226D14FDCF27F06D87452A8B6C5DCA658535CEE2A795E58137
+D48E566B69D53A0C3B766E84C51EAA221C46999CC8065ADB2F129D5B630FAB1814C0C33B5AEA0EFB
+B6E994D80941B53079AF96D90A0B924F9B0E319BED9836B8F9053F868363D3CA554CBB181863301F
+8CB940872ED5FA7BD18CE39218B5AD8AC57D0F752D941076B1C64D99BE0DB86D7A6D96510D772EB2
+4C587F11779BD21CFE5BDE1F29C1EF9022B2B8BCD7F91153C845906722477829C40111D810480F3C
+F62DE8DBA7FD86CD236E656618CAF6FC46827FBC4898EA7672F8C9971AFE43E0E01EC8B77D4AF48C
+BF1210E98C1DB15C16D149BFF58AB0270CF015B107A3A50F5DC8F37FFB92EEC8CB6778DDB7CE4AAB
+C464C4AFF654223006A550EB52485A23D2B4AA7198D3CD54418102F1E9A4FBDE37B841E56F5C2C53
+966DB9B66B000E4588282E3FB80C2C519339F0002D2F83C979EDC5827A3B3C8EF8810A0F9DACB6B9
+998E9AF6551F56313DC4011904CB979AA2D32B11A811BC248141E4B9734D9FB7982A5671002D8279
+CAB93ABE057474628DEFC95D43890DB1ED34CFA8A20BDC3D874E7679A396158E522ED0AB969A4E3E
+C7E4474E192590504D54DEB7B260B7935C4E56548A7D121AC1F741F8CDF259EA1B5813175A77A1D2
+D30BA26F65EB765A04C09ED51F69F41551ADF399E6AA2FC09788137BEA4913F17B8EB838C38FB272
+1FDCB55FD65697FF0B850E7D3D1CE266BF90F7EC06A9A0876BDFE767D3A918B092FC78C775F945CF
+1F96E859C03DBF630D9A940939654C3549D8F7921CB94EE23D5A0535DE9DF31EA0F937F860B4F220
+A99ADDFC343D7CF7BFA0B803C12C26403F0DCFFC8EA786D0D8A8D9C367419CA8AE41190CE93A8086
+583A1E6C9D70B612C84D87D2EEAA71EC2DC12F4CDE6A821303D5F6A9BBDB7EEDCD289E80FA3B75F4
+7F481B50719DCF4A142069393593B9AF9CCEEAEC56A35B8787193D7C88113E9E1E221D151E093B01
+9EF89F6118BEC4735103CC8003CC5AD1B6727B3226CD44C497DA7052DD681695DBEC3397F9598C91
+77701C73BF0594CE93F23D50EC5BEE2FB9DA1FC966DF148B27B28EE3C89526DD6625E2887F9FA076
+7C127C609EE315626BC14D274FBEA56528DC06A27B2D476D46E9E7916590B156A5DF04A6CB15E362
+45D77021767B6E5BDFCC679670263FD891446C3371B11BB6E1DF60F960AAB4149D7753E6A5C33810
+C42C8BFF4E935003388506F8278BD7CB672F132E065AE684DCA0B9064D01DD620E7FFDFE04F14277
+EFE8E60159BA0FCA3FE2F28B902D4AC275D19F0AC6971EBE827C4A232D87650D2688345BCA78F879
+077114F0463C5F058107B669566F8171E4E284D278405580F04BFFC9902784216E0C9A17AA9B2935
+E66E18A783F723BE044389B7E9D62AA36818FF2EA406C3C1A9D2F3436F3EE7DB8BE86AFA8DAA6A4B
+1B84611350D8D27605509612B515E16AA843164D5D0805E36A2B9EF74C5F6A0B9D59A04B55697123
+27F4B1B30E9587CD103337639967CBDC655AA46E80D2CFD24BEB50815B5338E522B3A7AFE8362AB4
+F05D8BC52BBA9C5089ADA8C89529B0275AF422EB540D31A938B8740860756325B966B36817115213
+FAAF92DE63F6BAE1E0064BFBC5588098B61EB83C71F1C2082436D37DAF1ACBE186FEDC4BE7C1233B
+6F18BEC5F99002D21CB7864E4811F7AB3C03003E1E4490AD1AC793BD28FCD5EF0E6CC30EF39A08C5
+2F71939B0CEF620DC69E31E39D6DB969049031B0C92EF2DB653D97F370141456A52985076B268652
+FA2648C792780BAD637C4D7581FB2D62011D57E293719487CF2D1F013CFAA532E1C2D39178D51272
+A6AF041440BCA174B5CC902BD7390C7D3695056CB4BD7791F9FB6D88E7A70DEF2C97869F5DBC5BD8
+23C517C7B7C39D624DF627DC9653EA5347BFDA80B723F05F6DBB4C9EA501D862ACE05B9DBDF21B70
+56FBCD8C6D4B85873DCEE6166C8B5ADC0316CA12D9639F361B15A42F00E1D62EDBCA1111972FA0F4
+5758BECB31DB38316F3CDFE1B41748C93ED58B67E9B57ABBED5924A6D53E99FBC9A994A6489A8BDF
+13EB685548B4DC6D62DA7426C22227D4D43B6FFC7B5EA91C896730253E8941AFEE588359C2BECF6F
+FC415B9EB6D31CCB0F6C7F85853E6449FA6D627A97A3CE8303F148393ADCCCDFA2FE085C6908BE5C
+3C05AF00A6F02840206C3253A559AC5C049BDDFD11AD9B118403B84DA10AE3C470CB9A9A2D1D7B73
+2F59F5FE146DEDA60AE750F551AAC934621B4470E1BC324C436303E25F81D0DC3188BE0D6FEC5414
+C20E4CB18952E12CB6423DF7124627ACDE145500D77A97A8BFD9CB50D1FAA008E2CE2B2505A4749F
+1EBBB092C347023714055A9B63353AF9E7FEE05BB54C9843698101F79888A91531773830C2C967B5
+88D3ACD2192883D5CE3962D51084FC653EAE2C5FB2DA41DACEFB5C76812D2EDB5B109677289CD199
+8D457FB1023A19AC67295BBC1A9A20A426B06A368DF3C5DD083CB1180D287F5500F2C635EDE157EE
+FCEEC5503447382D15C748C1E35F68753992E5C90F900DE54D18F8E1B355D1076ADFB1F3590135FA
+D1A36F028E44F48ABB149B80CA9A54614D467F8D71CB310BBC7AC7100261092DB8C5BFD39E0AC6BC
+2C9D6CBC3A8C05FF8A74CB21608EC4A4CFE4CBAA2D056DBA14206106044DECF59F957EF8A9CADE4C
+9B19D8D30DD4FDE6A9548E50DB51ACA73330142153FC36B69C1C8D5B26D0C689B7040E81AC2C864F
+D7C097C99BE5953843E172C97AB5684F35FB03A725A89DBF371F08DDF40A1531FC1B676DB0E1543A
+EC6E97D3D2E4AA3D5831D8B3C952ABBFA112352814FB6FAB61A0D680E6640F6AEC8426200CF61286
+F7422CB2F78C61EBAA36D47EC16D7FAF8B4AF31D090CDFA255D9D7C61D46CFB22A7D6E1758E71ED5
+67E00CBD8E8F468DDFB477F091A2F915627F22FF47B876544BC1F03B6BBB98385F009C20BB1AA2A7
+A78674692B8EAC2E3C8069B79E679338DA57F72976810F845BEB6B9ADD32B95D78E5E60F16DD1668
+9C05FD82D36A3115BE8ED494A74DD211D58A2CDF983FCB9CDC29BF7F0E29988FA23560EDF514BC1D
+183F3B2A22C09FB179B47E05ADEF48DF02F31C29875D1915037B19407764A4292FE44E741651A8E3
+BEB5F0D972B6327090F664417C84F84FFBF0AFFF8B1D85C822D90730AB4140C42A51AA8B1DBE4398
+4EA8566040EB8B341CCE23FD3F69DD235A080BA5C69AECB9BC732BC2D7D40617DDA6B79FB6EE40C3
+556C7DF9B23DAD89E94054B1345DB8402AE679FC4655A4A776C0150463F8DB2BFC0608EA1F124E22
+1DDAE6026B5E5D007A7E4A0D6B3B0CF3A2669E67C5E4F01551966A7BC48F2F4B6A87E740D8095E63
+F77C7A027F26B52F2299DE5B8A2F6209BCF3D31CB0235F998F781E5CC81E31DC424E008D46EC0920
+2951E5684804A0592EA47D6C788A20487BEA2EC8F2E6C1D7F378B62DB43CA43C4B366F8B4319631C
+FE9854F0E10321CFA3B01C873584863BBEFC23C72C05E695B56E8A52E89AA2DAB543834D34DCAC5F
+ED08DC51825C5257AE59850D101D84F4CAA1D29FC932F9E0EFFBF7A9A7F3685F61F0490CD3CC8988
+2DB52A757A6AF4C4E67B407BD2316B1C0FFE7DC54E43C87B874F57E4903334E2140B011484863CDC
+ACA331175F2CF3D72E0042855983AAF8853D3015E870FF0807014C31D55060DF3FE1FCE157324481
+2744AB51322444632F9AFDA6706E320FFE82B8CBE242A19DF00CE73EE48E25FF49D5871BD3E60652
+298FE3E8D400609E232E0DDC794C0579ACEF89E841B2EDCA50D51151F65E8C1CC3B01EF1870558F0
+BF5743718C3E068617E81BFE120C6CA16E0924BFC2541177D53671CAA3AB641C41557DCDAE1A3461
+47B5E999C4541B08B4AFCBC187AFD653D5B5F8386DF6AD8FE69E21BD0567DF494F736C6A184FA4DE
+48DC9F347787CA96E2E00A296C2DA05C2AD9BC423E9CA428D7F1FA12DC9353A302FB8C529AF8688C
+BB543B45B2717EBF8F6C497935F4F3BFFD285E0402AB7544B3CA4643AE5A8B5250ED987A95FC1F27
+5B9707ACD0641BD0EE2AE9758494F8D8A51DCE408A38AC20EAF0852D72D84D0C6BE973326793AEB9
+55EAC6FE0A2813A355DCD22F6F2CE56588D1C055CDDFA98878BCEB6A018DB22922D2B600A20F8184
+2E665DF41013CA0947C4237C2BD60A75E2FD1A3FB8C8FA19485730B87461AD466ACB02DF8CA24091
+4FB090B3D2B41EB6B8FF05E1A59D9FD668AF70BA5BB72778953BA55FC5F9F626043450E1D09BC83D
+8605098ABEF884639A37809A32565CBEFB3FF39EE53D6C18C58C272BB928E4410E361E59A50F242D
+69747A032617C52DEBBF62364AB5A96EFAF642D9D82BA679B1D70FAC10A4EB62FA5CFC308E86368A
+AAD7E75948F43598CD1C544A0D4091374D7E88D4522CBE902391641327E888E7748FA889DCE67ADE
+61699E7D77763681CAEE9B1CA8837B2F7EF9C18CBCC538C465C8E2DD34616953CCB6030A222C728B
+834911C1A179E2C770289407AB28B303E724D97F747D6134B425216A64C6E0B60F633E2B85300047
+E4C90339CE030A0FAE31E830C8ABA5AB3386A3B69267351A7BFDD66356AE5E57FB2994452993E90D
+E7C4E260ABAB93C37831856A650D56E44172FECA01D6C7C380F250B82473960D2A2A5FB6B4DA668F
+46E624ACF7FA0FD4490F485D640A3ADFC9F8652E7A38CE5799F770C3606DB4B8B947F93967F779E3
+A3C0572F13A5A187D31D7BD12A5C7BE23CB6ED6192086241B76C5BA6983DB9C93E4B208D707D3760
+F03CD6272EF3A4CE89B8E52E6AC5871A3D03EB975759AB4BE239E5EC7842CBB333E692CC607C722E
+185D3C39164DD320C6945629C70FF66A5237C0A9520A1FAD6EB9816069351AB0F135D90CC0982B14
+7D2294AE4A38A527EE40BE9CDE2512AAEBB590E134388BB171D0956A7C4566D65A9A041BE6C4F883
+6B3EC3D2ED1B48B566A783292B15B6127920D247D494F070BB20BEFF60640B11B276DDEEE49706E8
+B2B21BB40B7F00AAFC594C492C25DCA774E0B80D82E927448DE2E74A9D0DC7AC9260096EAF187B6C
+D6AEAA6D1DC4205B4411122751A5B22688404EA7C5861730371FFAC10F5AFD4727A0E402AB5EA757
+606B75EB86A05E8F774D6E430A1A3FE2A37EBB06700474239FB1CFA05EE44B91B82244C575B52E7F
+AF934B04EEB0D933FEB57EBE326D75821C8B23EAA85B583AED4320B7F04B9F2DC591091216FDE52E
+064BAAA9C2C9D9714B95A4558C21F3CEBE624B5403B31508F178581AF6863083ED762F1E2E34A45C
+FDD71660D626FF8648F5D6C5E580D4765A67FB6159EC8077A9F0A88038C8D3D7C77FF0926E2123BE
+874F7BCAF129D55A5B5960F824BD1728ABCFCC51D23936DE9A25C408D786E44C3A2BAFA4423177AD
+060D21D38E15E23EB6FFC0B4120E814695D423EEFC2744A1FC81B4DF89D76F0A6803D8B14E75538C
+AAD03A72517B86514F6952F6FD619D9E910D980F00964DB325318C045BDF79647F453D4A5CF4E61D
+D5359782827229310405FBCF6107C3AD9DDEF9A9A339D5D5A6EB2E7838A0A43221BD62CBDF732DB0
+A638A52016FB35BA7761AEC846A023D3BF2D1BB183543E81EB7CAC1E5970CDC6F068C5EA118C7AAE
+528D1396E6DC939112DA4460C890EAD5C01BDC438F5BB734218BA6270ADD0DC1778FD8AB16831D6A
+302B814A1A44B07EDC65956C9E6CF4875DF521F3CE5B422F71081B6D69BD270F739095C9E81C0377
+934A8BC6390C420C4E4CDD9CF7E32544C68D884E15ACA3BCC07FC8C132D8FB9D752C15D75C52C288
+57E2EA461A6FCAD90C56843513F74461F18D7164BC597A28AE4BA7C86EE1703535A9B9ED50122627
+71FC12F102E800E0E1AF7BB46681BD2B14B614CEA91B7B2AAA35235DE76C0E113C92688F8EC81277
+D58C3406778E1EC1CC15F1CD9A137C8FFDAAB99ACE3BFC782916F1A877170589A92DC921E6740A22
+B84DC6BACDABCC76E64C79E3A588D80F8F4D376E1B426F15751CF7391102102F0AFAFD8B22DFDEB5
+48AEB5F30B1673023D22054A13391A0EC08DE6E7B685A0D031AABF20B7C62187C0284892D5EAADF1
+21BA28263EB863D5E36EA9C06A77CCFC0E17F593961591F84D82AF823EFE41044C8D606FEF83CCC7
+B0E961E7994DF8A3CC36B209D953E250ADAB8D22D7F2B4E2C9CA39EFA2D93E56195C1560E30A5190
+CC5B17FAEFCF250DF79F6B624A4B917E11C332222FCCFEC4F6A47BD9E75DA9854FC3F7AE554E91ED
+DE144D7AEF38A0E3EDB5E5A5626374DB94F022C8CF549093041DE00D7269B7CE544E748439BA2870
+718C08E58FB4A77D93EBC04B7957D272AE1601D41BF85A2BADAA0DF73B0D3841D4839C85677FB2E1
+5F1D6CE592669FF4BBC9C69DBA334DC37706F2F6BE83D5863E8CD6A30C08640AAC4C233684E66B4F
+E6B62D4A8BE9D531E47BEF5640D9B5C27D990092BE1597F6995C8A77BE9C18AAE6C1CF130775DDAC
+41D34438FC7AD8E042CB56CBF2944932EBA7D053E9376FF398367450E35A1945FE23E05C921096A1
+5454721FFD0F429A3E06DC3ED36F1C170BE79C66996EF8337AFF85B90C5D3A4A94455AE9FA32E211
+7A63E59001F052D5F6223125BFAFA40901E98960ADF7BB886729DCA82FC3B8CC52B37FF2517299E1
+D769057F8154FB95582F02CB0BECC873A9C71796ADBD3E91324FAA94F2C41CF57C30B5897D031C02
+D256C909E080E70BFD1F32E69EF67031138C2DDCD1A8E4B65E485C23C3E450ABDD9815512D6F34A8
+4B9DB715DB2C7A93BFB424316E1AA44397749CB01088428F149A3B4324737ED9957FD388248462AC
+1B2610D72BF5C073ECA567E7385CC959E37CAC7E05470160FFA5A9F63B8E9B082937E911586EA165
+374938F492EDF28CE6020953A5B5CCEC7737F9D9CC8538C4339567AAED3794ABA3B9F4EAE65466E8
+E326F6C399B36355935FBDCB9972F10B13494DC25097FCEC5A6398F275C8C151558E74C5175F7BAF
+4155E36B733F75CF9D5C5979B0764F14D8306E06BA24BF791141E404C69F3F8FCCD91B9C58C2C671
+AAE7D4F9E5D6414E46ED633A5F78AA5BF04E652246A066EAD9E582B181CC196EA2D3CFAA383B5D0E
+4CAC9336E119C08CC6AC55CBFBAE147C623B400453BBF447E96DE036FC025624384359EED7C7D5F7
+858DC0521377CF647A157FC3F188DE5EEF094DBA125510FDE34C570D7BE76AB5DF0A28BF45DDAADB
+EA7EEEDB936332DFE93081E0AFD3FDD46BED08D6914B2EFCFDC41662A33B90B03D76D34F48D30FC6
+BBBB600E90E6AC7243FDF026762A44B4D6E4ECBEF48C9D7B696AF29EEE063E557D8FCF0F09E0136F
+45D17E608DA36E59F2AECF8493F8D62536119B5F7E1554DFE3F6E8D7C9A2C6F557D18B4AF92C9F6E
+050975C3B5C54F9B5F4E39D600B6FA2CD6DE203A174028CBB2A201AF126D1013C229BB82CFD013ED
+199D01E51EE2780FE896E01C63C655087A3E61A7F1029FA5E97EA1872F1B45F22282DDC317E17926
+7368CB52DA9444F6055A3C653659CAD2A1D8712BC2B1B32C1DC6906D957FB88524EE066156ED6BDE
+B8D832F9338F9912E29A250A8C4674E667C1C278B677AEC9972BE83CBA3FB779893FCB8F81A323AC
+91474BA2A2334A07BB5628E905C518E634F6761A3289056F83D5DD7B3890987EEE1C18FB2D379CC1
+905F1AEB3B3D2AD578F0D6C845D2D40C4BCEE3F71C90E68E5417BB8CDDD878D83BA80AD8485F4067
+E5C3CABF28AB56CBB219C0AAB8FFC6C7E192BEC8CBCA1459AE4450AFCC81B9548F40CE2622E5A7C2
+81F74DCC02DAD57EFD92D072318DDF05BF42F1EA8163071E23949B0179CF7DE64677CA99B23CB926
+B3E294194EC13397EA1DC9A5E1CDCD828156CD71F81B64167D4FB01E6002713BD8AC6F82B20CD369
+9C6CA4704DC5C65A2D66EB155B7AF1C9BB46469416FB49C1C7E17A30A5F045271D7DF3FFF2F42C6B
+470701C381E3456A500C6BB3D0E47B4D91C5F34B49BB6272F1F8698B307D89EDA3A1565DAD1C0864
+627560CF922DCF5B34C67860352390B282F95394AA2CDE0E97CE3ED39546A6AF1C52BFCF81A29BE8
+2C47C99E8050E4889E4575B75F39E662F2DB7420673797E2ED3D67CDA7AE2C15D0A0A794D57D168E
+BE13214E89E0209AB2C0EB7784E9491AEFA3C02D0DF3AE5365A0FC4AE023CAB528162C7A1B173664
+9DFADDACA8DA5FA18B7D6489E4229E9E24D38A620464A744A5C60F6F9D334B908706B738AED18669
+8A8B278341FA4D65A0A88680BA484694921512F7DE93337FC1C02BBE6E64AF2DAD07603279D87329
+1D1F4D39C1DD6D89C90F65240F4808F6F1115CA55B88E242565E59F3BBF1F10EC7B88872E9AE61D4
+4CAE185463EDFAF7DF63DE4D2207D307AFB61501892965170D2945846FCF5973A1D458607F50C15E
+06E5BEC715E0C156259AAA6C735593E5564F65F443B78CC7512EC35A56F126DF9D30974A40872E42
+65E1AE5FD483CFCBBBA26DEE426CDC4721F19C3FDA86ED7AD4FA1120F63669BEFE7002B128CEAFD8
+C63E8AC09943B6CBDFB3D2476A026C00A8FF81B1F651B97F310C82ABA5F388CC1DB5AFCFF5996D52
+52A6A42FA4D972E41EE56088F78CB966F9051171C472C774879AECFFF08BFD9CEA40D7C298922ACE
+64F28C14E0B81F4DCADE81D71DE3983D87D905192EF13CEE71B2D3FF1A88AEC671EC318917DF98A3
+C9054E372D22A3CEC82FCC217F47319A40900312F6E32B536B9E7A7FA0837EC65CCDB5FB0D414371
+17596CB39D9382262DE6E65379D3A9709B2CFBABF5FC5D5B352425F06F88CD31012A2A4147B112F0
+C1C0ACCC808CD625E0228EEF66661F70AF96D3DCFECD402700E4F6522AC9A856DA466D55C84F65BE
+2810A1565163872D62EB81333A698ED7B68352CACCA2D7AD38AB55C19E4F5582F75818302F5FDADF
+1DCED09D94872F2D48FB636C8E38C7563C72C771A08C6B1F041F3532BDB39006C89A33C09BE1E3E6
+03622D891F98010BF1DE5355F557A1E09448D486ADEF565705277B31B8BF2B86761E32631E3435B6
+88B79D566F1747BA456DDB43CD239FB47FF7B425EAA4C657C8EEC26EE01AED07CF916E77D53634C1
+37AEEA009C6B515B6342C54BE2C7B95955B1A9DA277A0ABCDA2346E88018C726F481F71D6011AA42
+F8852F2E5749518FE3B3AB668213FE1A05C10A1C53953D75312631D6BBBA01D418199DFEFF8CF548
+6109B099FE8E2F606165FE30F532C03567785D5362AA873C9D3EECEB20F1945D55F49B0CCAC84967
+59FCC7292E46938943C262D78F3212D3F9D0F7B103157F423D71B1ED54B2A603F4C269029918F238
+EC6828FFCEC66009DB9C9E59534EABB183F31D7AD4C57B1BDF0BD2CE5A421882BC10CC1BCE6A970E
+2B586BB221567CCA483989DD0B8DEC424C1D1FF042DCB7834423CF244EDA28D2D969B17440CAEAF0
+24A6119DB010CE366821AFA424D1B8299609C04148275AE6E5257A7ACB3C766C747CE99CBA2D703C
+F19B7CF301B634D8B613DDC4AFE4633A4D77BFF8E00CFB5E289EBBCAC90A24307E7941EC1685CBAE
+400CADD876FCEF7F6557EEE167D2035A05120293527700DC510B038A496BE1D5CBAEF24ED39F7421
+1A93AADF22214ED606A80582485AFE358E3A46D0671148998A3B3BE209467009B43400870359D418
+9A8CEB4D5866AB52D16D9CEB1EAB71C07E6CAA34B70E3096BF7604C22C40D5FBFEEA616DA3BABD59
+DCDB97D883FC8742B8267A16A99B7953225F7144568D566E64542C92E538AC140C851E5D295528EB
+7CBB49909B1CAF6409C9BCCEB325468FA0B5F7CB2987382616B477CCFE4F4AC79E4A6F7165363543
+F04DE5B6F6E1C2E910CDC3CDD6C4C92737198F892337DCB6647BD226C820AC99C65D8E7772BBB74F
+E65DCAA8A22C33BC168BF48E40A82700A3A7668C5A9A71E397ACDFEE7D556C5C19467B7AA69C260B
+727407AC837BDB7D67DEC055C1F45D8BAC61048C45BC9FB3CEFE7549EAA2992D2EDC126FF7A05EAE
+58613332A2BC1465B2BC0429162B907D65F793D236EDDD8D35405866D71B25F62DC4A7E06D4DEE82
+840ACCAABC0774F8A63E9C0F7FC980B3583E7A8B01C46590E3BC04EBA565C2EA94F057D964A78A90
+EA9F52ABFD70F84E44E434BD10A42E98C794065724341F907E35D3CB257161E01C7084E3A0166D15
+CED65DA7BA87DBB2EA33D39BD99AFB93D3548358D08330E807F8552CECF63C84F805205491BA3A1A
+622E70C232FADF3BF2DCFD6F0539158D3306506F150B0518371912A25EB96163D73E9EEED42EDC84
+D688BC7F7708D9DCA348FAB4DF62E5809BD094842D0A31DBB7C4B41F94D946810C5EC10B69AABC2C
+91A59500B2E5D37F4755DDFB7AE4ABF757F4C5BCF77C7F95E6A616646456FE8F18407080BCABBFA5
+7704287AD26222DF91AB2613951E2D679472F8ADF06EA2A20205EC19972299A78BAC52114334470C
+5F5890C2F846B4C6042D73945127F2E3910ECA1C4CD7A16EFE4B4BE38A15AAA710682C3836A8CA83
+FD384970139D8B46FB0AEBB002DD224199672FFA02250FBCFA4E649E335428FC71F50F45E498419E
+DB0E970F46894A48F65580881C9C4250FCEF65C9B28699408E18B26FE6DB7F1CBDB767564E73CB59
+54C6D639CE33220C894F36E70F71C9F9AA3FE2AE0AA0E3F2E304EC5ABC661675CDE2E70519E4220A
+E26FBACBD01D5169EB844750753E6CED53E3678FDCD08AB93E10067E9C64F38B40B76D99B6CD92BD
+F4155A1EA5CC824998B59AAD06E09E5F15EBB2288D66EA71B296616734FEF2796F07FF0D8B047074
+A1111D68B99C2B70FC56E74A51B062F4998ACC85B1943C9477E436E5CD7AB18DBC898D21BB93475A
+623BDDA71D7B895BA2D4C10F4B90BF335126F4FD57D73AFA50170F6B3C364922E551D40E35DA75FA
+891762FA23401D39260F2E92C7807C746F13BB35CEF9DBF2E76E66A72FEFF095DA482A4DE8A42091
+7065736CF4DE904FB52E649A32255E2030A7B31B686353492F31C064A3C4B0448C4BFD44B8E15384
+FD809B8761EE26A7DFA1758D57CE4F0BC376EB2B3833534B15A83436BA553955ACB5A7A66796AC5B
+92DB5388BC53EFA27508B08E82821E5CF669BCE52BB860780F749B4F38ACDF5FF12726BF3EC2743F
+01014CDE96FE6B4C40A034E9EAFCA2A35CCC776C2669E6AD138070A40F48ED79136D7FF57E993E09
+B81C543FBADD350FF5B5F7A46F060F88E30FE2D8233832D18B6C323EE017EBC1DF5C838321CDC8A8
+4CABCAB20B60A1A3AA028F36EA6E87C850AF8AF7CD50AA6359038BFA8818821D02CEE8F51DAB8C05
+F7AE9797814D97F3DB8CCDDE45B21DBB15CEE292FAA534A5F317B357F4091F3DA357325B8B9F5EDB
+45865415973C143E5E5BAA483FBF2D06CDD4246675EC58B84C6AE65CA743117FF00F229243772561
+31A7F2BA26A9115AFD96C18216CFDF41B7220ED0CB3FCC26C36380007B382A02AEAE428887DC8BE5
+FDD630AC57EE3DC156C7B8B29E687F24442E35CE10BA4087295A641F7139C831F7CCDA6CCEB5DAFE
+537CC1A97C5A337D3C48A6AE947F58A30DC08CC7B58DBBB4737AD52783C573FC1E9408F55495A80E
+7FDA61F0B9C4F090158F1A416249EBBA936C27BEFDEF19D1BFB839EB70576A010706D8B95657B218
+9C2AE04C11EF9E57FE09880273761FB4302C388BD608FA0C7F00F033C9C00F4E3D5CE2D903E0DA52
+E69C7745EE9FA75E2AD93DC6CB5CCFCD3782A699B807AFC36AD1F62B05856D5DFD6F88831B90EB3D
+CD523582A49732E3FD7253126D39E8AFB8458B5F7AD7F94A8DAC13365F433C857AF4A42C0A08C4DB
+9887C4957259ED22D13CFDF5995DA957EA5A0F620B0214FBFE08AB6D552DBF048D62CEF6EFF12F15
+3511ECA7833E0E3E95F85E6AC0F95438AC4C126E1F1ECF336ED31CCA7EB216D279877123FD9FCD8F
+B5E52B587CFFC4428456DDCA816819A8A4A211D8F1629E5D42BA4C5C356E580C8A22C61D987552FA
+A97893816DA73D423686E4EBD44375C257F031318865A20F22115E72BF1EB9F93AAA169C140A33A0
+6C35BD4526A38BE79CF40AD1EFA10411E8F3300A8A8B97AB140EE6734E1BEE6C8EE443D698D34159
+97649C6F10F20ACD80236422E215E146D744A262DA3FC88DC0D86FF66512F49D3F957D3C5CFFEB42
+4823509F33F155057A4C6F37B52F4667767BA94F6B8B62856B553F307E5D230C44CBFDC9A97A45B1
+39FFB2F2565EB0E22026972FAD0FB7B9576FB6F368B61979943A398773600E7EE1DFEFBF26D45D40
+BDA66EBB96A56EE9CAE0B2420C5DD83E24DBA9FF885BB844BF3D2BF93B07325DFF60C0CB5FDCCA0A
+C8FB5A2E119D5AF26E53AB8E3B428481C2871DDA26EF0B621CD8572B3C664BC7AAC01A1D05B98F79
+1A7080D294BE81099BDA7982432F3DFF4775C44D23F4F1B2E0162B61A8B2CB5EE8564BF98E2ED403
+2219085FE6194C19DAC98A421826CAED7F1AB1477AB327506010217283894235D7DBFC1153D5ECC4
+8AA7293F19592B4D7E95FE55151889BCD1D7FA7DC2370D2DFE11D7E4EA34B5C7A8E73BD3A348FD38
+9EF45B6167FB90BA44C23E912F9A4F2FC0427ED070592F7110183BFDB2C400393BA7569058227926
+351F07FED4F33633BA03A72AA2DC6B598E49B96021DD868DAD0F352E5722FB714F667C15C68D49C0
+3D822D82677EDFE86FE9668E537DA284068C9B0AED83074C92A5B939296D505B837E6A9DDAB1AEAB
+7455A08A114C2222B339284674B74BF4CA9EE0C020BF2A148B439C71C6BE51A94CB64FBE4A7EB295
+5A455047CF5CB348B062ED4F6471CBC3E9ADD9BE9B96879AC7BC71BCE02FD02F17C6063985A5E898
+3D205AA1489DA13C408990ABA1C54F2F501AA172F530480D789C848118C0A74EF98D5F607A067BAF
+F6030D887AC6A6497F9A0B38F9705F328AAD4BFBB634F739386177B07F22D5771282444E5EE17335
+B4D0EC86117C697E79A5F4F65FDC08E4904DAEDAB20067EAE2448FD4301849E456D085F392DD1316
+7ADF75CCFDB723E2904A9C0C976D6B84DDEF9D92B0E15FB246C3ECC2D0BF314CFB957757B3A3E8E5
+801F520644E4601D291DA0F7507C06F3B9BB36FC1C70EAA444E14E56C0CFF06C7F853DF36DA9D8B6
+AF2544B853DFFF535A7E5C6FC145250CDDA229956019659D0D253A19A7B51A4E538BDC01F74D7704
+9949C2C97C7EC6392C2E61CCC0992B66DAF1AB08551063E53180D2A67DE496716CCBAA45462D9F91
+B66A22545962DDAB120511FF08627131B95E5DEEB8B4DD9643E7B2AF65C0FDCE11F5F1E8DD468DA1
+8D41C8C4F00EA73836F4F70EC50FC3EC6D358C0658A4261C6D15A582A2C7C994E7882E661855B352
+014576858A265FFBC425160669CE159D07EDAC04D060B44E5800A7AAE8E339C29B929AA81D2F515C
+46229D2080D5917AB20AB6B34FDCA8E4AF64ED660A3173786FB1A1D005D575C2A5187D3F7CFDC94C
+CC44A38C5CD523E9DA726D8EFA6DA7B6131DFF3435FEE838B2C7D6B97934295F06202D307FF78D90
+6699CB9C5BBB10D1D4DEA5FDA5BFB094E704607083B646D37F5DA1FC7AD21B813F44D8C1AFEAB666
+55AAA19703BEA2E77DF3BF350E17C74B3447A452235919452B5175570A006C7680AC05E8950A62E1
+1D7E3ACA35A397D1E19630D094A86807593C97F4C484E4E06BCFF708B6DCA972E3A0009E1CAC0EA4
+141530F5C1B8AEF5E1B933F37FDDBC4BE22B74FE346D1A3F5FEC0818F8E61765568A2AC04713E828
+F98C449D9A1CCE52D10D61DD8BFD084C8D099A75D89DEA64D5A7CC68BD5B0593D97953DADA976383
+F5015915618AEC56D71D1DCD55B89736395C609B315A3F1E1255432FDBD37F38CC43C354FB4B7C44
+F1A7318B0B7E99C3C08C33B953727B6A6328051783A0A33E3CD9E498346A3CA6A77B517096EDD52A
+E443B87643A646C3A7BB97F742888D33F9B3127E61942F4103C1DBDCD8EAC8F9E259773066736CA6
+53CE57E8822651261D847C131321BB9D6626A1AC50D047C0BA47B411DF2A995545BD68EC0287CC9B
+31D5DDCA8755EBEB10ACCB3903AB0FD5788E984220443B8459E7C078DA4289F1350905881AD6DFDE
+C47302B0ACB0D4AF8CAED02B4B70DF3CF8FEC118F0FC2D3DDE3E494CD160E676E300BC464BD4400D
+B50EE43B314E0517037BF971ACD7CD327CB2134893B8A0410E68DDC518F5DEC966C7884CF5FDFE74
+723177F20DEDC039D879056CAAB4BF045062D3904F615C5CFE109AC7A35599C94024B41019B9AFD4
+04A80ACAA4837929F5C9317680A13D157A03B59A5588DF79D2E113F5F51021D6F6F90E8BBBA2C252
+FD10651BE80BAFD59C53A3367BA3C28DB6EB9DABF1EA99F47B503F627E15DCF3FD645FC52C5D5D0F
+2F07DB4C25C0D1E1C00146E1C4D973E613CCDBD3F9450CC0F5343D79F05E9492E86A1BB889ADF405
+03BD7F3E7543436859184A5B20BD8A172F350D846B7570803990ADAA48D4B9155A2B4C4BFBEF1E1A
+065C08E03928559735BDD442FF1E83E1FA20A5DA57D8BDB2FF5427C034CF0128AF111E6E73099E04
+6E0C240E80A73D7BE72B87834E45898D475521CA3306707631F5C6136199F354632D1A085F12A1C7
+C473868B62E534D15F5484323E63D0574196A19EF175214EB35A90873EFCFB92D6CF68761D45E37E
+AA61E1A1979A82009507CA193E44B36A806486665CEDBCF387053ACEAB979BD35D30978FC7659ABB
+E844F4ECAB3303318ECE80777A5FA5A9DD91B3D06804C4B4E9B4EFCF07EB89866D0DD8CA390CFD15
+98651417114D78776B1A1D36B4BA17746D6BE7FC123D473EF1EFED1C3BC1D555F914536869FD5B0C
+35F9C83F65B0E6BF7A627B9202D787D72C600DDB6BCCE613D88492E13CA0AAAB196E8A49928C62CE
+A4FFE2D0208EDA334ACF47F20BD793124D2C5546C03F4A364369A76A0425262F9D9118AF54E37D32
+E33AB25DD533A49DF5FBF1BAF4CEAC2D9D378CDCD13B00FDA432D9042F623DA41AFB80699B5538A2
+5403B0B3EABEC9E8EFCF42FEF3EA9F91766902CD206B0787C187D5370B60AD6DCD002DE2DE8DCDC0
+B4719A797C5E26BAA67665016DA0D967FA1346F9588AEDA174CA001B31213617FE19EA218EC23597
+79D979E2663166489C06993230B0D07973A117C4E3F4A4C93CF8428248DD5389414D679C69644142
+67C7FEA17E35B0CEE456667A9B1875C81B2302BDDEA2818D6019FC1622A82051F60584ABC904CD91
+8676305DC03FFBCC64FDDAC8D8AA9CE2EA00D6C97BC63C8A617DEDFC0E40775649438E9F61AFD179
+5E3B20560B01BE5E0983F136CF48AB206954E41DEE0D9DDD953DFD01CAEB569151D6BC0DFEF29D70
+FAE3E198E7EDD8922C0E0BCB8BCCF1C016142C1A8B337AFA7A05A9D7534B184BF3BF827F371E9BD1
+9A71244ECA1BA73D484CD2FAD54DB2F0EEFBD54B536EBCB5094E6BC2F5B2AAE41F05B4B311115876
+ED42C34F8E643B53372E3F6350DB8A38445822EA9A33E27FB0CC42CEDCD1FE2FDF723FC47C996EE3
+56C402112F24D0AF899B2D00BEA1CFD427998BD22B2A09046D6737814448ACFB10D387547D7009FB
+384AF0562C85694C071584236D0F1F3D3FCD0CFB38B77C81889061E668BA7AB37AA60F58A3967DE2
+6F939B79CBF10A9DCC42852561D8D6754F1B660D216AAB1E133FBAA321C56E2584BE5C9BAE20CCF0
+0E8DBE6D9C2FCEBEBAD945C3C04101D2387351F132628786F6D9D4CAB83419288D31F9BC600D9664
+12E6AA457CE6CAD26A4C0671097B98C2384C81DD8B9A3222D4F4BBDA7017895C3EDC26662779AEE7
+40D9D7E24185FB821970B0A3A94041A69E4805EC88EE1EE521981536F2844FB8F5EF645F67D42CE5
+148E2DDE43AD5AEF200EDB3A2C7866C98458A92666E5F9E070178BCC39F65A893102A10564AF4E8C
+AAA5075D2F8CD7FAB0401C03AF299EA3515CC93066744EB5AF7CF0ED06675BF049A6E3C211A89E16
+DE5BF0445A7CCA6EE8EB0347454950485D884606651E5887FE8B24323E2AA16DE22FC1FC8C4F06A8
+2A1FDE5758976024068197E1F4506E4D3D8A16D40461A4586338B374A592DC60334402F76388AD6A
+457DC3F54E6169CF7AE3959676E966A45609621055EC3AF80E182633300A4418E34A66DDFA6B569E
+5A13C9115B5FD3EC1CEBE50FBA247F60803AA83976F00117536342DC3D9890C49B2AC701D370E43A
+955118967827760F7091469C5406F08F18D7E3548148CF0E312B1DC71DF67A5E7A1656CF2F47F3AF
+F3DD50FFC2FCDAB7177285B29C17CA43019F62AC6FBA52D1493ED7C427526470ACC8389BAE827759
+4958908F517B2863B83292EB5AB3F57FFFB08393CA610FB1FE905D88A0A16AC395E2A2A6DD033D6A
+0D68992F830B2E1B95FE357BF672716E88FFB92FFC3D62945D1EAD22BC68C51EE0E10A43011DB94C
+44685A5C4576F6EF44CBFB45F2A4BF110A01657DB51FD499767E78058199B31DFD60813F1A344F86
+289F9378231D5B151C92385E3650B4FEB1DC91018EAB8474CBF69FDC1496A4D078D2C351C8196451
+247A9DCF8117E5B637371D8E22E248C64D999015C3FD2311E9950B8EE0922FBDD3D7BFF766BFE9E7
+CE0BE12F318FF2A7B5A9C6D00A54401609304ED2C55F5C1EAC3D4B38355BBD85D66D61636FA6E30C
+2E82829376BEC979A6FEEE040E452359768ECF90CC539A546F17AE906C76F14F86FF697797322B05
+1EB311A759FE260C1EEE5DACF383816AAF1294CFFA7BF87A4D9BC595EE8F2C2F86FEEE11AD959D86
+F22FDAF4CEC098942A57E57813A0FA99239E994FFF353C1E781D666B8928CFC648FCF0869FC68468
+BDBDA7D280DFAB8B0B3A4CA35B074B686DE8D372C61FB32305169A1A9912F6541DA16CD6316A6EA4
+51524757BE5CF6E820011BE3859FB8B8578C100FF029680E05F0E0BF11D33FE19460C85EA5E4C0EF
+28E29407C8AE6BE01CFA0D5022BF9FB01416FFF722A784DFC8FCE330EC95737A854471D334FDC58F
+AB42867A7B62836A8B56466E9A6C1247D46EBAFFB905CD4321970F59FB8D6FF65FDDD34BF913AD32
+2E68455C5FF2D23C1A5EAE687F259BC982B6A384D35440F7C693CF50B9ECAC0B5578CAEE87588B56
+2EB6B7F42034C9F2E545EC866316552354EB3728C7D26527ED75174EAF635E048B08DC5D23E88981
+070AD5641A652F2344956E9CF4C16E652A99F4A644D1787D6D36537489DA4D74E61B2FC4DFDF1D1D
+9D58F9C26C5EB63200526AFD168AC57D5611ADE4D4A382FC28BB60F9E7D626A6C67AFBCCD1183C5E
+3CF2EF210D0BF5CFA7BB10FA3887BDD4CD96EEEAA8F9219AA2F10ABC0A960C3B57C0EC0313AE10CC
+FF1F522124CFC8D2D49BFBB0C193EAFFC5B48FB3FF30B21CB76F0A4C0F1377C9223145BB0468A5D7
+1B9BC25873EA12E1C60334571C67385C00D0B570D3FFC6C7FF0DE62C183C76AEEB12DFFEE1459E0F
+C818C621B8D12FA1357E2B55D48935D70BF140B4CFFE8813DEFD479350B20DC2EB1D3CBB1A2D3DC6
+EE975D58C89D61FC50E6A0197DA9A586B72255023DE47DABEFB11E8AA02414C2FF6258A281219B9D
+DDFE41BA7D7977D0D6F18224FE22F7D4E9355FDB35BF7ED3418F4F68D093AC48F7D8FE4194FEB6C8
+0B9DC1F74E023C604DEA27089F98C3973FF9F4AD7BF7BAE601DB89B08D5D8139B95EDCF6C885FFA8
+B3E4B0477E7040225733826BACFD1EC4A0DD72DC41734856AB9FB700DF83CA2CE812913BD142D84C
+5C83C0B2583768198AF9E885F2BA74877A414233207234AA5F18840557CA11682AABDE8993533887
+7C6D404BDE4153C9827EB16D66C1D73A8143C8A2D3604FF72CE579FAA3C5224BAC48EA83BA848429
+9472007DE96466B5B29ACC7C03B05DCAA38A48BFF9F214DE43146AE4E04FA705421917F99BC54533
+F0EBC01849E396216B9F0794E6F6C6B61B52EF1B1950C0FB609895C3C55FF574163FC8B6B09E66AB
+AED1810E698FF37CC1F926B2CDA3B48C7D77790EBD2D514B6F385D397F713EC3AD3954EA9C846158
+6031D369E8B99E53408A79D64C34EB5A56DE8A67DE91837960E98A66FC04DFA0EBDE21DB003234BB
+78665B039D0A469A0221BD541AF7149A2A659C300132C14581EF766FFFBECBA8B58A5EB3F95446DE
+F49AF863A8113D17B2E7E6ECDEAFC3834D4DF900E3475596E86FBB4E2974C090DB4AD61A737D611D
+92B4535AC291C56AD8B1C031D2F9B505BB77517B737D70AB3723DB52AE2ACCD5DD2F617423ED3CC3
+9CA882EF41757BF7151806A9B8B0F312808863E3673FB54DE939B35CDECA7FBC4DC3BDF5A5F47D35
+E345916C39366C8B4F439CE1C6F1835C320BD1E67375B03B5DE18C93256F251761A4C8CEC01019C0
+68E34447BCC503B9571FE8000627A6B3DAD5854CBC0A2D69E5A8F46BC78F6A7B1422334EC7A98ABE
+FE9B83E01DCF3C6C9273B346F3240EA225AE4A4083CC7B0EA141A0773FDE940768358EB4B13D82AA
+304A1386D450C1C0C6A7D5A8FD2BD313F78F85248B5196241E31E5595F3BC01F37700A2DD3D4A0EE
+2DD01A36569CD507130E8F5B1E96CB560BB7DA15560CCADF3B2C9804A11D9E8055C9EC70E48C1D21
+3EB756A1376F2EDCB7189D78CD3D6CA5865537EEC31C17D801605EFD860B0B629472690588D02575
+02C6F7A75B9A1C1B397781329832CF3EC43C09F1559CD562C48FA9500295CD3B0A790DD3FCD4684A
+7C7AC49AC9BFFF36B39A9FB148BC28D37907433943CBBF0CBDAB46D3EA86DC8F81C859C52D15302B
+94A9B51C199B7104DEEC9D769C2634CECF8B700CE9C04152CC59C9326BDACBEC4312DEED92DD087A
+1C4840868D9F97CAC046581F762F75E8D24D6445370A3F1E0AE74A6478D9DAC37E7FA5BEBEC0A1E0
+81AF89C1BBF7F51E3E2E22C8C405E8671BA85F1BF0DF79A465DAC7EC07F731E00632E017D190A99D
+83E27E5C2E63D7DABBA23B2E88334C63721AC5A4CBC5D45F4C177259F34C2EADE01FA008AF65EBC6
+01D8DD16436D86AA94C99F3CC0A2F87134E73BF22F108B825A8963B49C6C685474AFE4A542C8641D
+C0375D7EFE9AC1168D9700459BE52D0DA399023E141969F25C0DAC4668534B6647EC85454BE945E8
+26B26DE6E3C4584B97A38E2B40A0D23481BCA78084FE80E00A71A790BF31DF468A435ECC88E60A57
+860BBCA3D65930186E9917CBD209C230E8F8255A7ABC7D3F043AE4D7AD63D9980BEDF062B7D5C298
+C40225B6D03F29A0339E0FCA02138E526F06B9EF47F5E7A8068A846CFDE2BFDEBD24F5A73A66C079
+18662AEC80B43246284FA4E2EE0D9AAB172B1E59A6CC46B801149D8C0DF6DEC9A55D8E1B0EFD9D30
+2FF618075944CCCB6831D336B11617107B0530D09885E5CA11A5F1FCC8D69D603DA16BEA51116D42
+CAB1AA1E4D7B9B4D79993F2BFE53EAC904FEB70B2D330A89780EAC10D12CC0C35B8399F218AC2976
+E57A26BAD20CE2FA2AE2363D3FD2A8A971747556F2959DA74A8963C20B504711AE1CB0D0C02457FF
+2E9BF696B159AF031DD5155F21C0F5549B0471A3C5DC8918B675CEBCB23E29322B959ABC05283A70
+2E878DE8EF25EA760F3C5C7B7B49D398283DE2ED837FD59F7C22D62C58FE4448B1049FDEBFC8787E
+67D7DAFE9774979BB3802254DA59BCC0219F98C219F84D995CA768B8B5D9D4A32525DFECE003675E
+E4BD5D8DFFC11025AF2B468F9207B5B2B42349B98232BAC0759758C1F4A283405815BD7145C93FA0
+8F3ED2826655053A3C2559073D8ACD199DEA2C5BA5F616A2E48548B4370EC73493BA07E197165DCA
+774438B0766867819C1154D1959FE6E01E6312E0AB91FC2E2BD240FC8652A2D456A1DE7F34EF372A
+53794D4C4E050BF3CA5B7BD2F1B8DE93B4C8002485CB219AD2D029739FD3C81CC6E78EDF38723576
+1A57143EEDE5CC887F282FECD261F6A25D0A7E154ECDF5DC38E426811BE86AAA458577E5E0C5F0F7
+5AAFA9C41E5D1DC9D91ECD79B514F8CDF7A5F1A189470D35FDF4F9B8788879CCBD91B427822ED658
+389E981E0EE5F7FB87692A3E3E931DF8A1D1573E3B0166204240B7080089A09EF7487C9AEE2D665F
+5A82F94C877FB5B0DC531CEBF1E71C6592CEA2401E4B5122E5091DF03D203DF979B9A6EFBA12E2F6
+B422FDF15D49AC0914D372D21E871DE65CBECD105FD4A3E4714B9CCA5C6803FA39DBB015EA8A88BE
+7913502E562E5B170B87BFC8572DC9DF49AD63694311EF1334444BDF0B4CA3245271C1F7A4D7FAF1
+703E3AA0E1EA8D5C6E821B28707EE0C9B4F22F23796FE87356C58AE2CADC191F4C58E1FB58DA03B4
+5A25AC95DBAE13A293474217BDB214742B9D9D6AF35F70FED2891942EACE3E625E55FFB820543FBB
+250A062D3D395BC0F219ECFE0D76686AC148BC41476A887BC494DDBD396BE200FD3E03CFA12EC9AF
+6B934A283C42AA05589AA6B4A8D16946BB51F50419CABECEAEC5AEF9085C9989289E9B46BAFB6FB2
+782D84DE2B068F91A9744AAB237CEB1BA513E57E4C307108E993C972A3E0A898D5A8D27833155031
+FDB98863C3BE7FEF3004CBAA5CB60A1F2E3EB4D7290FF5FAFA088B1CECCB6CF51A58DAAD998F0839
+6CDFD68F5ABC9C1CCB8F6514107773C69C26873E889D1F79D10E866910E4684186FCD71C965ADF62
+39BA3418B313A27AD632300969B6F284519366ED85E7CD968D64823F8C59B5911A72D0A20EB72B60
+3A61E36F52F256FFCDF706B4560B4DFA5D918FBC530D83A4B3C01BDD3CB4572E24242D141BF9E775
+36693A0407D002E09CDA5B195BF1CCF430AE9824C07928A050D0B460F2704BE8F9E647A4884C4567
+0A81EACF7CC038643EB0FF18A376FF6F32B6FE4F197273327FBBDEC6443A299CAD4B26F7778A99F6
+5A11BDE047153E764039EDB251936AA43DEE50DDFDF8856519056AAFC4C5AE6F2051AF0579A9ACD4
+1D00775D7DBE70022CC263DCA5E0A25B9C7C4F5C418587666B2FE24816B1E0EC92F9074F1403BB83
+AFC3F1D52CA79C387BDEF864366E34C90BE52F7AA09935373A07E4E026224E76F9EC3CB9E7EDE50D
+EFDA48248D61F3CEC880A3B8843306375D9711E58645F3625BDB8E87052DA67F9794EF4AF8DB0BCF
+E00677C3A26907DC651BC838C40EC39E2B5A5DC0DBD345944A6C32226089D63C52490FA10B215AE7
+03CFB663EB8A47793B84CE7364DA1C4E7FCE32DFEF09490121222774915BA59C78C2275F829D15CF
+4D8686B095C38C731B83D48738C25F40B8ADD487C350A2EBE846C3916AE384CB1050F9F5DFE09FCB
+D9129C6270FD86D55A459618FDFA4F907E6B4746196BB717865AB378414029017551161A52E9D24B
+E4F7EED553A927933D4ABC8F25DF607779A717909CB4D810DE8F5762581900E224E4B91598149BA4
+71CF8068ABE8744356B261600BFCC57FB8BE45036CF6571D9B2A95304933BD4F17215F8EF53F8E08
+1AF61FA7F9583C34EB5655CB0ECB82246959F09091F36989EBDD646BEDCA614B9A61AB7696B3FF18
+1058A150FA6EC1BE2EBC7F64357A3FF2A2B0491D2F4E0B970DE5B7788B467CA678039B5EF55C88A3
+84578D427FD2CB16C87B0BF0A3D37CE8ED43E0F049AF2436344D5F47C948C632C94A287509282561
+6C64C5D262FE5B24916FFEE982A69A6CCF888BD01D62EA591EEC51F4B7DDFAFFBEEA93FE08D736C2
+0129E345D06B10246A5F57151C198D407730713F32299638EFBDC01367E23EB59AAD42A83AB41B43
+2DB462652E29813740F4680A5D4BD47B18328FAE6BDF4200CFA4CE3773809B45E8887C9B2E423698
+9F6C48D64F5986F563D9A7538A8716082F81936AEBD0461E6F4BD470436D8B7656F0FDF89108E6DD
+02ABDEF907731D458D690BC608EA9CED09EB1E6E64C0790C7A2378201CE997FFE0317679EE1D4EE9
+F91157449323E53B4ADA8096CD628B5861BF794543A98F2FA2AB54FF0F25A13DAD43DAF9394329B9
+5AA53CA32749FECB0B2BC035DD1EBD53FF9FB5AD8BCE06CD89E5568091C1CC314CFB1D9821D7F9AC
+7C55F55E0A16E39A87D43148201B928F3C42B110FC056189DEF183745F3B637441DE8BD4C3C7EF12
+F4258E306B2877ADAEC63441010750DB4E6269A4C78A0AC01BB3603C386651FE814031CB5D8C1F14
+9EEAFF652A53E57BBD4C8C0CE36A84A319A53BC1E5FD3F1ED1EE72F4C1A9BF264B594062FCAFB22C
+C1FDE3F2E3D3C17DD3F7FE0E15EBD812D550227C06D01127385374A11438ABD50048E17255FCD2BB
+85122A6FB9B7DA9D5E9DE8A747FAE0DA45A1FCEFE92B9E70A5B2CAC668D4D07527A5C1403267D823
+048BE671F725CFC7474B44FC5AAA348420B2D7C23C6CA066666FD6F2208E329878D90CEF1C2E77ED
+22D3BEBB9D547810B189F08920A27E7107F208591A84D463CE2576C70C3DFE6643E4EA93F4E1DAEB
+41D46F0E2F56FC10C69AD5034FC9859D31CF27A3A1EE256C93111F81C11ACF1FC0CE20B90BAC9AA3
+27A5C85A7985B951519FD4B03C40BE637162AF41B2FDA68F0D1E9B7602FE2659D3D75955C579AC51
+DF6A552EB9581AC3F712F083F19B52A6C4F560F36C59CEEB0C996AAF1728A2AA45DCAD79BD7B23AB
+388D5B0B64A2B95154B6259B730B0F4A72C8C7F7CC93C7D64D9D8810D1F63FF8ABD4DB89824E2D26
+4FDEE916C41E299211DB1A53256E1DB5CDD04862F034D9404B73183A99D3D13D642A663F129B6D16
+7095BEB4EAEFD03DF2FF2F0B6B594C1EE90FDB203DA89FACEE23F1BA3901FECC75FE1811BD701259
+343011262B6A0A9707AAA6316BC3C17F787BB80AC8DA5AAC942D90F80C5A3BB59E47EC767244AA95
+C63E50BF809998957936D3BF6ABC24B0A397258F9EB4DC8F65692CB023D9091FB180C69498CD0C08
+BBEBADC84A7E0016E8F8BEA325D924EB0DF82E75D2CC2CCBF039B11934363D4332C5FBC5EC556BE8
+5EE4E707CC2753CCC43D2ED50558E51A104221C9323CDCB0199B7B83454DE3FDC810D0F362C0299F
+5DD981B31D8E3DDA284FEF9DC8F9C8DE138D3065437A7FE8C30572AD06D62E8527AD37AE39AAB0B2
+25F76A25F6C6505241ED73BA494CF923E919F688DDEBF193E188F8C4C154F21631080763B4D091E8
+AD1D2FD6649E0CD9360E8D1A67A5B5FAFC67547CA31C95A5EA8D4EB5D68B9F6D6532DB9B54584735
+9558542A2AE58C09F3BD2918EFBE1699E9C8F2C2A11EA4D224C726D2ACD4A8D8ABAEDC6588CF2AE5
+66528B94F55B823A2A1F7BE19000F3E7579D094E047075DF18C8C868760295533B26EB3ED90635B1
+29C17ACA679C3E88B06998CE5A7A2544B700229F5A6A504BD3E45B276471959C8A3F81917A534287
+39B5EF9E3D463B3BA7318448E2A3E79520D2D245A2A72F31FF7070B6E4624E3A5E216BD103640C8D
+F387E49D732529C611F8B971073F17EBD2F6EB18F9B74A67E1997926DF178D4C9EDED435B9682F1A
+279C81BB9F60DAFE125845A2FF3B02979E5481C78A45C479BEFB9FEF3CE2BA9BC46C77B50B03E48D
+A6D17B76F06F3AD118371ADC69E178C52B5FB4B261C9311874ED07DD6D5B3226A005FDD7A6D53848
+09E7063F036CDEA41619122635E835D2D74CBB6AA9B38CAA4D819C26E95115FE0DBAB4198FC5838F
+2C91B7A87B07D734C6D4F4F83444C1E90AA9BFC908A2BAC4B3DEF9157AFCA5248F2DA31CA87BD363
+AC25E9E77F741D4B2C6E02F04987A6F49D30E9038CEFC41BA172DD675AED8B392164411144E5B738
+F3210B0E66B17A13CB9631C33D44484E792A7C082DD0A5382F34C5637653261B1EB6D2035B08B4D9
+1FA9AB770CAF40A103629511F7B43F2743D7E583433DECFB19C21FD4FD0AFCC22A4119E77C87BFE6
+FE50068B22479015BE5A9F06BEAB4D37412E062A45E0CBCD7BB39FEE747E96306F79FC4F2E8942DF
+5D9DA0E55AACCDA547DA19D30B8404FA121298B44C9CCE198C708C69A8D6BF17591C5C50D3FC5BE6
+961F7ABA8F366DAE957A1C3730DA4A5B4F035A9274675EE3BBF0CA8CE9D8349F50CABB1C3EA4948A
+BE6F9F143592F1EA95404E6909A909168E3279A957AE1924245C356331A75E7008BEE92BEAA304BA
+40B7C3F48F74D9018B3247DF50EBD7CE541DA48ECCB1B0BE51A455C3C13C279D4D8676078C3EBE43
+08748D52C9B041D3E7244C745B1F2F742D010A9E60695F3EC4FDC1050AC082B905D6A57E8F407A3B
+472F731011A5798965B7B1A307E252FE02C8F79CEEDDEB6E165F1A94D7FFF18DDBDF79477F14E9E9
+3981ABD200FE7771B29D1D2D120EE79D28B9543818527039AC74085EAFF241B56D08220C958B5D9C
+87C0C04A14D52AFD475B542D391BC54FF33DEF8D9484AFF6873BEED32DDA4B371112B523B6CE22B4
+0D1B416B64C9370F1CDF2C548F4CCBE9E12E21C36CC3EA52DA232DCFB65F66B22B5E2EC04852510D
+5E264EE939BB67AEC4764B87062AEB7F680B40BCEE04AD45C7519EB3B6199C9E0E332661463647F2
+FB7EDF303EFEF84891CEBCF0FAC5F723A9D0476C3F8C092604C87FC69C7A90F4D64AE45A478EE8BA
+2DF50FB93F55A3546123F0B0E2C1C40C98EAAE9F0F26B8F80FFE6E6B94B7E27D2884D58B8A119662
+2DF6BE608C5569D7864BB756DF2EDD184B90812B44ED4A32D001C31383A40AEEE9743651F7950846
+15C48E402DBC01C818D477EAC0347795CB2792E9C11E8FD4A02E194EED1C919D4598FEC003B6D9A8
+A0BC7D456047A1C0579453FC1D7CB2D158D466939A23D7A7B8ABED7E2777EC7487973E73F2266D9C
+250CE30729E3C5223AD93B9AE8443B35711E446A3DC660123ED45CE1942A1A2AD0610467E081CE2C
+8B92A6C82F0B17B5D2429E99F1A6268072C6B5AAAA6EB6283A872C54D3694CD825EB2926E57DBBC7
+C1663075E687A144E4D61C225781D80FCAE1497B442342B4A3F1CD6BDB50E31791CC3928C30835FE
+F845B6BE5E2D7E3F2F5F085AA3FAEB45CAD0D76BCBB1ED859A9CEBB9F7457036F0BC3F195CB1A98C
+9C8648F6583CDBB23894BC719D68C2DBD8003B10D08C8CAA40BCE784D7BFB4EEC9EA5359AC056E57
+B8B0F2EBCB1F4CE40C87FC7861180133E0CB6CE2FC4FE690756D327A2B5AE063E3021C0C0BD420D0
+56F0B941E6B36088A55BA11D0C35FD0132D5F48E5D9673572347171B4328D4807B972831C0D74CFF
+A5638C145B89C989E6EC942148207D6DB82257585958034D9F9D4221C7C9F7013790DBD130F277E0
+BC88BB179DD09E27062379ED06F25EEA8B7FB33C35861A0034776E3813D2E9E5C10E227CC569AB36
+CB2D9DF2E7B7B44758F9DC4FFAD7A24AC7E9F47AA850C221048C3CB35A37CE8EA75632AE65FE3212
+175146FECD6334AE3D3C5F492F067F795E1E8FF386BA198CB74F0BB4DC0000DA383BC4CC3F070DE1
+7721431988D69C8B1A5AFDCCC83C22E16A87E01C6D3E79DC7AFA3DB0371B0866EFB8B6F88900472A
+FEF1C4A878243C52D4E02E82658979731C841C489A6B97E271C4C93800EC7D91F93EB9B9C659A554
+E1FCE42A5EC65AC39190EF4B66DEAF6FC0569A000A9E1495F42F706FBEA4D32EB7EF11A648910259
+6A65CF899C2F322F5679C6D123469192A9BF1A7F1F2C81C554ADB97BD19ADB746A4F81A4D5559E60
+AB94C483DBABF6CE2F28CDB412D50FF3FCFA3B3DAAACC6A83CFED910CCB3B8D2C19590AFF4D75303
+4A6CE7F4156896A13808E0DFEAC547E69D3C886691728E4A35ACD575B40D721E8FCC5385A2EB28D7
+08101DC50811529528F5CB0C009BA7E3C88468E37768FB0D83895AB54DB2DD5426562AF9D8AF304B
+F6EDA54E9C92643DF926F5C3578269750120302A37CB140A18BA56BA01108D4ACACE8FEAE640A6C6
+958EF156B588ADB0EA5F3B0F37BBA12B7BCB221C811415387B024B7076FA4403A3AD6EBB5D9C26EF
+EBDB7ADE7C60B444AB9F90EA493B658B7767AE2BE649BDBB3FE85F460F1ED137C61BD95F7CD3D8B0
+15CE45138538930AB62AA0E54B4CE1A5EC5FEC0A2B28B345B67089A4E4AE14D2E1F5A9C8848DA688
+CA298F93860649EC3AAFEF3E820D86988C8E3E5A4D4BB937791827994AA3E81D0BB3EE115EC36D5F
+B9A392D09E79AF514D11C7B3A03C9F9C13355CE79E119A19177FFDCA34704D38118A8976D1EE5AA0
+2D14FEB1414419F5E85244ADC5C0A765A522EEF36170064BB19FEE3B5F7B441E4DB967DAE0BAC2C4
+8FC6A836E0EF5A69F073BEE1699F55E9C757EBD6FD8B514E2B49D6333815B7DBD1E0694695FCA3D2
+1320A0C4B852D9706DADD8369A95FDD917328BE93DD33818954DBD2C212D2CA81560ED5BC284EB04
+7A5F389E24E43F4FA8C97FECF46589FA7341076555CF55B1C21B28E0C1CBB00AB8B6F67472F27BC0
+D11148F407824B0159B5188D4BB7386FBDBF1C0FAF34721B7BCB5C0FCB7C4010DCB6A1284E9D7883
+9E3C2111A05D29AB7997073B590A81C6168020F1D48951BC7D8476D5BA593F4F23CAC1F9BB0E091E
+84B4E99E5C584D1370DD12DEE8DF16AF8BC6B7B23E2FEABDB7F32779AF8E2B5094A6E9B7A7225F24
+C43A8E5D2B977E1E19E633C26771E23017ED233DBB02C64F8CF03992C6484528D0C8464B46F24F9E
+8380F385D5D01B8893C67FC103498983CF939432AA380CA576D09030CD52FD99BDC3BE16C7204CDC
+3365BF76294A83A1FC14A236F5FE5321904E779B13232A76F8FE521F425562678436359C2461BEA5
+AB27209541F557AE2AA60009C9CA0A9FC7898C14306CE35A50017BADEFDECBBF94EE2905220706DC
+806409EF87DB1D73EAB0698AD2DB72CDCDB293E7FB13C94D9FC87E74502E6927A212F0D7D2F2D194
+64F7A66AC07872E18CB1DDE8F11835DCBC5C4EF039333FFFC0FC1456DAADE7DAE3EC2EE0D3415B0C
+ABB69FC5006F4D14A4EE1A5CA99AD4D5E629C0DD1E0F097B5B93DE2DD001A8C418234C9C45E8C13D
+1AE04E9466DAB8CF1ECB88A4E059C111A6468D2DABB90DA79C7C79E94DB28F6968B1A632F8C57D9E
+565FF91C6916026FFAC0661856B9FB8DE9C81661816221B1FC159CFEF1751E7E403F5F2CE32529DD
+540792FC17A12A3DCD7C50D38EEAADBD10ADBF5D8A82442AA900CE6150EB7A4639DD9FB6E385B2FD
+093493DCCD9014B23EB172E21AA89643A6CAD1093343D85D81261972DE0ACB16A4C6B5F0BE4C978B
+FA12D3CAF0134F9EA49F6E9687C8F99A456745EA252F0BA9968C7F9586E3DD841AA92DC7705BDD68
+2DAE41518A09DF0E209F321D7FA3417202F4BA76A984DA3ADDBC58136885362F02F0A24EBC439B3D
+BBDACFFD8498EBD29F88F016B1FEABC10785438EAC860B554525F3266097A675299AA0967BD3B7A0
+EEEE3FC578D1BE99D3533BD91571AED904BFC9DA1A1451FDC5406E1CD614E0C7FBC733563CD6CE6C
+C31E9237CA153F1F0411114361D731636BCF98555ABF12848AD109371A42B63675A4130B81E97C2A
+2EE2BB5D8FAE2640156001AF0F55D9D5DF8FF23C8AEFE14F120000F14149A36E5C94CD9081DEC277
+C2C34870D05011F99D48B0875A5FF542F067F7E9880109F586BCF2B50522A1F23ECE44349E539E70
+F84E207DC9BEC7CDF856A046F1A03226AA41F541719AD1AF88FF211E57DD0C1275DD0B7B47440DA0
+89B98C6EE92A7D94700B83CEBE19EAEDD8A615F6587587BA8BBA3CE3AA5E8EAFB1FB0F486BE3609B
+169EFB178A4292F4C0378AFE5D24EED1CAAB514DDC66C696D8E37F294A6579131DDF5488E9436609
+ACD750C3DB0A940C84FE022B22ADC2676F62E91E8F891225F891FBA537679B24547BBBF35F04915D
+20B11739F620D18B5B216921D222F15044368569AA302980B9225BB839F494588481B94B0C724352
+B2DF600A22B062561D86CB8F81514FBDAA4F8A043A0265F992FAB71FC9124A45B8475E1EF3DF6B6D
+E35CF329777D45F08325E8505EC0D979F542807AE77E57E453525F23BC59A50740371EFA98678AEE
+6C425374AEB745B99DDB5D8D908FDB551FBC0DB15832107BBECC4E11A1A8DEC69358A574A2ED46CC
+31D564549EFF23102D92BFDCBB2BB985F78F36033E34F59C0EBAFA3BDD71338736464CEFDBA91398
+33995EDA4207BFD4A9867D32E867FBEB7DE60D132803EF9347CB17BD91315484EF6570892297DD8B
+7D966103339535E28A00CB1EECA4A9775F60A9F5FC9BD8B06D78FE8E6318C31DA2E847E3F9CA587C
+B01AE2BA0A2EBDE308314413F4F230A758184ED60D4F71F6CEC22A93A01B6C54E0449A3860FCA895
+4A347B7588329A80974ECBECDA1070FBC055666375229F13DD995E99265DF870BC8B8CC6347FADBC
+1A6AF64599271A475B9123493D46BEC41289BEEB67EB97A8DED7A9C9730D37C65164CFBDC22E5CA5
+89D2E7954C7136EF4E084C43A6C7F361A3E96989239BDDB9A593CC2A80BA16DE9EE90E95CD39393C
+212AB22EECB677FD36D34DEB46C4AD0D21BF7E6D7CBD0C8083842FCD87B18FEA7CECF939987E99BA
+34C214E44DD84C176C9CC5A4CEA76D380CB316BB4EF9DE73D73B4AFD4ADB54451591DEF86621D138
+D5A0A29441502BF6C2ADE671CEC3CB5CAB903A657EB2D70C943F976C110E46C5D9D29BC00A875F27
+38E5D22496A43E096E009C5D3CB724B4CABB32838DBE527F83B18CB457E57B092C302EE557FD4F00
+DB9C56E66C9FDF4EC9FFAAB85F60D02BA79694FABA476A199A0331C30A78A92E10417BA236E23364
+8174C826331DC1BAB87C5F95027846130C6A2B4027930EBF9A97BA1B039D386FC51C302648E25980
+212F6A582CDE2778C677A01FBFB3C5D1B8A374ADAF6ADBF7DC94075F25ED66D440B3922C5F255FB2
+3FD8F6E21EA65B1D93BB225684B50F11310E242B087575973345B229BA62C1E2C35BDAEC04D10148
+F5B2F3BCF7399BDFDF1F3F79119714AEA697245BC647316EA157484ECB951BE367234FD02E8B1F09
+1AAC3D29BF282DFF4011BC0CBA8E55234D943DB3017CC7A766720BBC29B2D097A956C0F1067177F0
+12D42ADCB473CDE8D1BA35B4030757FA1D8211989DF3BD22CE5D501C21EF8708FB3449DF47D88650
+9FF7B59B76C0DBAE443F336FEE2D615D7EED1C284F14335BC8A26BF4621E10DE9611FB2F1DBD52E4
+B7565D8C65B54EA36D508BCF0C578A49A2665227CDE1F9768EFE847F9D94F1BBB7DB83701C232198
+5C7283D47B2E40B27A268428AAEFE75F6B2F8764A8494E5827573758CB9CA46FA93208836BCCC8B5
+564A69F5AD882052AF1C1417C3FA7F580569528682C77080F3688B65E7FC24D2A3AEB61574B4A321
+5927281544DDD7A6EE0A3E9388F8F631CE7251724DF70726E5912DDCCC8C652DD6C9608F8462303D
+867F589DE0F2F71711B35142EE6EF93B64D6326C4DD7DC83278E057100EE772082E6BA368ED91A55
+53ECFE2293A481E42F83BC8F9148C70EACE91F7B7D9CB8A72415BDB3AF66F68EA733A17ABE9DB005
+3BF148629132969589F38D30EABFA96A01FAC72650B5A6FF3935670198A1EA33810A9B11E330EB8B
+451F24F93544263436F669AB5A90A53B16CCEEAC36B1445574EFA7E802DE73522BE725E68704822C
+B7D3912717333367895BBFBE06966A5CC653AAB5E9B3596702086BF0010085B900711932A95ACF15
+CA4DC45A754EA334E9EB84D6FC8E3FC4F897456BED64BB93B593549FF0D5352275D8E417172A6664
+C5E0ECED1019494A7ED49AB0B965BEC1A82E5873766BB38D7D856049CCE2FCA65AAF61E961B60634
+E2A69EF059754C9D8163D87F928C222772D070D83FEC6FA5AC734AF65E40BFDE521F7D9CB1650FDF
+64754BFF21EA3FF0AF7611A93D525EC9B28C51AFECB04E7FC8323DD6C9B0D8539A34FC3CD8CEB795
+8E8EBBFED4313C77ED469C199552A9FF70BA5423B03B6148D4EAAE17B71C5B39DC436AC53D6BA8A7
+AD81AA8B02335A8B2B11E9F4FA913159A725B8AB60F52F1A2EA50EAF4D56656E615BF382CC68A690
+BF83DFF24FE986570ADC0290ED1A37C1C2AD469CE789E0EA0BB5CE01020100E729721AF3B5BADD33
+A2DAA6C33EB8F9064F5292F715F820B4BBFDD56F76D42E7A1A068C1CBDCE4640082F6E7D582D1939
+990CE6EE8D270015A2C461798B37DCB5798EE9F7512168B76D26C28BE4A49A1BF96C89D235F21A1D
+B6A96E5DA474D0B19B808D13D7A11BF39EA8647499C410ED9894A1ADF33D41B6FC2E614D8087F4C8
+4E437B136F3CB32DB8393C49177A0675A0C9E7EECEF448A97AFDBE840FA01FC7E5F2E8FECEDC1884
+84C312E8635CD79195475DDBFDD4D38D5A0246DE2C7F21608F8D2C0DA1371D302E941572E5792A3C
+F4E51A33228B93A814D03FD4FC223C314CF3714BB3A34BD4F7ED6348577FEED9DEB082C4049E57B5
+D3CDB7F26629E9F3BA36893E09E3C7463D02A22D7056BE76B87763260E46E48BB832B7EE13F8DC05
+37EC8E81E9BDFEAD8C27EBDF1AD706933EFD11131E12814F236EBB01BE85B7F1B2D627413B324918
+D247604F56EC128909873FEC3857028BEF76A3494364C2A7002D104D486236C30B48E2B75D851C34
+EA50BA7FFEB4E19190898AE21768C157C0CAC628A2181A32796FBC1A7271D2473CD88E5395DDBDB1
+FC3AA8DF0F3D588637F19A8B833AFDEB5F655A8838EECD684E2315B72C75CEEFBCEF94344ACE8D6A
+DBE355008EC72FE7CEEAB01363A895F4E73F867639BE0A0BE67333848816B05B419221BE8F9066C3
+62C23FE85B7F392930BFE4C12B9526FF2FDEC38F23A159ED61A0718E7115C24597D849FA76369153
+54A40C965D4D72EC94DA61A03766AB39AAB684E134FD1407A5B1B19BFEBA52AA0DA5D99CBE5C82DB
+AA663711E6DEBA180E1D4A39C320516A4350D296BC19BF1BE054859A0889C7E9727A021F3176FE62
+0FB0C837E4141FECE531A950C03D319E3255703220B7185BD20FE5DBA673F8129AB211EFCF36EE39
+4C7E00EB0876624BC840FA86E58B2F584754CB6BFDFD76810E300741EBE4544E5AC17413ADEB21C6
+2F66CA4F075C32381796BA709782DE34A675B717A2C7F6D88104CB924FDE5DF775B4F0B68E0E2E5C
+2F788BBDEAF06D8E1FC2105CCBBD5827C0B03FD6CD64F0D073F3192D5F94839644E5EC6C5185BADC
+F04112A65F49A8C83174A9AE958E76A2F5AF469E8B76C833782C5FFB8BD7B1BBBB3EA0CB7C9786C3
+BE2ADE5E7AFA8C8F20892659A59BC421E28845A108E34EE17864042EF587A6D67DECDFB3F510EB40
+D2229585347A0035670FCC76C2837A4E4D68304FE113C539B35C1F0234B5079B8E32934546982978
+C5E4DF955A454EA263C3CA5D7101F31A318D82A3F9FCB5A8AFD7A65209663B0FC9DA400B26F285EF
+46D0E1EAF8ACB1F1CB805E3986D04BC585073FC64895E4DAE1CCB749BB439CB32EA91176D5C39C36
+50D10AFB9C9884D5FB90183424CEE67EF2175D01D2478D67511EC9F54F88763C152697B06D948BED
+49240096EEE3D06AB4575E8E8B2CB8263B5BCF4FA1608720F52B675309833071879DF52C3EC2871D
+20F398B5CAC8F8A4D41D0F1D47584DD90DCDAEA4A1CF160C4B3BF1AAB890B5CEB6CB3488672AA68F
+BD938281DBC1D8BCFE92FBF514DA5358443CB6E0147254E91B38CE6787B2BB0DEDD2D38F5938737A
+977B5EA42892520C58F8FBB53C994B57382379E9490F0D6970B980E1BDF8CF9F4C3C5E0A18F66E86
+EE93FFE7FE546DE50F41364BCB3721B637072571FA1779F1D672FAD260C16D7F13CBDF3E4376E7FF
+56D2A710AC5AC35FCBDBCE2C9C17E523BBE6218617B13C1FA6679B308979AE7C61DA6E68369324C6
+CBC7DDEC364E5A86707266C0B459EE7B2C03FE584E529BFFDCE98C90A2F3D9305AA74D3ED8430DBF
+3A49FE2ECFD9C4BC9FEFD22618FE9C8A973AD072AB6F713E4DF02DCDA7AC5359B2D652013E131B76
+B3ED6C75FD53BA58D862846264627F6B9E70D8800F6D9B32242B747A67BB2B45675840D34F852AA8
+062FA6B01E31ED24DAE02F6CF788A17F7B9368175195DB0072259CCE0FFB2C1035C1D26E1777CCA3
+D56A827C3242069E76D6DD69B653768614B9ACFF16567FEA61508D51454BC02F6C60F755AEF6AFAE
+3536BBFA1823F8E1A53C41124DE983E51CEC92AEF4F99785D554488A51C20885346D1F761DA79017
+940A0C557D93F1DB6B3D00FFD61D08E96FF3AFCE5FEDF545CC9F47A2B1BB26713431D6D1E47FD6BD
+6E3C668B0368241F0EBB5FA9C991DF79890E52E83A3675EE699B61BAF869DE91F67278F510061C6F
+E41DE2D883F48CD0E068E2A652B244128D82E5CD52F35F210DDAE3054691ED55A7D99088AAE8FB04
+F525C2084AC09F5EDF80A4EFAFE981F74C0DE9D194320709B3464F3FF2C0F6AAEA6D973D9C323F53
+DE3D741F698FBF01036716BBD62957CB32CD81D3A2674560FFBC5BDC5C6E4F547E589AD0B1CFE14F
+5E17FED1C4A8ABE4E67CCF8A49F32C4C6044F1431E1CC382E7758722A6D0DF9ED23E51F8AD14D11D
+7B6428E27443715EBA4E9C05D6F238378F9498AEF0E7EE4FE6856622CC8E6ED141EE5F109E343CB6
+695C4BE1E0F66601C27975983BF557C04ACFC19227A1AD7E6C44C00529FC7EDD7F886D24B7E029B9
+C395260088BBFB96972199A7B32796D27257DE83A7402291C14FECDF7998C5C96B1EDADE0280F856
+8A8F5007852EED303969180B3329917973C2D32C080C9765B6BAB0673BC7ECFDBBFBEA980C263843
+39B7F1052591D91667D4FEE413AFC23DE2D4B9DA742F4269C6C939F5FC32A38040730A018155AD73
+3F231E4D5B9D01C03A58EAE7B5F590CCFAF25EDC8552CFC8D95C60EBAE1837D7A97CA137E9D4A4BD
+2CD34AEFD68D64B3F4F62326AC429921D7FB3C235184FE0899690A0B775F1A566EC29D5830D32372
+6526F7E7F5AFDD71B77E07613DDC4FC63EDF49051AEB59E6337AC0A4B6DD872E776C9CD0CCB86130
+5322D816732124F5978A86C186BF0A0F88E733CE38E4D7C1BA5378C5629B1EFC97806059990ED42C
+5CD183BAD7E94070E4058569DA2E51831FFE0D080301AEAB4350BA290318AEC582C78D05DD92E5AF
+B4424EA808629BC972E68F4FF2489C245593F07555CA6A2B25964794CF31CBD3AE5C229AB9B8C298
+06C01D116EBD0FF0F159ED2D3D7DFC73EAB4910BFF5B0B0B587CD9EA6E6FC45D63C09766224D8346
+1F0588140B258B1729F70BAE7962189B1554483392988CF230AF4077193E53330519394DD99BA135
+6D4730AB221DC6A66019BFAE564893DDAD7B177DADD16ADD21D396CFA6C3DC818052E2F71149FD59
+4A16DE0C2FFDD366C99B486C55A6E991E4D22CCB15843F0C3363676AF2F5B2D1B7EF66CCF2F12DC5
+0D63776BFFB058D70A9C76DCE96C754872D72C82A0C33F90D49C935402CDD26B6D743B1F43BED5D8
+B539424849C1495DAE73044E885A7D0F307F1816DF6244A6F2D97BFD4E200E93F69B08AF39EA21E6
+E347A47CEEBF803F73B978ADBFCF056789BB8E6E2563DE87DD9A8C877157B934102DCEDAC54D487A
+1BB2694F0034093C48F10A17D32E2BDD0C723CAF59ADDD1BE373AF8C9BEB4415AA5AF36310C31F24
+354A53C0B962573148BEF91D994FE3F3D8450DD4D686725799F53C373A0A3E3C060C2E1A3E800504
+9F26D716E1F381B9F83125E4683264A07E2D8938F605978E2513DD2050B3D8A1012797CBA8961632
+BED260916338A812AE751C7B657E086A0C7DDCD3BFDDFF3E48B84751925736D1310C4910FC114387
+F3ED7FE163F91895EBF55FCB425CEF5729D99BD8F2C072E36C310523E75CD8E5DE49C031C4263410
+9D56E91A46C8C8E89FD92012A00C33D0DEC52597B5C6933291A7BDC5CEDA95DCDA5600F9AE1C8250
+54E7EE1067458CCB66610704C58E4A4FC0CB5FC933D0322A716B2CD430A3AD48DAB3D4CBE9D23F2D
+092368CFC4E1F5495C133A92942EC62118D45C17723646E69407B4A89DCDFD2AB3FFC099A21D9D29
+741D68270629AA3A414FE58658DC9170C247B6E23F35C4BC5FF83009F462F2EEF4DBAC5FD158A658
+57F9B6DC1F5192DFB169DCB65621CAB2F1B07BD22F4155A8E9E2B6388D430FDE5EC1C834D22EA035
+C52E1E34482EADC36B4CAE902AAE89A7284E62B3C84B608D6BD05F75BC31310B2DD3B2C08A00E073
+7F104F03A41989D5F6B9A2C38B22F1D1803EE5D7A4D8DE44E4ABD496A1DE0C0E12C4BC96D0122846
+3F0EA9CE9509FEE987139F3DD3F9D0DF4313F555BE85433718F6D05F197C41A9D9C7A8B0D2740196
+82D49F58DD5F66B12A6520D9F226D1DF1F1B65CDFA261F980CA25A92645B86B64606293F8BFDE364
+C47D2AF2C709BBE77A70A5712F2CC26F3D66F5BE2C307A48E6F887F681D30121E32BBD87271B5DC4
+615D28C309F15AD263FB37424E56DDA6E17B998B45BE6C7FC6C28E3394A8764C9EB2DF5C06626593
+B5C665D550D4600172791CD208AE9F37BC082B0B242B0A504B751B18F4D7495172B697EE217834A8
+A4FB7CC16D6F9E8BB400BE8AEB0850960283DCE725249FCC4DE97D9886745AB6066C3E2F64DD8AB7
+9AA11667F11188D7965DC11EB760B772E282DBF13249F31986AC6898FEBFE23E3E8B8D2C33E00EA6
+FC493850ECB2E6D831D1EFCA3C2EC8EE2E394599091ED58BEDE97D7A43B6F739EB0F845EAC1DF6B1
+EBFE876009CC5D804B15ED4B56761B3CE1AF59C07B49DC798A44532297AD73D5101ED47F36A3678F
+818297CC27F6AAA2AACCC9AA9B6F5459911D8C56CF499E390AE607F3790450B2B9C9BE0F006EDA0C
+715B5CA0481734CFB0597478E7602B0D2C1E4F78F03C68C17C70E4B42D7D2D3C95CF40F73488B371
+8E2CB05A549944D86944D78724E266C3319AF89AE430E777E95F0D792B1C654306E421F3D63A26B2
+1E74B6E8B21B2E2B9DC596D013CDA16D08E65E8F24A84B12B2BADC653E6E1110DE2E709C1C1BED13
+707B70A421B384F20CA7A9A9D20324DD383F28B2D3C7A9C53F5D4C6B7C378D26DF11CF55238BE1B2
+4FA70DCC178DAD3D35670FE4919085EB1CD905971D76A368FDFCF9D2F0A23739851A3A6D2E02D65D
+54DEE69ED5D81315D3EA5E356F94EF256DD267FD1E1A9EDC9CD63E743F299BCC4A4506233B8DD765
+2CA067F741603F93250C087D368F9E9CC4CC1A6DED567487C05BAA992B0056A77F630A72008E3946
+15A9DB24FE56A956650EC9DE90A6C2259189440247970541CA198748928215C0E132A81AA13208D8
+63C1FE817F70CA573B54577D10B73100AF8EA088208A44FB92ACA314AE5879706180788C17BB1D0B
+81B6B95A1C4E0F9EA66F9B39BFE12444A6446691A7BDB03E0F03D9F07A10A7598F2166F108529F34
+CD90E601FFED3479ABCFCBDE8F051C348E48C61D95B00C59EA1287423F05666C3D36288844067E83
+E14F6B5210842C742B89F13ACD126B9FC50ABE2CA7D7ED513D43B6AC7F41EEDA416BFFFCC5C844AB
+2D23D4DC09B2D510504CE98D02E72020D9E669DDAA344C63A1B75632F912A1C0DA3885DA4AF7E243
+E4A4C6493D6595BB6D56B0359106957259E59E336BAAF35BD1CEC5CDE735272EBCCAE8D4904AEBD2
+B32610C6FEA2B69941D6542ECB44D71092A3CF067708A3D087AE99FF29671AB7DD8758759B971A08
+AE1BAD78270D2FBEE37AA2DCB119D72F6C7B0C8509018A70D0B0BE2C6830EF8E0B24B1CE1141EF87
+3A4D7DCC501F808BFD94E4DC0F2915AA023076BCC8006490A43685EA25AAFC187302EBDE7FE1965A
+04A5A398985D29F08E085127B56B057334D88EB638A4DDE64AFD204974C3939536B1B66A54B4DB81
+151853915718F70813F096CC1B0EA25E363B49264C2AD17158A4489F91453FBEDBDE15D7B74D7F98
+E81DF23251785D58295BA297F295AA6248A912CDD4F1111E6B628EECBB5139709E76EA4AB743CEC8
+26621D08E6BC64691CC90B3C3C1778931A28D3D5B1E20E96C643316613FC487C9B604C43463FA453
+3BCA1236286E6F5A6EEB2F1D9C34BDDE4595495A365F88055D9268541CF1654ACF478D384A5496A8
+772EA1402751A093582A6625A0A44816B5FDBE166835D598644296249B92CC90AA3FD6445C9A19BF
+27F59CB0616C7306070F33C7DF4E1DE64AC8C5BB2FFAC1EF2B1B30E5A0275E6004CF64BBE2C6710E
+DCFC3AA4ADD60106334708862FFA6652825BC84842736E47AE6917180365C75B27505EED3C6108E9
+898A780E20C3F606A860229AC46D0471ACA0187D6D539A1B8820F620F72B41AD1D3BF3834BF48CA2
+AFEA8BF535AF74C4562DEADCB63D2F5C7585722B77C989342D190FF926C8A5263B4F25286F99CF6F
+C62EE6E2AD61C82B29D82468AC10FD27764278E5558CE8B41BA111CB2F040914451A480C93084237
+CAC8F66BB7C6689F340B8ABF0150E06D5B1177278A4C08742FE22F42C28680F190900344ADFA486D
+59718C25D37275BCE4DF981AAC35D2C7E85C72A0188B8953CFA516FD545AEE0BF4B8BA301CFDE214
+4241FBDF3D204E3D2823301572E23F204C97305A82401660E12926EE7BA6EA1A81FF5C007933AFC7
+3266FAC4C134ED818A48E7DA01C71A46335C845F9DA5E960B25339D551582B375814148D94CFB781
+FC56093827B78578A73D4FF67B6B87F40CFA5E3F4325D9108CDB64BD06427B88C84105187316FA29
+90B4E3E8EDB6C78ABF164F4A9717D523794B2FE772A04DABBE688CCA977090979B5F47CEB90A1DBC
+167D305EAB231C9F4260C4AD10889CB785169902FC0BED78DA15B8417453BB65856EA0BEA5245BA0
+573F623D215F6C0CF801851C305B355D26B52B0B343645FE25C78A3526841EDA480919A1BBE5F56F
+C10ABEAA3E1FCCA7C43EE560F067F1AA2AFD642F769D1ACE8E2AAAF38850F0D757CD808C921D716E
+96FBC07DA7860DFA70CEAE2888C0ED3CBF9586443532B68DAED9A926655C157A416C383A53D8F283
+2A4E67468112A09ADC837ED8EC95F70852921F50D4417239FC42EE3624CA97F682745CC5E76CC7C6
+7BD99F2180F8C0B7FB49539C8CC474C25C0DDE491671FF329E51BCFA779346D4686835A3AD6633FC
+B5E0F67E0CA9CED8F215BEF4D240453EB2EDD6ADB22278AA5B985FA140C9834D38753DF2014F8C0E
+E6DAD19E8FC54C03C1F6CB0F858986691D99592562CAD95FA0A5B2ABE4A8B54B457D42E8C33A2D19
+51C0419A72FB94FDA78ECD92BD2A1416459E9DECA9469F35E4C47DB531726DEE8F203D7042EDB32F
+025DF3D582547BB1D45F7A5B70D317DF4EBB16E36B0D798E0932FD2A85B04FD67143E4B287A50416
+2C1F5A037CCD780088C5476385AF8168E12D97D44B0630621759173C8F1E3006B5B1C6D7138B7EEF
+C3CC5F54E24B2C3CA7B41AACFD25E554880AAF406EA4C3C6E21D3B550B040FB1952598A7E8E6488F
+E38288B2AEB6C4718338598A2BFE4D2B9D14C65732DA304C16FF3E1F8F03046EF095B65FD609DA87
+EC24A69278BFE65C905CD0329F6A486B8525B7EEA4F7AE56C2633CD83543269E8ACD6D71F500D82F
+DFBDE7F7F7B1AEE67328549232E26CA55085B6E84D9E2E7F74068F93A90C4654F2F396E57C5F76F7
+E61CBBE523DBFBA6E76638BBA3064DA025A79E3A294FE7F1CC28A3B4C57DD6FDC48E541A85534B25
+E1BC11B4F78019457239EAEFD4BE9007D205F1D985F389DB22400B279C10948551A6B4A17FBDA0FF
+C9428B18B43DC76EFB15FC2182216F1B60B4E344A03AD6C00F141EF99F89F24C819C3E32877A927D
+84C2D006940F39CA8B71E5951673EA9BFD1749923219DE38929ECAA9CE43B06CFA7DA1BBEDFDA56C
+61FF6C24F40E59B13870D5FDEB82D981154FAE5D6D5152DE69339359461A41A9713B6BBE47E868C9
+33CD74C75DB71D13BAE4DEC85E02FAA14EAD6C0A253B16C79514657B15E68CCFF9EE6AA385CFF9E2
+C53D9AE40F85C793E4E8FF50B2B7420F4FE69807BC5F37C3E300E6B3C3549D1D3246A2E70F091054
+1135BDF805E0A698E236B6496702D061241687B7B8D1A0E517DF0476DA09D89667A7AB375FD2672D
+CBAB8124E511502DDBD08BA04D941DF1CEBDCCF7ED48405CBCC33774A68C5212FC6F132641FF413C
+984F8B43BDFD7B1A2A3435F15AF07EF4970D3E4A0BB947C181E9CA27CC14A35BD1BD096875B45873
+8CA244F88C28728B74E25CB8C4FC1095A56CA75E4569AD3082EF194ADD11350DB3B74B96761D4538
+596FF7243B1E1B724716A144106E080D42036444FD472998460CE9ABBD05B42AF9389AC452BDBBA3
+A13A96890025789F16B9D92251FD3B3BEB2C61EDDB370A20456E3BFE5F4039E2557C451C524F8087
+015BAF3FF05F51869FB97512968BDB2B49589C1C7AF1E085250A47657465F480B7023E24C76731AC
+0EAB6704123D77977D3A2C4C56B691346EBE589C619C04515D34F81FC6A17527D5D8319013C5D4FF
+27CC3925E24C99231AC7FB9EAF0BBA482D3B75807AC85D03CD09DE5D9AE0B07B7A813F0449786500
+0AE8A7E00080300F0AB8C399057EDDBA273DD2E1B2A0DCEFAD3B332E6D4AC1FFAD846167DFD70E03
+46DAF84AF292D4F424256ED5AC4E104F80697050D50844A708EAC9E7F7784FD01646F3BD0C595CA5
+1EE6BD607D254E78ADDC5E15C3B6AC4940EC865A5C23105B6BE09EA09F2C05D6D76960A843B81EE4
+33977FAAC3CBDA85CDD2F4DB7C28293A77825635992AF8F3B38B4480D9A139B1662345A8ABE1634A
+77496C3F57597D2985E9E54717AB2E99CA35789441BCDDEDE9A9E2106B401D9684ADBEFE40D607F0
+75C179E9CC03E59E65430DB70B441D43DF03F2AA6FF06F224B6E455B01C64FB89EEC9103E48453A9
+749B4D602808C7E408A8903091D85E06AAF635D0D529C3CDD1B8479AC0F4208C284BB678A547F2BD
+77BB17C86D4560434F7AD1937760A6AA55B614CFA9FF8C9C96561AE6C8F2121C4E20237428BC51DF
+2099B6C49E3EFA18E6D439E6E6981E746EBB1DC461259D8EA0F8099C47CCA27B2D982B72C9A07CF2
+1B3C05D6E26E6E286E348B8944078E24809F9C5F3D014B4CBA02533F5621BFBA1F0EDB776C634746
+703C9F73BA89B1960A496420C68F54E5B901A6D733D7ACC79F275FFFB253F389AA480084468BB34D
+A1E797E43B7F6E8CAF5E8C93069A3A2730E57EC39B677BB73E3F07C2055599F7062E53B37A5F0099
+907D2ED87FF7A82C95FBAEB888033BDFD67BA3A6031A4CDC56CB1E4CF5B06B46E16D988BECCEFACB
+9E1C037023D7BF5CCF5D65AA66A17AB361BE7981F132A578F3ABFB97960A6034F052D9D5AFDC0679
+782EC90F240F943A5F9A3D969ED7399254FF67D89DF668F7C56FCEA1FFDCF20481474AC8495D3AF4
+B6D7EE093E369C057F0B70858220693B398ACF8E8143558132E4391405E30A73937C53402E459F4A
+A3539CF7A99A3F51C0307D045DF8B77757E92EA2F51BF0BB4F77D3904DD355665870C2B59F1ED7F8
+4FC71FDD7F0B6C5D3182DB77827CA6A2060D2B8C83C4EA4A432EF43A4D0A952CC6CBBE52A9F0CD66
+1A538973DE41FFE9C5CF55F2506B9EFEE51FBAE5E63BDCF5528499A47C031163C88D3022606784DE
+2F46A9C9235AEE3D4F71D4959B0CFDC5B7E78C8C0A8F9DC99440C2263DBACB343C5C648577F5610B
+50EAB1CF7FD02419EF3941C7CA0B0E64EBAD4B2CB05A0793DBC38F1946D44767BD287F5E9779C611
+CA0DAAA1E7393DBE0683C8D3455CDFEBC0E64B54B737E298DDA605227C0C4BBA87AA3EC7FA6EBAEC
+39E6EF2537D5974391D31739D9FC42983D81AEE44711C823F35F8E2321AC74943871739D2DBE9748
+FE68592263E7713F27E0D49B9B5CB7A4E55DE54E6B800D15856450FFD3AE5F287B12AE4F438B20AE
+9E27E6CAA00F3EAEADBE08432684FDF9931E925544A680182602A3C1997DE5D0630BD5A010535E66
+E1C123013D23966B3545C7431C39B97295BFA4099D14461004C42C85095EEACB9B47C593BC6DB863
+533A8619BAE09095DE8ECA432D4DDD49AA600D277E75DC3F5C6631E2A05382CB007825FADB77438D
+CFA78E252D79B6A196D5164C2FEB85D75ECA25FF80B1D97FE10E87960CA0FC47C41D3A213BF141B4
+8BC3AAA93FA86245064668394665BFD52D12C3BE4CE39EFD8111754398A944C3FD1AFA98EC337BAA
+AF899D35E804CF416AD7FE45FFF13FC6354007501043F98FE8428DE8013901BA6A28711A2CA85A27
+0BB135B72F1D5026E8217581860729E94F2F1878A0E96C59E9F62714FB5F8F25003DFC7347E99007
+8A9A331CB3A6A535BC61866F02513DEB982C4A13ADBFBAC3FF70A7335F40D5489E48E5EDEDEF1619
+1973D932479C62183B0E25EE8C4F76D4F1AE45DAEA4A12AEDD9EF81D248E8D19F8C8A5BECDD1EA1E
+98783EB7A38149170851B1942C96C53DE06DEF80913BFC04E539EC67C110498D15B78268853E5C72
+F485F8A27B768569E54241F6115875E2973292CF48FF91D45EBED627AE9F0766D22201B20AFDD40E
+5B17CF337F2999E0BD15B86E46EB3C18FC12B7DCADCF9DD50C6C7E3F37E615A892DB3F57E250A072
+A49F7277DD6A2C8042698233D35A699B17ECA5DBDA6D250ED4A16FCC893BF0DC2E33FB1EBD7DEDEA
+3C1C39603C8B7E1A5A833A8FCDD5570BD088749BB232615366687962C7E56ED089CD7B092505CAFA
+5A80F503C4CF337F07ADF0D106937E25670839D491F7BFF7A523DB609D126328C16113ECBCBF9C40
+04904427A108618AE5D4ED809F8CCAF72251104C94EC5BEE21F91B179D31DBA79CEEE5EC7FF698EB
+84AB1D2D1A624F58B3622A78844CE51498B2CEF38EAFE259D22C7BA61104651A862008BC1DDDA58C
+C45F663EB26428DAA85E7785363A69D2790996EF5D9621D53042F42F794962FEA46E46F37B8AD1FB
+76FC8D5CF2146843F8CC625139C75FB42DDA71A752BAC48F294E4C0C8289FC46DA5EFD9C91BDA6D0
+27518B7E81E8B21F755A9615627D5812ACA674D1527A1185EED4E3C628196E7D0759B1CAE6B9B7E9
+01E9599A65230F1EE469CD33B9BD9C104C44E3C1AB966C9678BD0AD78111A4E0F2D07A01A038CEDE
+7036D0534D684A1562A17AD64A00F279200C0371B1CBA61747671D2A21D3F9646CA290F6B82418A9
+6FA177C6278277504B7FBA936325F5FA124AB018A15DC18D2C5E8F93CDEEA52BEEDB78A57828D81A
+3E6C38B9FAF3DC4EB7273ECE3EA4482A1C6242A335862C2C3717F9C9ED95F77B140C4E1569B2192F
+C7DCF702D0BC9A50428EC406F8BD0CAF886B4D979320D3E429816D88F7C7146D960AC12E70F2CB7A
+9F4E3E366665AB3F1B4B6440F55EEA26DC9EE0096BB7763731740A537766490C8C174723BF0EB40C
+53701AAD12B21D436ADCE22203C1053A9DC4E9F17AE617888C4B4E6F3A720E4E6366BA628221A387
+D8AB15E04AD69387C310D3528BD2FAA5B22BFF3FA494F5FBFAC4F771C9C7402B95580C5AC4BB3AF6
+92A70CB2C851FA5CF1173EEC3EC29B5A05A0B728BBBB51D3B7AD8B0AF17A1563E82FAFD93F8B7118
+1FB7AFE352874F4EC6D334AB6747519AB8E847B7BCED33EB5458A828E074E74BA621BDCD03FEA604
+7F7B6ABDA01FC7514BA1AFF0D4D0C0CB8F4E42D5A87E395D9ACDD02CCC220C157153422018725846
+009A3ACD8C8CDDB66BC6836B4026FD9F526AA275D06C813179E5924F26A25094E7BDA8BD26AFC4CE
+B41D8964D4FC4AF1DFB0595BC5D6714C32F15DC7194E9A3A73013C45D8FA55CC0550A12D9AAE8E9F
+F199FA28EFC2426D8D1DEFB93A65717AF3EA8E2D5B4AA8EF0EF38E9600F7D4E7D9F1D67A2E63ECE4
+789FA74B159BFE2F91C19B0378BA52E93DF12830D99553B6618645E26126842AB70262D96E35E5E7
+50ECA0CE3458B3E51BEE2F21191136DFDBCA39BDC07939E521E4F492F392DEBD029C1EA237BD89AF
+76BC89F618D530160AB16269FA6B693CF14BDC4EC7C630025703C5337F61458FA09104EB15C7CB20
+AA4C9BDB7CEF3A09F25BC7F3149951A7CD75372993B80CD2112F7674CEFD6AFA764AA3486730D2C1
+897A264D82A91709FEC4A21E30D812F558451804EE6F3DEE2C4C437846BCBDA07C5B6CBA1D94AF02
+9163B7383CAC6E088AB1DC14ED3743EE77E26EA7AD3119A76C0B5F925C4DE305CD7BB3A09A453947
+5B9BD79BE28FC462D8718CE05F9D94CAF3387BA55E6E447BF81A9EDDD3A34E17BE66BC52B0C0BB6F
+86F6F008829173816D205182ED2ECED319864A796AB65D4E3950288BADA94FA32B6F453AFDFC6C39
+A4FCFE60353A64627E2057D4B379D3240012B3BB0ED0C7876CB83C1BA5EFB6E2A03F340C2B576731
+F848F762A7E1CCAF267EE06D621BC33FC245D0E1547ADC12CC0EB58B26BABDB8EAE9CBFBAB93836F
+FF22BDA1831DD01B7346AD377AA298D84628BF1C07433284B0A90FC89F5AEB2651BA2CEA405D4F52
+DDC0E74B871D43F71EB4ACE0D2B401F9348EAC3A2EF0AD295036BF6CF6F870D58E00B619D50EA7DD
+77BC28DEF91D805CD527DCBCFDC16C042BF9B874E3B1567EBA4C1E70744B9E7E5BD1FDA6A5FF6E10
+1613FBE58DC46CFAC1A65ADAF65E49757E9304E2AC9A91E0588600C709A61D4231730073A36D473F
+518A145E141D0A5A494441B9EA99AC23F60F54F8127B477E1CE698BB4129B4B1DFEEDF10D9E665C2
+47A62F112F5CA30B0AE5DBF3E495FF06EB28EB438CE8AAAD84D5F50FB56A3AF002C23BCF66ABC270
+7AC233FC0F2723DB99D2CFE7D3B3667732A531F5DC315CE74EDB9050BF75D29E6430F57CB6778B2A
+CBD57DFCEF896E6766C8FC5C9F9FBD701CD62CACF33EE0FC95E78DADD205B5F42CC63024624BAA0A
+B4DD447832B4E1DBA77BDFADD223989F8E958C8D759AAA37930664C6EFEC708116248A2A7AF3D656
+DDEAFD009B7F5333854608E67E5E588A857167ADF9225CF6C641F5E19C3E08678A281199EDDAC831
+B57223B1BEEADFDCBC8F6F25D32FCA2336C808162E8F381656E847FB6CB13969572425AA05AC830C
+33DE6E030F86A3A85D2A66A77F103C7042C97205526DC882EA9A00EB8BD5519847EB424C15F808A9
+1652A6CC89B66A5731126DEBADE123C63D88A2E550FACDEB3886FF98646000C64B3A91078012CA30
+904B71737CEF6BECABD43DD702880538F5A70085E6CC6015D2163681067C3D513A8C66032C34A0FE
+17A58AD4BC97CA69BF41F11D5E910FDFE9729652D3EA21F8DD8CC19160A8FC77573B1E9CEF4E790A
+79D8AD6723B6804E9616466C935303E063DEE29CAA6C3BAEBF278B818C2EC2F13ED645AB452397BF
+00DB8B26E115026E256746CD0C78A959364FDE6DEDDCD0F441A61A1EBA32C7BC172BB09512148D1E
+BAC9E791B7D51B71CAD2DC9B83B2F99B3726607D9CBE58B499A13753CE87FCDCE21C0AD0528ED0EF
+B9B2C927F57C78C626248AA2B835A0791244C5896686A66173EC9F802C4C633A42B086334D2A4878
+0E53D00809247BE64E529F96AD2F8B3922A6097D414DDE1EC76F9552F9B8D58B8E34F359AD792B2B
+E50C26DB05035E7497162E7C49C38D3CD9B98D620AA67492BE5AFCA3A81A7080185C7F0B5105223F
+1FA77805502A2E8C5FEEA27699858D84A95842C5F2FB68686D59FE24091FCDDE139B6463BC6C7B1E
+0E90D20A83651AF00C85797BB9F53ECEC1675C7EE636D0D9E77DBD8F89670F855EE4D4800FF3F695
+0EFF09BBF8A0DAF6B8242840CFA5BA73BEB95115F4A78BCC02D85ECCE0C0F2EF6F328AD1DD6CC049
+5A3315B414A4D61DA50DA46D7ACCEFF6EE56451805D26B0359AF193531F95F6589CEAD6FA041AF15
+3067F88A0A2FECD135C56682DB2B45A71D1FA737C064EE9A4F404BB72A70B3AF0330359393247EC7
+81512482579865240A23CD8479F21C2C44A119EBC4E81B308DD8AA86E60C3DD8ADA50E0DFE8308EB
+1A7F201EDE8DCFDA405AEFB47E0E6CA7DDB376DCB21D37F7ACC4D3E9F26B03A8DE0E8940CA3A9E75
+963A389DF8038D2C486072F61C0CEAF500753C7A6352B1CD0338D9212B42A4D3DA23D5BDF44C27C9
+4B88A415A3242FFE2E1B332477A21D2B9CE075EE479C6E657A4D8874A8C53964229310E01ED4F3C6
+86FEF5258EDF3B464DD6FFD7F1CAF473BBE722D60FB14AB4918E93878A8AE4773930B8CEE110F476
+7F42A52D9304C55BE12846C911A10AB9B2E036BF9DFD597F5348D42233315FA80D0F563C388BC253
+2103F05E90DBF1923F229F980A2F4585C7A373511372D07DCBACA583099EA972C03E5AA67E663882
+6DB134564DB993CEEB6E7A6659C7C5C05C310267D5F8A24EEC2D5CC3E3F3C808E6D6068D1A57646B
+37FABD98ECB7BAF99E7D9AC4414A491A73CA34C52F394352F6B5A15F0FC4D88622DAC694699C2464
+84ADAC3B1D366AFEDE2A2CD2042C90516A666A19A91C80248B11224BEDDF1A320E230739E755D098
+B6A67315535F4C187CFA67ED817A035056353FC859BF286317996FFFB478A2248B908FF12ABDE705
+402224A3EE5F463DD3D243875C84E02DB968ECA1CC52C75171EA50D6A88CA91327A7AA5795019F36
+C0A19C093A1C9D3723C7568F9D41F2E4FFB712FD47F897703D7A620B586B81936C84AAED61D84332
+B3BEBC4F95B796B93EF7A1F565C494F8A65EDB21E2EE18DC025522EF8E599887CA2836069CDDD889
+88E5862977B7472584303198CCE97EF9F9E1446D1F1F5ED1CFC666A8A0C3A03E1792EFB60A9B4065
+49E0DEDF6ACCDBD98742568B4735A747D8E5DE21E630125AE0C691D054E42199C15B1F80CAFA6E7B
+B2005F374A9A5F9900ABB7409CCD50C3AFCCAB1214E6A856F7C7EBA89BC3291801E1343DA9DAD2C6
+ED075C8ECA1423B43E587AEC67E6145272814B3F191B3C285639F9E2D6E148A02DC2CBC0E054D629
+5CD05DBAC1950400A9189316F0265B86A732D302C5BEE8ED233768F237C62600CBAAFF3A110D5EFB
+6CC7CA3B92D965CA7C5E8D3E64ECF239FE2507FC797FDBE54C1112B28D4DA44C60AB09D994C5BA78
+D663A2591934CC052BC70CD1DCA3325C66C9CB982E2039F5DB70C848D3DCEF655B1C2CD0CEC8865F
+E8E1C0A267BE4F707ECE6F5A3DFCA3CC1EDF92C760439F51AA69A4C1801E96CA4D6EA4AD980258F3
+D15C893913ABCE09101984C61B91D603053E49A97CB82FBA707DAE8AF1D579FD69C8481CB7B712CB
+CDDB4D287BE995E32C02B399602A08B9DD849039B5673F1930BEC7BF366EB082D2CA5DB2385C8CC4
+5BE3FC0E31820191A814EBA7C4F23B1938E6C4D800732787CD2CB97F762DFC85D4B798809B5F2254
+D826CA42B32695428D120298B44CF38494E56240B75DF1E41E46E53C44DC505452256DFEC819408D
+605FF14D6C1F3F152F2FEA96EA0AB3B472D8704E06BE9F8C3E8395CAADD06D6DA033E81ADE5DC3B8
+3DAFF743C6E9E48716003D358DF63CD7FD3E2F727D1F2D0C29962F76D5C95ED44B6F08D052025A66
+5785F264A3D5F5593677B630E628B5EA81FB37CFFD7A30B7FAD226B6FDC82B0878AF4C0EC4F4243A
+807B9839EA62BCBDF7C2E9B30A623876E632E084EBF4A21EDA04FC88A1C07021D0C72EC3E969D449
+FEB08E5826EC20E55B21EA71EA59F6E3B0710B0DDAB3261B4A2029ECAB68C19ADD5174E55D5E984A
+4E5F38F592A302FEE6ECE732DDE841A28672C620CC5D687455A5C06FA9FE688394A04F96312ED025
+B7AA6FBCE2925F3AE559CC1886BEECDB70822E2E5CA3F732A87404B1536AAC469989E9610CFA440A
+CE43875A70CA51F36CB6F629D9424C1E35A88F92D5DA3CD8CBAE6E8425A36968E21F4F30349749E0
+205BFF8D552837D6FC39532525370BBAC833F75F1854C93FC533A4AA53ADF7008173A70D94A4EBF5
+38EA9E62BCDA7C20E0A073BEE2EFAC34D2EF1D03BABD5147659E50B557045B2EB89DB303749B04D3
+F54B43FED612FCC68206E001A7AFE90230D9C12F74A32C7EDB5D0241DC3A5D51481FD7C8FAE08FEE
+263FBCED7C7D911B3A303C835AF5FADFD218F61A9D6DE80485ABCA88200047B094441F7767B97A24
+E8C612590FA2407BAB1E8B56C71914EEF2355DD97CFAFCC192BC06FCE063D3D9D1A629AADC75E3BF
+207234C208E7E30663EDD691043065C9CBC473D97C6D4DD3DFF59D6A9ABCDD4412C3128F603160AA
+D8F81C6E7A4DCAF35F3A99B4EA10A34375B477C2BF846521A7EABD4D28078E9340452A198F3F5ACC
+3DB7E3908939FF6E3709C6A3FD9889439A4AE3E10B618CC92E14B68429A3AD2C80940A1079452EC2
+66F254657BE7D79A2A24084AF73F6DF71FBCD32BF6913A3FAB25F977787F7BB0C3A3E8BAB38D7A2D
+B0B4826950643DD1E03BD7DD1FB149A33862A89226B7CB454DAF613128C2075470E42E70A9444A8E
+6ECA526345AB48E6F5160BA23B5BDDFDA6049EC44ED1461C7E0DD514B16E2FB285F72039DE3C7982
+EFD40D7F6C8E8F4CF35AC71B467BFC578002E8D2239A2FD2C4BCCDD8AF3D7DB1F4AE7F2D2E0811DF
+9D0155BA6EDE50B5F052F14F6AB884FFF244D8806C07EBCB49ED22D85DF696995991A954AA97A1EC
+D86ACD76E061B7541E87997FEF0657A826BD88EF3A4A5920462C6595E7A156F453291CA044CED810
+860C3B0149BCE73BECA713040664AD0591304106129600AF71317B0D2907839CEAC99515D357E980
+B1937B6E1200AACADA205421001F1B2F91753E80D2263C56AA164A74701A8D5FD28E46480B0DD963
+A683A1F355D7FB4463C7347C94EA5E2CA40B60B56297CB22D972C5BB10E56715A955605256C1541D
+9F3BC5768A6F355CD3B863F0FA1A781EDB49368F51B29481CBB41D4AEB07AF9DBE8F52C5D0FF75F7
+FB6431D37D6AED84D78C778871CB0F715B4F07580F23B586C969C81B471FF6A6C7276F7E141E02A8
+584D4B9AB00E7BD643D2C3FAAA299B1F1E25048461952EA42D4882768A70DE46B213A287F8D31AC4
+6D5436F22A796C05D1FE50A9BC2A928066627A0D87DD57A3AD91DB446404B41557D1457873482005
+EA20916BBE46C613F456C849D46BA79D20627B446B2F49E3FA309AE14F8C420CFD94922CBC0FB9D3
+5A0F7DBEF577F1849A1A80E0011DA8AC082A8C6F61658E65AD177ABDF23EE17C8CF0D26B9FA3A6E9
+4837EB9E930336889767A8D7EA3CE980A8EA95528B004957BE6067CD9BD8E02A0F23CC1762CCA656
+D33412FF45E917FD4A03EB6E8C1F43FDB0A8965A33B4FD26BC24A20B304CA817E88495BA9B361A3E
+933717FFB0271F7F70C5D3CBA1E86D0F51BF3ABA194DAF32C35C796627D00C7B2271ACE2463E37E9
+7B3C826CF3DB60028F240F9452CBE08F7EBCC5FDB1BCBB3C327A9F450B9E5671916101D6E3E5E458
+CA31F04D12F592F83BADA2C3683D3886AA3B403963AB5DBE220FEC00037A745839F67A3635DFD3BF
+F08F367482962DED88ECF6322852D643A54D5D303EB04BFDDEE9BBA1EBCCBA7C653B3A613A8E719A
+DEBE3CE1BD7E754E5F4977E863E3C2D388A65227B451D4F3A4F94E06513CBA4AC1F2F511613FF035
+611684CCC461599000E546E4D972CA6960E095A526E4735A23421A4C9B597ECE08AFA2753592BD16
+DED93255A1E33DEECE3C5EB77B94670E8137F2A4A4B98AC193258E7DEA5DB8408A806188F2D1DDC4
+40CCF0E9A6E2F0C78FDBD7B68DD4939D2458C1965BF8BED4564B32462FFF3EC892C03B11D3EA813F
+AB4CFBE8D3016329C5B7E3DFED0F08284D44AA0B7A2F6BC96EA4503E8EF52A64C22BED6B452581AE
+8FF8917D53976471941A9116A2D878FB2541B561767ABD4E31CCD8A590CA03494C62AFFD64EA0A1B
+C779173DAD84999C7A8D844EB1259DE7BB5B25CD023537A474A524EBE4660B22568949E624D8FEA0
+AD37F4CE1EC75955EEFA49C6BF1803BE87E9C9865FF3F6B8525B8C15FE8835CA153D27E6C0FF0CA5
+1029A7A9185D25F0F14D86FC797DCC1F99EE97E2054B9C2A2E06FDBEB8DEF6CDD368BF23A858D9F8
+C1DEFDCEAF1B4A8DE5EAFC604CECCF0D285BE00AA912EAB66EFF4D37AD2EFE34853BBFD87CE09B18
+749B489943EECAE7887B006FB827D10191DAD18466CD1F86505879310A8B171F902EA0C26A388E13
+B53C700272CEE2BFB47ACB58247C13449C6BB9D01232C32517358F1A3DE064D43C18F8827D53789C
+CF3CE2EBE78949A6ABFA1A6B8414CE360A5E22AFB7D1DCE6F5A06182C3B984B4F9BB1A905A9D5A14
+83750A1DE0A857CD5C06945EB7D4A2A6BF1237F32A154FDC06D51A703D44FE052FD3C53E9E8F417B
+35D1C851F9203A8997521529F21AD8498F96930AA77EBAF82EE02A57BC77C792D9F220294B45F48E
+A8FD94E01CD25645D36D168923562F3FDC93CB79DD4760DA0C103C2675722D7A1B79FCB4245ED12F
+A0DB52492C9CCE58B333CFEE822812F7DCA68E802C451B5CFAEBAC608B950386B6C58239D1C62D62
+4DD5D15782FC552222CCA06DDF387B373E32C3C2864C63C768350C37283760F3515A5B0AFD66C48A
+B522EB3E808C061F5CD6BD96CD18C9839D30508E7D4EDB88E8F11E31E10919B16B7971F06D7877A0
+58D8A4944C84FC6CAEDF3341B48B6E0D3C7B85D710E0C35F5B5053CF4B4798B3778CC28B2DC7AE0D
+F3A49F9F3BCD8E95D746C35C3F47D68B8AA35D97AA08E711B5FBE70D1A623C82541EBDC51A827D0A
+69E6C049087AD26F256EB7577F58CCFFBCCBA5A95D093DC29464C9A38DE95BC6B1853963B2DEB0B5
+7AD1248D6F1625E115EEB9510B5772AAE4E3C866657DB0B3BF0E0AC345E116F8D4976B770876FFE3
+748C36165522991F46A36F193DD1A1C94713673C7E4C81582391B636C72DE94CE6254374F99B623E
+5686C13D8A8322E83E11BB0B0A896C6A8C2C4F756C5385CD7017F26D23F7C3EE97372C868C8C9155
+81723BB6B76B4C3CE8998E4FA6CA40B633DFDAA59BA902A4952DA90EC4FC3CF0F2676ACFA7F76F78
+236FA2DE10FD3545357215246BB7E527F277C28B353CC6D79DCEF21BCC8F77603CDD58A2CCDDBE3A
+9802F941CED8E035313875319548C41992A2BE939A17CC109426E33825AE59BCD17CB19F50D972FF
+CBE7D9B4B0BB095303D9DC9D406696C2508D6CE99E11CF00F6461147E97449ED5F486D480A86D3A7
+ACECB7E9A945984724EFC21C5079B1FD03ED803C2DEAFCE3327D2D7827715FD65D9506216C88B0FA
+26935E95C64114A51919D419038B1A7E9C1E829FBFB53275093752DF19891A97F3CBF7719C1FD6CB
+17019A6D2D25360ECA804C4B35172662CC4769D2B785C6C87E5A4ECCE31704E59F71263B7C3CAEC8
+ACB4C7426EC25F11A0042323EE6C3EEB04284DBAE2C770BC419DCE79BD4560AEA41571C3B595F525
+60191DC7A8FBF63D413A77A0905E517441B16C2B501EA2F9E99CC38D052679F288FDF1894542E3A6
+6989A0090185EB2E75134BFA3D9147C3DB8A621D9D35E37786853779E157B47F71626D6B3E633005
+9159C17596C1B87FE2B4FF47ED9D78FA4C2160077276C8B58CEF5DC030B4A5D83CF257096C047FE6
+4DE307C598B815058E72D5F57DF5C369E664E137DE29349E2F9DCD8C9F4EBA6E765B6327D7A20DFC
+B20711273FD8091CBA605C4C494248076F7E03DF65A6A50164980BBBB708741E5BF6056E6F996DC0
+7FFF408C5B8EAB8DCEC315E92873228C805D4440A6470E3EE3983758DD211C9CECDBFAA4C9300CBA
+00608A4B2404A3C7AF017A3B7E67F39F0B51ACF950D3E75CC7BC2B8D3480202FA958E8EE0B240501
+5232EE0D264C7CA02C18CA45CB3C2DE322D3EB7F00F9455DB6C5B1F4E59C3E95520EC36D7D903CBB
+625D70B54BF6F8255E412604BBB29FEE026CC660577F91DB1DB4A613EEEFB20CF7AE3CD89D565AC8
+38416B01B5DE4FFA5550D17FB51FBBEBE21CF1D56038863EE931B90DEC2E211ED42BA92EC244D4CE
+2C4EC5CA87A026992772DC2AF754FC982B94F36EA7B7BF75E0ECE90CBB2A6AA1A012E8898BD679C2
+3CB3827C35D5D02F0569C7AA82615D4AA67518ECF668D3B57D6EF1A8013424AC2268BA0D9A74D588
+79EDCF6382A89D397864940303EAEC45A38304BA8B1CB198967AE23EB81054BE74B16909A405E8A7
+799CEE3C270FE2A6DC50BD7370B6B2C8FDB9A87D88D5D40348D3984E39C693B6F4486D994778607A
+80A3122872DD65E40492107C71C3CF708A9717E9EEFAFBDDC239C53AA9645B711038E59C8B861B37
+411AB2039BEDF9CFD00F08D9C5D76154427FF5DD39878CECC5D7BFB3F1F035087185C0981F3C2139
+BE84872FFAD3408531C4EA9387B89F5E3EC779E8850D50992DFDCF9132BC551E985943B07618AC10
+D1150451F0844C0DC41D6E17EB508DC8689EC726400D5A7F6FEB3CC7BCE05F09228B7CB2C5393664
+D8DD9A4B96B1020EF25D70AA2D91CAE93AFB5F2BF0AA18CA5C599FA1A708EF35BF8F7FFEC9AFC1F2
+42870D028B2B1459063B493943EF1283829783E1010242E5CF4DA39D93D506F3892936E7D6CF1124
+70A521D397438733D053944CFF12D6FFAE8246F20618684F263715AA98E15D72A526383E05C23214
+B78338E5B476F0981D90056E6E5D0DB66B1DF2298E597B2ABE1D817E18BEB056E65EDB4234342D96
+00470B1420C9210419D834E431B82F58608C87AC361A02D0F1FE4B470A3D71E0D21BB87E1023D428
+E23D596CB9E1A2184403A16E36E644BCCF9BBDE27290485057E62827283E7380AF786BF395B3961B
+A5EA469C315763FA59E0F176EF81985F38B882DE56A74D128E256D1B89939728E55A92ABA21A6B78
+44FAC1BA7BBDD8B34A18194A2984B000380FE9F672E83EFDBF276FE797A325815B0F25CC95C97A9D
+ACF56D583486305D7C9E51A7E337D14E3B900333EB38FD93A99587DA2341B10C059C71CE080FE753
+3C0F059FA40E560AF9C4A41A4BE6FB45846FF8F78165E10B4AD40F264BCF5596A1E8EF8CB6EA4B1A
+3A5C69059AB1563843679ECB2511A90E8898F54295649CB73D277760D8D04ABACC7BCC6E777A0530
+E2067CCBC08673F9C8C178F9D672AC8A15E5367F0C5651B53E75E0CFA57C931746AE1A679C246D7C
+9417F1CD89DDDBD1173C2F880B7B3847CBCCEBF99F7122E832D7C9BAFE2B54CBAA1ED48158DE3F36
+238B76B0E67644A28AEA996DDC006F6AC0242E4B667639E7523CBC90A0561193C1AF34481C2EF402
+EE43A82E1EBF4E3D601BB36B2D95CD93550D61CEE7A94E72F6D30C32C8F91A61E964B1F66ACFC398
+7F95D4028F116E9A9A8474AA29C1C1A984BE0E393BDC41DCEF6A6F1018DB60D52024899D8EB5D55D
+324D73F39BFA47377B9E15B3B06A7585589FCF52A54684173E5183367E7B0952DC4BC2767C4C6247
+B1D6103E52BC7B7EA6298F454C5D97AC575F19C10ACDFF4E10C7D3755CFAB4200CAC545269FF1D8D
+B0D607C7AD47F40DDF257AB4E7D0750577003C13E4941960C3DD7B0774DDAC18E8ABAF8F53E03CBE
+F6D57B44F24CF821014C064278FD51B3427593D17694B4ABCE81F49CBB984C5878CDF0C38D1ED7FD
+99B0B9A3BD8D8FF6219588B3B8FA59D0CDD1D9B2F65122AB45E48F1757467B9204926140E3C350C5
+A927A2E700173053EC35D3F1DA2D7258714C97FAA857F0898917BD94625C6D1E2D77138EFCAAAF51
+7B17FE187A2212C24A881A2C6A647DEF6376ED80AE4175C5EE80921F001995B44E49F0D33DD9075A
+CF33BB03671C0BCC34AD5784AD1CDFED3A6D9BA103B3DDC1CC2DE74DBB576A0277715275218CD19C
+A8899209125266D8BF1286F881DCC2C383749D1E768D670F4099F7DE959EDFE852583183C9111601
+2881A56A24AAF020EA45CD5F39660DEBCE30AC1C7B8CFC60387B1B0C3E361BE612FDFA9F01B7E4B4
+A18839A2C7E0E393EBC5AD9A8A4EBC316A740C1C295D9EF5F4DFFA0667F9582C0BB837B142C4CFC6
+B1798E9476D0631111033B8BA75A10FDC800E2AB1E0E829632F869CFE4737BE9E2800759EE0831DC
+7D1195EAF80555771981DD6DC6606812D92CB8EF86447F5F6C6F626D0E265C67E52A6319189EE349
+D48E49DFE6A9E98F76C414A1E3217AE0A215A17E54AA498F4ECDC50242ACC7E2322F63BB2FF2189D
+057E7354E32A3ED1803116176B9B9D0129930F919E2FEC280B2C8924E49E7BB75768A2EE1DA8ADBE
+D4E3589906DF1B923AEF84C1BD327438B731012E69BB0D43A1842CB88BB54EA4516477F704CFEB28
+6E3EA483445AD4D74586FCF32E96D366901084365F693A53C5FB532FBFE7BC0CADC404C4985042D6
+8DBB90A6DCDA3531EE324D558A214F935CD9FCC9A0CEBE9B5FB0323F4B3820529599EF48EE068B5A
+CE85004FEA2984F0A86F5AC9D56163BBFE1142B774148F1EB0A4DC89C3349052533A7DE66729DB24
+41B82F8F7360111DACF69293C9B281A0534F3E9E9224A75C49A832F28B2E497262475507B6DDFA9F
+01CA0A6696E3F5AC7EA68595EBA0C2EB8A47813FF936D84AC1B23ECA7AA2862B793CCBB0DF9FDD49
+31BEF354CEC12FBF478559FEC29F81ADF4452E83963E56541D31F3691C93A50F0BBA5E9552C4F2A2
+3A6E53060729854A3DD71CC4308B91957DB19E66AAA18FA67055A950F1C2CFF78A03BC1A588CF624
+696068068719AFB1001C4581EE072113882D9052B21E355D401ED8CD24D067B99E616BDA5A0A5A93
+36FC499632B79FF2FD0DEFB096EF46B75E2D4E0F48DAEA239719FEC4D9A29818F5875FC5041A9EDB
+D26CAF0ACE14CC80BA49BBA59E918EB3D8F1E541AA16026585A2F72DF7D83541816DE46981FB3EFD
+0C30E458CFAD04C79421AB7C4925E23AEA07F9F018431C790002596D26BD9663B51B699DF53E4882
+CBC34EDE88EB55045B889B6062E35FD1E018BCE785157B85EC3B9CA6C85D4B16238275385B8285DB
+012D8FB7C9F5B946A41D7A0FB878FF72C39683144D8A007CFF631B43748F2D5FC690300F9BC0C837
+006B92ECEBE0605E8C3A4A400E18AE8997D1B45FEE10068E247C647CF82C6DFBE5E881D511FFA687
+B7AEB78546BFD07D5F7EC242DCEF4930D8AAAD8C6152B6642AAC325963FD147F236BB850A9966573
+9D06CDBD7CA79A527DCF461E33F22BC9C5DB00DA2BD3DDDD8C99D99793BC98282AA8872FF96C3942
+85D82D9419EB78B6AE37A5F519397700F75D624A09BD255B576E955A323E784E8FC31131F003B0E3
+024A4F58FEF2A6C043796201FC425482E1155E229D1B2D43EF7B0D22322B22EF5C9A1BE026A1C3D3
+75EDAFF99597E1E5477952A4E8D2ACF5D014BC00DC2A272FA62B6983E27D228881E2EF2B8B95A681
+CBE90C5FDE16331C85222FE2A16F0A3C3000A63E2E21666C0C119F8AF89A543D37977069A5ACF155
+6324F05204CE8CAD50FF4FB630D9CBBFC324DEDA584AA56A99D3A76FF55BDC2C2EA3A021361CCD4A
+83C7A5E2768D210FA6DE889FD48A39D679C94EC3C99A8D33FF11377DA7F6F1B71A2A05B302ECDE95
+4F26773F39AC881542F0D0969C3995C3519A8EF70B4220D86BF01BEECC6462855E7B686E1AFF1CA9
+1FB8FD8B4A69E10EE0C2AD94ADD44449506F9B6EF43641F2026EFF6E605C670560C2B74706FB949A
+A7E8CC6A2D0D6207E457E7FD87EC1B9092DC68B9143947CC8ED14AFDDCBF8FDDA228A76847F96802
+E561F67CEEFDE45AE587673983FC04C96744DBAA83F2DC838D633943C75DCB9E6410474EB27B348F
+26E505F0AB90878940E846C5E9F3C5FE8C3558C3236B1B88C405716949B8506841CABE1717474BB7
+C30DB91CDEE33B0F844811762FAEC535BDCF84C1C747CEF9B1FA61D2AFB5A81335BC42C06A94D7D5
+9B7EDE55BCF6F9867AEE107555CDD084B7684C2C87087475A39A9DA6347BE281CE5635A4D07865BA
+98CE26C1465B1AB0343F49FF37B4D0CA9F3BB693D78DC3B21925CB996A038DCC172527FE57C07460
+EF39C07D4396E7FA970D9F22ABD21A9C794B64AD96762C7428F59A8757C36D6C4FFB23216195A04C
+2A2C2E7B10EF7193931544D782FEE4B91E01119C5553BBC6252270A8D8C56DD62D448F5AD8DC69CC
+B45E1F17F0AA1E445129DD00F000005B23D38DE93A3BE55A4C041947F36B4E4536E307D0180553F9
+2E46B743881CB5D5386C48C7D5F84C2BCD06B9C501F78C7EE61FA23516791FCF4DB278AF688A2E60
+10A56692AD92008497487EDFE4BD5FA083FA544138B20D6940020887E35D46E093B71F7A04A67460
+DC8116B4D4839625D7CA6959D6831CD93F81AC4EA2709036DD738364FDE71113BF22EBF13DFE1642
+E564701E6F0FFE7511EDF03FE448C2B28C64FB7D54B94CA576E481FA56B2B18AF10C71F699B6BFD4
+7459CDE1869D0FD306BF489A6F42E5B2F05CCF55BB6B9526973D19CB134CA7F13F1DB3716F8CC217
+73A832568C16250B5CDB16DF24BF81D49F5B37018BD310262EA7078107868AB0216CEC83CEFCAB1E
+9F2C665A31585CA04DC01879CAA79AAA5AB201B516F7052B01B16BEE5606098393B0E5D9F9E5E3F4
+EB20F63C958E796DF41CF28839F5C62A0431648745D7837B519F3AA36BC6C08EF040CCF53D9B6D8C
+0C7D1A84D707EC57A3C6AC9A62AB37251A01A5ED40FDEC6F5BE6E34C6A91D058319439778A2EE5D0
+363E2E1F33463C33327D05FFC0CBF08D5BC457C7230448972FB9B4D0D782BA7DBF10D3FFEF8BF523
+6EC16D4DD6D0D870D9D5EB5C64C9A46A4F583D4F831FEE74B0E5B33A09ABFD4444929BD8F638CD72
+EAB99CF2E9551DF427683964A592E49D186F285258C5D5F62196A98532421D73E3495F82695FEEC6
+E1952C562D546B28618FFAEEBEFF03A57F4D855021F85B0C7BC37FCC6DA9AECA099B646B99D41896
+09D3FF2D56422F8C37E97640293EC7C90E3380887836F4938FBF495CAC14FBA5648D89282D8D49D9
+1AF73ED36581139D8BD42551E263E830EA3C6EB381D85C42D74C50DB0CCAEC03F535ADE92128A016
+0E811C34748309AF7604919B66CD43EB5CA975302DCB6076FEB6BDD6FF55976FE990FB0CE9ABB11B
+195403FB26E3D6C6A0DE1C5BE79E171A61E21F79EE8DBE7A832519813EF6B33EA098C2C32ADEA219
+AB2AAC8B093F40000995539D1276D5F2EF84CCD099B71FE4269BDBDB6A8D59C86F7D2E3FBCCF8773
+D0FAE97640BC1AD43CB4B992BFADFB09DBD0CAAEB8CD9DA264187C4F97300E9A6C9DEED5525479E6
+05C65AE336CBBDF4E5D7F79AD098F977285E065579B748FEAA97F2A753E1F962FCAB68D72BAA8EE4
+FF6691C23E31BC0F3E981A96FB440404856AE1AB32A7205B17D411D8F21C8C93B704D07EC594422A
+BC368CDA2B1610CE6A973F4474E12B78B532666797F5755D269772C9F5400B3BFC6C58395D38527E
+2CCCF29B56123F7DCEF3BDE5DC1DFC5B0293BB125085B1D2D929BC3EE84F4FAD571A4991C3DEE03F
+2DB3A3097E52B1A7D5C73CCB6148EAC62E8E36DE9A71C57638C6E4D5D9DED18174E8C390E50B4A5B
+913C074EEAEBE390B214B3A68F02862B9A296DB4B409769649E51D738CBBDFB7702E15C73C2AFC6B
+C37CE15171F4E822CF20EFE55D9F061AA43E648989628FF79E65932390CBB15D8E621333B18B11C3
+BDF96F841D7434E01AD501FEA964A75B248A35CD9DF9A37E48A1E5A09C624B93CE44F0042FA00D7F
+9EE89B9F7AB785E9C718CF6E7228F743271C2C9BBA17E5208B920E44E765D99D86650EB454B0FAAA
+112753AA1BD3A24239E9C5FC47EEB1547AC9D23731B8DC48B9707830DAEC60C8D3790BBA1120F776
+4EFAC542CFFBCD5C05F9510B27B2534B704ECD36C8B041FD49A96881302FFF5B0163A2DD09C751D6
+D6AFEA9170A4F4C4AB8D46E62F763FE1BDA51DD1CE4A27E772F3A2869155F762FF26B7AA6FCFA4F1
+292E56F03AAB6322BF867E7710C34D43B5D85B45AA68014AD7879EED051B1933E491496E3E26D9AA
+8B80A07BF2B94F1077E84A9726F08199887D66DE7A307BF33C30DD9CF3DA188088C03B2BAD09A217
+6B110DB2C868B53DA9A66C85737BA66C93C58A259860E294AD0191E3A72C73F40B0BD98699AA08DA
+F03587B78F391F3A4313C58D9F29B53C70785637BD0C58310109C54091AB0A34CBB0C478613A7AC0
+FB8F0A8B4645AC966395D8BA775262CD291136AFFDDF01C1D83DD4EB3B59CCAD18057FE7D92A8CD4
+A58F22508D9FD7CF356571F701BBB23E749BDDCBF8A317FDA0AEFD952BB18545610FFAD3AC143D35
+1B8DB3F66293375E0E50235F0D0466932181D377EDD32A5F0FFA4E22B5A0CB4F343D9A7E4A342E9D
+09DFF6C697630CD3971802C277A5590B8CA94BDE6B38446C794D072BBCCB724D5BC208EEF1B018D7
+39373BB910D668882CAA779C2D686081DE6A2606417B54D7C20E0E7F722648D893E4EDBAE8F00D6A
+6DA3712F91AE860C756D1127D133AB828E9D80023B50B162C5A1C5CDF70CCB3FDD7EA060ED20838B
+E1E50C4094C9E79E1A0187CDF780CAF45A725964F004253E034C5BE46BBF89D94631F1A33BAA35B8
+4FA2A9D08481C6674126CD96ED05DCE48BDA069D902D6836D5DFBA701DC0F98A863E64F0E312145D
+8DC0B77F25B43AEC729A1243B45B08CA228DD6101CAA2AC5ADCC8EFF84A4CA3F254176C2CC711EE6
+C273835D0FD3528ECA2A976B88E51FE347FDB60F32370B66D338931D6581630ED586F349C638960C
+31AE4204E89521A96E1219E696B913DEB2AAB7A3B022D06F34FDFCB810A04E60A4FEBE284C2F063E
+0AE9EDF87704921CCFA193BDC912B747E13570066223A49F1F6E2AF0D4D65DA04CA876FF7A462FFC
+9C0BA2CC545C3BD36DBE762F32B2D6BE5867C59F479195C92440DC165098B74EA5C3AD93CDF2D410
+B04C16BC7801E7956F4E5107450787AA592493171C3628E6B8F49D4F8429EB98DC52EF025F001387
+BC1A7093F7A99F10B5D2D7DD8BBB393BF6E56F08F4F7FA1A343F220D5A1EAE7168C74D41BE1DC1A8
+3BD65B72B982F4F7B34F24F97F9EC9A91011064031FACFF2A14921A32024385F4E061CD07D152E74
+1BF97156D951A342488FA7F5EF934CCAD13E2753A0AB7A1F565C2F7F6B349DF03BBC25BBD972A9AD
+F809BB5C5048A8CCEF9297B2ED3324D18867F293CC66E88B3A39D107B610DFE79A3B4E83A96D3D52
+A17FE8A62C9FDD271130148366942C9CE57558D023DA5F7501319EBFA33DE9E6D1E76D7C20DB8A09
+B657839DA99F3D8143F1EE6253A3295C9651FA4366547893C2DC7ABCBF4BB7609DE5D001E0A36D9F
+FBE01F7D0903B3208AE8547E2E5F14EC1AF4C2535CA8F4EA37E3F3CE172C7A1E8308995B1CC23E6E
+81190246BCAB6E755BF868D449BB02A2AA87C44C9CC0F571ADC72547CEECBE104BB274B8AC16DCB7
+5D5F458D356466B921ACDEEAE384E2EB1DF6EF393B41B9747F0A4FAEB4AF1928D9AD6FB7E06FDC62
+1E4C6FC98CFB43F88584BD55D9B97CC9549093EDE586912161931162B1B1D52D0443260DABA02AF2
+B4432100D5506546013DA703573FA8013685CC798CE501960093DED713FFCCF89CA2B9106390198C
+29A00864108CDCC1984A8BAB53919028C01B26ECC7925E38CBE6CCA8978EE21C2B06E7B3E48FBA97
+8E2A7D186E563C088F84AA23178B60E4729EE87D67B1091F3B6973676C1CBFE6530EB773C62E2C24
+97014AB0E8B71A1F4E86A378AA26591511BEE3CF3D64C94848582E1354E1605B6457823F2C5E640A
+D3802946BB2E7E8E594E8C04B430C2385DD40746CE8534F50842E74D7115F3DB0C72D1C9C607C657
+3B094AEB73B7A79876CFFC3E2F8C9FEAAA07D3BFCE05B61F7749A8793BE90CCCECA2D7077F25E899
+D3331FE161A7E86C842495D584C6E4A0880B2951D8A13B88C4672080A0B1BE36BF47C3ACE7288CFE
+41A8C1BAA6F0814A947FBD6B3AA72B6C73A8C578CA51CCC96F2352316C467BB960E981F2B6485BFB
+44B577E71EFDA16E7405954BC7C9F0759F5A9F1EBCD2FA9CC9648D5831A68887F41B15081A204C24
+B4B992A231DEF9E698D4C3A25B6F5474F5BE6A601F2D337A58A0D21FF37FD91EB86D1D738893A03A
+69F0CD743F611CDFFE69DB2C6ED0E4611D56F803BB0DC06E7FE85A303839612707647B1BE9FAF8D6
+84122CA9E5CB8BDE2936D3F4FF254D31529D7538BBD4D35539489F9E7316F24214B996BCDCF1818E
+749A71CF0E8845AA1E2A58AA62A48E02BA4564625D20AA220EE719608521D7D7A7FCA0BD8904A401
+9819D371F3F59D46C1354E5FC1A6E5F79B20CF4ACA2BF0F2DE73DA193A6F9ACBFE0B4731C4BCEBE6
+D96FE822965DE965232282A3A130361F188B3AABDA95A8A2790D9240BE008B6A6DE4BBFCADA05B67
+86B9BB8E0DFA0C30043A3B07ED46277E07B9808422C8ED16758B9C396F4EA929D769785B2C9568E5
+70A83B989B25CE200F1727D41E2B702E7F88F1784F4C83FA60A74EB26B2DA95126E508ED519A61CC
+151DB6804F61826C5F86D8FA89D06E526FED97A0DB88EDB432FF32C1ACC9B622EEDF601081AF7B96
+3C9CFC1D13E4A9C74FEA0A1C8E3D8653CD92A944D4CA6B0D306619AFD503506D77732D6514F604BE
+4610C2560931BDE0B40939BC1D126B0E97F72AE1B4A9252123B54F7A27E0CFA4425B4546526FD741
+CA77952B10D13E0AC2E32006A903808FF0CD013F936238C74CC75FD915244C56A8412F37F0134840
+347699508D6F3D7F3203A25B7C70100719582CD588590EE34B3AB13E255B613A6D00386A0104CC5E
+D2C646F09A88888D3751651D5646C5227A3C80E8DA1B0A331121DD2429F1F4775D30564DFF47D01B
+BE2C6C72CE4D1FD9A2077C04D2B0274B8916F6A9D1A4A6964A534F47CF241D5A8E34B23F85BE9ACF
+FC2FEA961F277539F215F8728D6788F67BEAF45502839BCF23D8763C3949352F00C579A9A4FC408E
+C625E310DAE61512DFE6844E82D36A2F81709E1F05B38AE9C222ED62C961EE63593CED7AAF73CE2E
+D3667740C77B309B93EEFE1B4BA65D48575A66BE86743DC9E5D3C2FF418D11F7F211B86E827EE1DF
+C3613E7498030F07050524536D1F8A94DDB6698BE7B963C55CB3F74B676CD815A7B3DF4B1A0EA2BE
+1B0B9A11FFBFD5B1FA49668AEE14629316AF436A0821C20BEEF7B3480847934A99F6D85B68F4DDF8
+859A754E009428AF89A90D1852C220A607FF0806E8080726EDC94D691D214B4521C147C4273AEBDD
+BB4A697EF16448CD9B2FC95293305858DECFD406B89B9F3FDAE2AC579E80CF321EBAE5701FB2F7CA
+D8ED04B4A63115886D45D6120F69AEF1A21D80AD3C2D35D2899F1902242B96CD349E0AAADA40F7A1
+1282B6B52BDD97708E58DC5E2D22D1153E5FA3F3B300BCDFAF98DEC2F4E3C82A1C85F985735F3987
+4F557579F422664E07CBE19DA680EFB0FC82C323EC5C4644C51709AC8D674608A8043C91E6C7988D
+430F10BA6CE1FC7FC0604FCD8F723895250AEC36CC35B3FA14FE2A0D24095DCC30B2093F2298F5F0
+A97676A0BE66C3DC9ADACFE2FC0F721A20E945AFC1096A619075D5E9A264C796EC6C90EF1AEEA8DC
+089B44FFC13D27CB2370070A52D4416C53F364393E46EDD7EDE00799960CE6E0D57E4909E88ADD64
+BDD2B0EBE2D73FA6ACF8B40280DAA0637E705C65AABD523B8815F22F23E9FF81E7829C7E4BC980C9
+143AEBE1A04DC0D253396BBB7268BD5AEEA356B610D5DCEE03135E00AE34388251F31714A1C40E18
+2652C48CDA2211A22CB6F02490E69A44CECB169754C53B16028D352E0119F5D5FAE0BD7EA1CDA647
+12A6147374B64244E21E9EC9F0D1381AD22D5B6212B26C3F9AA5F6045F25DD9F5EB4489EA39B1945
+331AC70510C5752557DE21D0A6CFC1EB10A98FA867B76DA6E4249469F591FD154D39E89364A43DB0
+07AA0D7A911CFAE6CE2B557997FBC44F55A27F622BD7B8B10EC9F5D10F2649A646FD964AE1B111B3
+5B46A252C4DEE44E7426EB5739F24E8A390694597DB3A1FE7800C97E59558322F0E49A0CCE2AD94B
+1E2D1026AFA771723E3F523916F55ED866C9FB4A2F759651C613A2CFF362028CDF9D38F05D4C7C60
+24C533E930B64B099FB1AF04B01F5FB9CA6867E6EFF55A772C5391831059987E10CBF987E3F378E0
+1329F73D54DC0484177D3C3C06F67397955FF1CA4EF8AD1606B70455255D631A7D6EB92BFDBA14A0
+FF28B2ACE7E81AD666EA9B3A0F5A6BA3B5DFE35044FA4B3D8ED956009C60E98CC132F2E84967F4A9
+8A67B336D5EE7CAF7DD1F74D1FA08619941361FA7312CF225D89CEF97E864C8369EAFAB94D97F056
+5505D825972B754F6729596EEA91210B75DD8F645382ACE36DE60819A02B3B48DD00F5485F9264F9
+FA926D732E2C267B0BE8CA98526F124F97EFDB86132C5EF16B103908172FC51F286FFE45FF253512
+E0033F037FF182BA536A9EB2DF2D1DB257D9C86C46E1B002FB32AC70CA9462E6EB48994752CEBCE3
+9F08ABD4F4B0889283E55500702185A841E328
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+cleartomark
+%%EndResource
+/NimbusMonL-Regu-iso1252 /NimbusMonL-Regu ISO1252Encoding psp_definefont
+/Times-Roman-iso1252 /Times-Roman ISO1252Encoding psp_definefont
+/Times-Italic-iso1252 /Times-Italic ISO1252Encoding psp_definefont
+294 254 moveto
+0 0 0 setrgbcolor
+/NimbusMonL-Regu-iso1252 findfont 42 -42 matrix scale makefont setfont
+<202020202020>
+show
+445 254 moveto
+<63617365204D45445F544554524134>
+show
+823 254 moveto
+<20>
+show
+848 254 moveto
+<3A207B>
+show
+294 298 moveto
+<202020202020202069662028696E75656C6529207B>
+show
+294 342 moveto
+<20202020202020202020666F7220286A3D303B6A>
+show
+798 342 moveto
+<3C6E6D61696C6C65735B695D3B6A2B2B29207B>
+show
+294 386 moveto
+<202020202020202020202020656C656D5F69643D2A286E756D656C652B6A293B>
+show
+294 430 moveto
+<2020202020202020202020206F6B203D206D794D657368>
+show
+873 430 moveto
+<2D>
+show
+898 430 moveto
+<3E416464566F6C756D65576974684944282A28636F6E6E65637469766974652B6A2A287461696C
+6C6529292C>
+show
+294 474 moveto
+<202020202020202020202020202020202020202020202020202020202020202020202020202020
+20202A28636F6E6E65637469766974652B6A2A287461696C6C65292B31292C>
+show
+294 518 moveto
+<202020202020202020202020202020202020202020202020202020202020202020202020202020
+20202A28636F6E6E65637469766974652B6A2A287461696C6C65292B32292C>
+show
+294 562 moveto
+<202020202020202020202020202020202020202020202020202020202020202020202020202020
+20202A28636F6E6E65637469766974652B6A2A287461696C6C65292B33292C>
+show
+294 606 moveto
+<202020202020202020202020202020202020202020202020202020202020202020202020202020
+2020656C656D5F6964293B>
+show
+294 650 moveto
+<202020202020202020207D>
+show
+294 694 moveto
+<2020202020202020>
+show
+495 694 moveto
+<7D>
+show
+294 738 moveto
+<2020202020202020656C7365207B>
+show
+294 782 moveto
+<20202020202020202020666F7220286A3D303B6A>
+show
+798 782 moveto
+<3C6E6D61696C6C65735B695D3B6A2B2B29207B>
+show
+294 826 moveto
+<202020202020202020202020>
+show
+596 826 moveto
+<636D70743B>
+show
+294 870 moveto
+<202020202020202020202020>
+show
+596 870 moveto
+<6F6B203D206D794D657368>
+show
+874 870 moveto
+<2D>
+show
+899 870 moveto
+<3E416464566F6C756D65576974684944282A28636F6E6E65637469766974652B6A2A287461696C
+6C6529292C>
+show
+294 914 moveto
+<202020202020202020202020202020202020202020202020202020202020202020202020202020
+2020>
+show
+1327 914 moveto
+<2A28636F6E6E65637469766974652B6A2A287461696C6C65292B31292C>
+show
+294 958 moveto
+<202020202020202020202020202020202020202020202020202020202020202020202020202020
+20202A28636F6E6E65637469766974652B6A2A287461696C6C65292B32292C>
+show
+294 1002 moveto
+<202020202020202020202020202020202020202020202020202020202020202020202020202020
+20202A28636F6E6E65637469766974652B6A2A287461696C6C65292B33292C>
+show
+294 1046 moveto
+<202020202020202020202020202020202020202020202020202020202020202020202020202020
+2020636D7074293B>
+show
+294 1090 moveto
+<20202020202020207D>
+show
+294 1134 moveto
+<2020202020202020627265616B3B>
+show
+294 1178 moveto
+<2020202020207D>
+show
+220 1289 moveto
+/Times-Roman-iso1252 findfont 50 -50 matrix scale makefont setfont
+<4D6F64696669636174696F6E>
+show
+507 1289 moveto
+<6475>
+show
+583 1289 moveto
+<66696368696572>
+show
+740 1289 moveto
+1 0 0 setrgbcolor
+/Times-Italic-iso1252 findfont 50 -50 matrix scale makefont setfont
+<534D4553485F5352432F7372632F4472697665724D45442F4472697665724D45445F525F534D45
+534844535F4D6573682E637878>
+show
+220 1344 moveto
+0 0 0 setrgbcolor
+<706F7572206C61206C65637475726520E02074726176657273206C6520647269766572204D4544
+20737572206C612073747275637475726520646520646F6E6EE965206475206D61696C6C61676520
+534D45534844532E>
+show
+294 1445 moveto
+/NimbusMonL-Regu-iso1252 findfont 42 -42 matrix scale makefont setfont
+<202020202020>
+show
+445 1445 moveto
+<63617365204D45445F544554524134>
+show
+823 1445 moveto
+<20>
+show
+848 1445 moveto
+<3A207B>
+show
+294 1489 moveto
+<202020202020202069662028696E75656C6529207B>
+show
+294 1533 moveto
+<20202020202020202020666F7220286A3D303B6A>
+show
+798 1533 moveto
+<3C6E6D61696C6C65735B695D3B6A2B2B29207B>
+show
+294 1577 moveto
+<202020202020202020202020>
+show
+596 1577 moveto
+<656C656D5F69643D2A286E756D656C652B6A293B>
+show
+294 1621 moveto
+<2020202020202020202020206F6B203D206D79534D45534844534D657368>
+show
+1050 1621 moveto
+<2D>
+show
+1075 1621 moveto
+<3E416464566F6C756D6557697468494428>
+show
+294 1665 moveto
+<20202020202020202020202020202020202020202020202020202020202020202A28636F6E6E65
+637469766974652B6A2A287461696C6C652D6E73757029292C>
+show
+294 1709 moveto
+<20202020202020202020202020202020202020202020202020202020202020202A28636F6E6E65
+637469766974652B6A2A287461696C6C652D6E737570292B31292C>
+show
+294 1753 moveto
+<20202020202020202020202020202020202020202020202020202020202020202A28636F6E6E65
+637469766974652B6A2A287461696C6C652D6E737570292B32292C>
+show
+294 1797 moveto
+<20202020202020202020202020202020202020202020202020202020202020202A28636F6E6E65
+637469766974652B6A2A287461696C6C652D6E737570292B33292C>
+show
+294 1841 moveto
+<2020202020202020202020202020202020202020202020202020202020202020>
+show
+1100 1841 moveto
+<656C656D5F6964293B>
+show
+294 1885 moveto
+<202020202020202020207D>
+show
+294 1929 moveto
+<20202020202020207D>
+show
+294 1973 moveto
+<2020202020202020656C7365207B>
+show
+294 2016 moveto
+<20202020202020202020666F7220286A3D303B6A>
+show
+798 2016 moveto
+<3C6E6D61696C6C65735B695D3B6A2B2B29207B>
+show
+294 2060 moveto
+<202020202020202020202020636D70743B>
+show
+294 2104 moveto
+<2020202020202020202020206F6B203D206D79534D45534844534D657368>
+show
+1050 2104 moveto
+<2D>
+show
+1075 2104 moveto
+<3E416464566F6C756D6557697468494428>
+show
+294 2148 moveto
+<20202020202020202020202020202020202020202020202020202020202020202A28636F6E6E65
+637469766974652B6A2A287461696C6C6529292C>
+show
+294 2192 moveto
+<20202020202020202020202020202020202020202020202020202020202020202A28636F6E6E65
+637469766974652B6A2A287461696C6C65292B31292C>
+show
+294 2236 moveto
+<20202020202020202020202020202020202020202020202020202020202020202A28636F6E6E65
+637469766974652B6A2A287461696C6C65292B32292C>
+show
+294 2280 moveto
+<20202020202020202020202020202020202020202020202020202020202020202A28636F6E6E65
+637469766974652B6A2A287461696C6C65292B33292C>
+show
+294 2324 moveto
+<2020202020202020202020202020202020202020202020202020202020202020636D7074293B>
+show
+294 2368 moveto
+<20202020202020207D>
+show
+294 2412 moveto
+<2020202020202020627265616B3B>
+show
+294 2456 moveto
+<2020202020207D>
+show
+295 2573 moveto
+/Symbol findfont 50 -50 matrix scale makefont setfont
+<B7>
+show
+370 2573 moveto
+/Times-Roman-iso1252 findfont 50 -50 matrix scale makefont setfont
+<4D6F64696669636174696F6E>
+show
+656 2573 moveto
+<6475>
+show
+733 2573 moveto
+<66696368696572>
+show
+889 2573 moveto
+1 0 0 setrgbcolor
+/Times-Italic-iso1252 findfont 50 -50 matrix scale makefont setfont
+<534D4553485F535243>
+show
+1161 2573 moveto
+/Times-Roman-iso1252 findfont 50 -50 matrix scale makefont setfont
+<2F>
+show
+1174 2573 moveto
+/Times-Italic-iso1252 findfont 50 -50 matrix scale makefont setfont
+<737263>
+show
+1235 2573 moveto
+/Times-Roman-iso1252 findfont 50 -50 matrix scale makefont setfont
+<2F>
+show
+1248 2573 moveto
+/Times-Italic-iso1252 findfont 50 -50 matrix scale makefont setfont
+<534D4553485F53574947>
+show
+1550 2573 moveto
+/Times-Roman-iso1252 findfont 50 -50 matrix scale makefont setfont
+<2F>
+show
+1563 2573 moveto
+/Times-Italic-iso1252 findfont 50 -50 matrix scale makefont setfont
+<4D616B6566696C652E696E2C>
+show
+1826 2573 moveto
+0 0 0 setrgbcolor
+/Times-Roman-iso1252 findfont 50 -50 matrix scale makefont setfont
+<706F7572>
+show
+1943 2573 moveto
+<6578706F72746572>
+show
+370 2633 moveto
+<6C6573>
+show
+465 2633 moveto
+<73637269707473>
+show
+635 2633 moveto
+<707974686F6E>
+show
+813 2633 moveto
+<6465>
+show
+900 2633 moveto
+<7465737465>
+show
+1031 2633 moveto
+<6475>
+show
+1119 2633 moveto
+<6D61696C6C657572>
+show
+1326 2633 moveto
+<74E974726168E9647269717565>
+show
+1589 2633 moveto
+<20>
+show
+1601 2633 moveto
+<3A>
+show
+1654 2633 moveto
+<534D4553485F626F785F74657472612E70792C>
+show
+370 2689 moveto
+<534D4553485F626F78325F74657472612E70792C20534D4553485F626F78335F74657472612E70
+792C20534D4553485F6D656368616E69635F74657472612E70792C>
+show
+370 2745 moveto
+<534D4553485F6669786174696F6E5F74657472612E7079>
+show
+912 2745 moveto
+<6574>
+show
+966 2745 moveto
+<534D4553485F506172746974696F6E315F74657472612E70792E>
+show
+1581 2745 moveto
+<534D4553485F6669786174696F6E5F686578612E7079>
+show
+370 2801 moveto
+<657374>
+show
+468 2801 moveto
+<756E>
+show
+560 2801 moveto
+<6175747265>
+show
+703 2801 moveto
+<736372697074>
+show
+856 2801 moveto
+<707974686F6E>
+show
+1038 2801 moveto
+<6465>
+show
+1127 2801 moveto
+<7465737465>
+show
+1261 2801 moveto
+<6475>
+show
+1354 2801 moveto
+<6D61696C6C657572>
+show
+1563 2801 moveto
+<6865786168E9647269717565>
+show
+1875 2801 moveto
+<74616E646973>
+show
+2037 2801 moveto
+<717565>
+show
+370 2858 moveto
+<534D4553485F666C696768745F736B696E2E7079>
+show
+859 2858 moveto
+<657374>
+show
+933 2858 moveto
+<756E>
+show
+1001 2858 moveto
+<6175747265>
+show
+1120 2858 moveto
+<736372697074>
+show
+1249 2858 moveto
+<707974686F6E>
+show
+1406 2858 moveto
+<6465>
+show
+1472 2858 moveto
+<7465737465>
+show
+1582 2858 moveto
+<6475>
+show
+1650 2858 moveto
+<6D61696C6C657572>
+show
+1835 2858 moveto
+<73757266616369717565>
+show
+2061 2858 moveto
+<656E>
+show
+370 2914 moveto
+<747269616E676C65>
+show
+621 2914 moveto
+<7574696C6973616E74>
+show
+880 2914 moveto
+<4D45464953544F5F3244>
+show
+1279 2914 moveto
+<61766563>
+show
+1469 2914 moveto
+<6C276879706F7468E87365>
+show
+1792 2914 moveto
+<6465>
+show
+1938 2914 moveto
+<6D61696C6C616765>
+show
+370 2970 moveto
+<534D4553485F4C656E67746846726F6D45646765732E>
+show
+1028 2970 moveto
+<4427617574726573>
+show
+1275 2970 moveto
+<6669636869657273>
+show
+1508 2970 moveto
+<6465>
+show
+1637 2970 moveto
+<7465737465>
+show
+1811 2970 moveto
+<736F6E74>
+show
+1977 2970 moveto
+<7072E9767573>
+show
+370 3026 moveto
+<534D4553485F506172746974696F6E5B322C332C342C355D2E7079>
+show
+1000 3026 moveto
+<6D616973>
+show
+1110 3026 moveto
+<636575782D6369>
+show
+1273 3026 moveto
+<6EE9636573736974656E74>
+show
+1509 3026 moveto
+<756E>
+show
+1576 3026 moveto
+<616A757374656D656E74>
+show
+1809 3026 moveto
+<646573>
+show
+1891 3026 moveto
+<706172616DE874726573>
+show
+370 3082 moveto
+<6465206D61696C6C6167652E>
+show
+280 221 1 967 rectfill
+2125 221 1 967 rectfill
+280 221 1846 1 rectfill
+280 1187 1846 1 rectfill
+280 1411 1 1056 rectfill
+2125 1411 1 1056 rectfill
+280 1411 1846 1 rectfill
+280 2466 1846 1 rectfill
+showpage
+grestore grestore
+%%PageTrailer
+
+%%Page: 6 6
+%%PageBoundingBox: 18 18 577 824
+%%BeginSetup
+%
+%%EndSetup
+%%BeginPageSetup
+%
+gsave
+[0.24 0 0 -0.24 18 824] concat
+gsave
+%%EndPageSetup
+%%BeginResource: font NimbusMonL-Regu
+%!PS-AdobeFont-1.0: NimbusMonL-Regu 1.05
+%%CreationDate: Wed Dec 22 1999
+% Copyright (URW)++,Copyright 1999 by (URW)++ Design & Development
+% (URW)++,Copyright 1999 by (URW)++ Design & Development
+% See the file PUBLIC (Aladdin Free Public License) for license conditions.
+% As a special exception, permission is granted to include this font
+% program in a Postscript or PDF file that consists of a document that
+% contains text to be displayed or printed using this font, regardless
+% of the conditions or license applying to the document itself.
+12 dict begin
+/FontInfo 10 dict dup begin
+/version (1.05) readonly def
+/Notice ((URW)++,Copyright 1999 by (URW)++ Design & Development. See the file PUBLIC (Aladdin Free Public License) for license conditions. As a special exception, permission is granted to include this font program in a Postscript or PDF file that consists of a document that contains text to be displayed or printed using this font, regardless of the conditions or license applying to the document itself.) readonly def
+/Copyright (Copyright (URW)++,Copyright 1999 by (URW)++ Design & Development) readonly def
+/FullName (Nimbus Mono L Regular) readonly def
+/FamilyName (Nimbus Mono L) readonly def
+/Weight (Regular) readonly def
+/ItalicAngle 0.0 def
+/isFixedPitch false def
+/UnderlinePosition -100 def
+/UnderlineThickness 50 def
+end readonly def
+/FontName /NimbusMonL-Regu def
+/PaintType 0 def
+/WMode 0 def
+/FontBBox {-12 -237 650 811} readonly def
+/FontType 1 def
+/FontMatrix [0.001 0.0 0.0 0.001 0.0 0.0] readonly def
+/Encoding StandardEncoding def
+/UniqueID 5020945 def
+currentdict end
+currentfile eexec
+E98D09D760A3C22CF119F9DC699A22C35B5B35ED6AA23593C76D54CABB5E942BF7D6DD84F1664B89
+699C74B472DE9F8E6DF925F6C4F204E9F1C639B4DBA988ED2AC419FF2B2BDE605B8EE3264EDD6641
+2D4F21C64AC522BDFC7C5502F9C3F3E5592B3B2093D33C9BFAEDD2D49E89AABAA832E23F062E91A2
+5032519D1868816E44B4E0747795003D7930299D6E1E2A5BFE0D595DC97E140989CE81D8D7F852FF
+9CDC7A1B1B598C69131DEE005B415805A16D8A123E6A2261C63C769D2F4B60FA2C438AD7D199D8E4
+5F7E7C9A605C8CA14E21FCD81C9A515FB8DB6F99604534D06EA9D87FE0FAA852899C9D0595C7A97E
+6C55F79FAC45CD38E87B10D210CE7501E88C8FCD3444354365FB893A12F596AE2C1E70D5819EE0D0
+87D10BF8DA96F3DABD5405D28C4228C6C31BA4052464859640933FEEFD8071C0C84CDD829A9B1D0B
+A01F25A4D50EE2EA2B45160CA6333B2D2800306ED2BEFDFE155E9D9F9342EB8D5B0ADBF2460CCC98
+643FB1287CCD28ABA7B5CAB92EC39EE2E918990372B16F8487EBA30EAE88708B6CF33B6C015D8096
+C7CFE2F139F52052E3925C0D50FD64CE68236D59CB83EF56BFC584150EC38065059F3308AD6F9A99
+F83EF4E6CB13855C8175E31417D190D036B387D3952344A950F4D8C7781B307A094DF1ECAEE4D2C2
+FD747BC6F7F9C6BD0E90C19294F96C8C5CFE88FB34C477574A1B1630B8CC591529E59B20794DA32E
+61DECDA8ABBD1AE956CF74012AA01D42EE01E861B0AA6897C864788AE59DEF43C493246FDB1ACA55
+4C12594BC7B33657A9ECC9E3D1472EF826073F632BE540C35FF6FB40566773F3BB2204D3A579A08C
+CBC844C14B18C350F003B9DA23A570C362D6003893CA32F86F59B829C78EE3188B6E3F7FA81D7F62
+2825C639638DFB78B7AF1F500F5B450FA54DBFA5CBA277C794ECE93275A3DE0B452FDC8DDC2993BA
+A42F28A636008CDCB03EBF71BDCAF35019778993443F88412AD2AD0D7155A3944606463266322DBC
+0244B07DA1E9C27A27B59664E8566D7A54CC03E995AAD008B0A17E2C3EF61F720CE7F7788599C4E4
+4C709CD5C31B11107F16AD70B17B9AFE2E8CD922A7428DAC171427FFAF51067307FAB0ADB530E701
+FD22DA22C4CD3064067BD4F6089C4B2C87937DD426E4E9D2F60E608288BAC9056554D04947E69200
+61E379CF5E81BFD32FD37EFAC1F61CEBEE551B0851516471A7472C60DF89DAA9EB1DC5A67E479745
+3E69B9E22BAF4E3CCA4192D603295B018C4AB69D18DE52DFDF15E96B557F290A4B8C5B1E7A6CACA8
+1F2351B97ADFC36995ABA43803A6E5AC04A3C93495F6D38106B8B144449C07D1358210F9176E1565
+72363CFBDE576BFDF99FA329DD1346E83F79E06CF68250CA57A68931BC7F342AD295D0CBA17AA95B
+B8EEB53EA6E8E660B814E9F857CECB14F44A43288B69A9E7908D55BF19E844359879D28CAEF1C38A
+36420185D20DFB32C2E002202800E8EF3D67C5D50E919657CA958B538D537D503444865331D79BFC
+40312068D72364503BD0CC84B5F30A74D8B5B6A26AF2DB764564FB65A6BA8F9051AE2B4EA458D46A
+4569F30C6E77DC097356770362E6CF3F1661074778EBB44FF7D1E3B64FF75E77E11FE525BB121C65
+46CFD13300CA1F02D571B82A5825E6226D14FDCF27F06D87452A8B6C5DCA658535CEE2A795E58137
+D48E566B69D53A0C3B766E84C51EAA221C46999CC8065ADB2F129D5B630FAB1814C0C33B5AEA0EFB
+B6E994D80941B53079AF96D90A0B924F9B0E319BED9836B8F9053F868363D3CA554CBB181863301F
+8CB940872ED5FA7BD18CE39218B5AD8AC57D0F752D941076B1C64D99BE0DB86D7A6D96510D772EB2
+4C587F11779BD21CFE5BDE1F29C1EF9022B2B8BCD7F91153C845906722477829C40111D810480F3C
+F62DE8DBA7FD86CD236E656618CAF6FC46827FBC4898EA7672F8C9971AFE43E0E01EC8B77D4AF48C
+BF1210E98C1DB15C16D149BFF58AB0270CF015B107A3A50F5DC8F37FFB92EEC8CB6778DDB7CE4AAB
+C464C4AFF654223006A550EB52485A23D2B4AA7198D3CD54418102F1E9A4FBDE37B841E56F5C2C53
+966DB9B66B000E4588282E3FB80C2C519339F0002D2F83C979EDC5827A3B3C8EF8810A0F9DACB6B9
+998E9AF6551F56313DC4011904CB979AA2D32B11A811BC248141E4B9734D9FB7982A5671002D8279
+CAB93ABE057474628DEFC95D43890DB1ED34CFA8A20BDC3D874E7679A396158E522ED0AB969A4E3E
+C7E4474E192590504D54DEB7B260B7935C4E56548A7D121AC1F741F8CDF259EA1B5813175A77A1D2
+D30BA26F65EB765A04C09ED51F69F41551ADF399E6AA2FC09788137BEA4913F17B8EB838C38FB272
+1FDCB55FD65697FF0B850E7D3D1CE266BF90F7EC06A9A0876BDFE767D3A918B092FC78C775F945CF
+1F96E859C03DBF630D9A940939654C3549D8F7921CB94EE23D5A0535DE9DF31EA0F937F860B4F220
+A99ADDFC343D7CF7BFA0B803C12C26403F0DCFFC8EA786D0D8A8D9C367419CA8AE41190CE93A8086
+583A1E6C9D70B612C84D87D2EEAA71EC2DC12F4CDE6A821303D5F6A9BBDB7EEDCD289E80FA3B75F4
+7F481B50719DCF4A142069393593B9AF9CCEEAEC56A35B8787193D7C88113E9E1E221D151E093B01
+9EF89F6118BEC4735103CC8003CC5AD1B6727B3226CD44C497DA7052DD681695DBEC3397F9598C91
+77701C73BF0594CE93F23D50EC5BEE2FB9DA1FC966DF148B27B28EE3C89526DD6625E2887F9FA076
+7C127C609EE315626BC14D274FBEA56528DC06A27B2D476D46E9E7916590B156A5DF04A6CB15E362
+45D77021767B6E5BDFCC679670263FD891446C3371B11BB6E1DF60F960AAB4149D7753E6A5C33810
+C42C8BFF4E935003388506F8278BD7CB672F132E065AE684DCA0B9064D01DD620E7FFDFE04F14277
+EFE8E60159BA0FCA3FE2F28B902D4AC275D19F0AC6971EBE827C4A232D87650D2688345BCA78F879
+077114F0463C5F058107B669566F8171E4E284D278405580F04BFFC9902784216E0C9A17AA9B2935
+E66E18A783F723BE044389B7E9D62AA36818FF2EA406C3C1A9D2F3436F3EE7DB8BE86AFA8DAA6A4B
+1B84611350D8D27605509612B515E16AA843164D5D0805E36A2B9EF74C5F6A0B9D59A04B55697123
+27F4B1B30E9587CD103337639967CBDC655AA46E80D2CFD24BEB50815B5338E522B3A7AFE8362AB4
+F05D8BC52BBA9C5089ADA8C89529B0275AF422EB540D31A938B8740860756325B966B36817115213
+FAAF92DE63F6BAE1E0064BFBC5588098B61EB83C71F1C2082436D37DAF1ACBE186FEDC4BE7C1233B
+6F18BEC5F99002D21CB7864E4811F7AB3C03003E1E4490AD1AC793BD28FCD5EF0E6CC30EF39A08C5
+2F71939B0CEF620DC69E31E39D6DB969049031B0C92EF2DB653D97F370141456A52985076B268652
+FA2648C792780BAD637C4D7581FB2D62011D57E293719487CF2D1F013CFAA532E1C2D39178D51272
+A6AF041440BCA174B5CC902BD7390C7D3695056CB4BD7791F9FB6D88E7A70DEF2C97869F5DBC5BD8
+23C517C7B7C39D624DF627DC9653EA5347BFDA80B723F05F6DBB4C9EA501D862ACE05B9DBDF21B70
+56FBCD8C6D4B85873DCEE6166C8B5ADC0316CA12D9639F361B15A42F00E1D62EDBCA1111972FA0F4
+5758BECB31DB38316F3CDFE1B41748C93ED58B67E9B57ABBED5924A6D53E99FBC9A994A6489A8BDF
+13EB685548B4DC6D62DA7426C22227D4D43B6FFC7B5EA91C896730253E8941AFEE588359C2BECF6F
+FC415B9EB6D31CCB0F6C7F85853E6449FA6D627A97A3CE8303F148393ADCCCDFA2FE085C6908BE5C
+3C05AF00A6F02840206C3253A559AC5C049BDDFD11AD9B118403B84DA10AE3C470CB9A9A2D1D7B73
+2F59F5FE146DEDA60AE750F551AAC934621B4470E1BC324C436303E25F81D0DC3188BE0D6FEC5414
+C20E4CB18952E12CB6423DF7124627ACDE145500D77A97A8BFD9CB50D1FAA008E2CE2B2505A4749F
+1EBBB092C347023714055A9B63353AF9E7FEE05BB54C9843698101F79888A91531773830C2C967B5
+88D3ACD2192883D5CE3962D51084FC653EAE2C5FB2DA41DACEFB5C76812D2EDB5B109677289CD199
+8D457FB1023A19AC67295BBC1A9A20A426B06A368DF3C5DD083CB1180D287F5500F2C635EDE157EE
+FCEEC5503447382D15C748C1E35F68753992E5C90F900DE54D18F8E1B355D1076ADFB1F3590135FA
+D1A36F028E44F48ABB149B80CA9A54614D467F8D71CB310BBC7AC7100261092DB8C5BFD39E0AC6BC
+2C9D6CBC3A8C05FF8A74CB21608EC4A4CFE4CBAA2D056DBA14206106044DECF59F957EF8A9CADE4C
+9B19D8D30DD4FDE6A9548E50DB51ACA73330142153FC36B69C1C8D5B26D0C689B7040E81AC2C864F
+D7C097C99BE5953843E172C97AB5684F35FB03A725A89DBF371F08DDF40A1531FC1B676DB0E1543A
+EC6E97D3D2E4AA3D5831D8B3C952ABBFA112352814FB6FAB61A0D680E6640F6AEC8426200CF61286
+F7422CB2F78C61EBAA36D47EC16D7FAF8B4AF31D090CDFA255D9D7C61D46CFB22A7D6E1758E71ED5
+67E00CBD8E8F468DDFB477F091A2F915627F22FF47B876544BC1F03B6BBB98385F009C20BB1AA2A7
+A78674692B8EAC2E3C8069B79E679338DA57F72976810F845BEB6B9ADD32B95D78E5E60F16DD1668
+9C05FD82D36A3115BE8ED494A74DD211D58A2CDF983FCB9CDC29BF7F0E29988FA23560EDF514BC1D
+183F3B2A22C09FB179B47E05ADEF48DF02F31C29875D1915037B19407764A4292FE44E741651A8E3
+BEB5F0D972B6327090F664417C84F84FFBF0AFFF8B1D85C822D90730AB4140C42A51AA8B1DBE4398
+4EA8566040EB8B341CCE23FD3F69DD235A080BA5C69AECB9BC732BC2D7D40617DDA6B79FB6EE40C3
+556C7DF9B23DAD89E94054B1345DB8402AE679FC4655A4A776C0150463F8DB2BFC0608EA1F124E22
+1DDAE6026B5E5D007A7E4A0D6B3B0CF3A2669E67C5E4F01551966A7BC48F2F4B6A87E740D8095E63
+F77C7A027F26B52F2299DE5B8A2F6209BCF3D31CB0235F998F781E5CC81E31DC424E008D46EC0920
+2951E5684804A0592EA47D6C788A20487BEA2EC8F2E6C1D7F378B62DB43CA43C4B366F8B4319631C
+FE9854F0E10321CFA3B01C873584863BBEFC23C72C05E695B56E8A52E89AA2DAB543834D34DCAC5F
+ED08DC51825C5257AE59850D101D84F4CAA1D29FC932F9E0EFFBF7A9A7F3685F61F0490CD3CC8988
+2DB52A757A6AF4C4E67B407BD2316B1C0FFE7DC54E43C87B874F57E4903334E2140B011484863CDC
+ACA331175F2CF3D72E0042855983AAF8853D3015E870FF0807014C31D55060DF3FE1FCE157324481
+2744AB51322444632F9AFDA6706E320FFE82B8CBE242A19DF00CE73EE48E25FF49D5871BD3E60652
+298FE3E8D400609E232E0DDC794C0579ACEF89E841B2EDCA50D51151F65E8C1CC3B01EF1870558F0
+BF5743718C3E068617E81BFE120C6CA16E0924BFC2541177D53671CAA3AB641C41557DCDAE1A3461
+47B5E999C4541B08B4AFCBC187AFD653D5B5F8386DF6AD8FE69E21BD0567DF494F736C6A184FA4DE
+48DC9F347787CA96E2E00A296C2DA05C2AD9BC423E9CA428D7F1FA12DC9353A302FB8C529AF8688C
+BB543B45B2717EBF8F6C497935F4F3BFFD285E0402AB7544B3CA4643AE5A8B5250ED987A95FC1F27
+5B9707ACD0641BD0EE2AE9758494F8D8A51DCE408A38AC20EAF0852D72D84D0C6BE973326793AEB9
+55EAC6FE0A2813A355DCD22F6F2CE56588D1C055CDDFA98878BCEB6A018DB22922D2B600A20F8184
+2E665DF41013CA0947C4237C2BD60A75E2FD1A3FB8C8FA19485730B87461AD466ACB02DF8CA24091
+4FB090B3D2B41EB6B8FF05E1A59D9FD668AF70BA5BB72778953BA55FC5F9F626043450E1D09BC83D
+8605098ABEF884639A37809A32565CBEFB3FF39EE53D6C18C58C272BB928E4410E361E59A50F242D
+69747A032617C52DEBBF62364AB5A96EFAF642D9D82BA679B1D70FAC10A4EB62FA5CFC308E86368A
+AAD7E75948F43598CD1C544A0D4091374D7E88D4522CBE902391641327E888E7748FA889DCE67ADE
+61699E7D77763681CAEE9B1CA8837B2F7EF9C18CBCC538C465C8E2DD34616953CCB6030A222C728B
+834911C1A179E2C770289407AB28B303E724D97F747D6134B425216A64C6E0B60F633E2B85300047
+E4C90339CE030A0FAE31E830C8ABA5AB3386A3B69267351A7BFDD66356AE5E57FB2994452993E90D
+E7C4E260ABAB93C37831856A650D56E44172FECA01D6C7C380F250B82473960D2A2A5FB6B4DA668F
+46E624ACF7FA0FD4490F485D640A3ADFC9F8652E7A38CE5799F770C3606DB4B8B947F93967F779E3
+A3C0572F13A5A187D31D7BD12A5C7BE23CB6ED6192086241B76C5BA6983DB9C93E4B208D707D3760
+F03CD6272EF3A4CE89B8E52E6AC5871A3D03EB975759AB4BE239E5EC7842CBB333E692CC607C722E
+185D3C39164DD320C6945629C70FF66A5237C0A9520A1FAD6EB9816069351AB0F135D90CC0982B14
+7D2294AE4A38A527EE40BE9CDE2512AAEBB590E134388BB171D0956A7C4566D65A9A041BE6C4F883
+6B3EC3D2ED1B48B566A783292B15B6127920D247D494F070BB20BEFF60640B11B276DDEEE49706E8
+B2B21BB40B7F00AAFC594C492C25DCA774E0B80D82E927448DE2E74A9D0DC7AC9260096EAF187B6C
+D6AEAA6D1DC4205B4411122751A5B22688404EA7C5861730371FFAC10F5AFD4727A0E402AB5EA757
+606B75EB86A05E8F774D6E430A1A3FE2A37EBB06700474239FB1CFA05EE44B91B82244C575B52E7F
+AF934B04EEB0D933FEB57EBE326D75821C8B23EAA85B583AED4320B7F04B9F2DC591091216FDE52E
+064BAAA9C2C9D9714B95A4558C21F3CEBE624B5403B31508F178581AF6863083ED762F1E2E34A45C
+FDD71660D626FF8648F5D6C5E580D4765A67FB6159EC8077A9F0A88038C8D3D7C77FF0926E2123BE
+874F7BCAF129D55A5B5960F824BD1728ABCFCC51D23936DE9A25C408D786E44C3A2BAFA4423177AD
+060D21D38E15E23EB6FFC0B4120E814695D423EEFC2744A1FC81B4DF89D76F0A6803D8B14E75538C
+AAD03A72517B86514F6952F6FD619D9E910D980F00964DB325318C045BDF79647F453D4A5CF4E61D
+D5359782827229310405FBCF6107C3AD9DDEF9A9A339D5D5A6EB2E7838A0A43221BD62CBDF732DB0
+A638A52016FB35BA7761AEC846A023D3BF2D1BB183543E81EB7CAC1E5970CDC6F068C5EA118C7AAE
+528D1396E6DC939112DA4460C890EAD5C01BDC438F5BB734218BA6270ADD0DC1778FD8AB16831D6A
+302B814A1A44B07EDC65956C9E6CF4875DF521F3CE5B422F71081B6D69BD270F739095C9E81C0377
+934A8BC6390C420C4E4CDD9CF7E32544C68D884E15ACA3BCC07FC8C132D8FB9D752C15D75C52C288
+57E2EA461A6FCAD90C56843513F74461F18D7164BC597A28AE4BA7C86EE1703535A9B9ED50122627
+71FC12F102E800E0E1AF7BB46681BD2B14B614CEA91B7B2AAA35235DE76C0E113C92688F8EC81277
+D58C3406778E1EC1CC15F1CD9A137C8FFDAAB99ACE3BFC782916F1A877170589A92DC921E6740A22
+B84DC6BACDABCC76E64C79E3A588D80F8F4D376E1B426F15751CF7391102102F0AFAFD8B22DFDEB5
+48AEB5F30B1673023D22054A13391A0EC08DE6E7B685A0D031AABF20B7C62187C0284892D5EAADF1
+21BA28263EB863D5E36EA9C06A77CCFC0E17F593961591F84D82AF823EFE41044C8D606FEF83CCC7
+B0E961E7994DF8A3CC36B209D953E250ADAB8D22D7F2B4E2C9CA39EFA2D93E56195C1560E30A5190
+CC5B17FAEFCF250DF79F6B624A4B917E11C332222FCCFEC4F6A47BD9E75DA9854FC3F7AE554E91ED
+DE144D7AEF38A0E3EDB5E5A5626374DB94F022C8CF549093041DE00D7269B7CE544E748439BA2870
+718C08E58FB4A77D93EBC04B7957D272AE1601D41BF85A2BADAA0DF73B0D3841D4839C85677FB2E1
+5F1D6CE592669FF4BBC9C69DBA334DC37706F2F6BE83D5863E8CD6A30C08640AAC4C233684E66B4F
+E6B62D4A8BE9D531E47BEF5640D9B5C27D990092BE1597F6995C8A77BE9C18AAE6C1CF130775DDAC
+41D34438FC7AD8E042CB56CBF2944932EBA7D053E9376FF398367450E35A1945FE23E05C921096A1
+5454721FFD0F429A3E06DC3ED36F1C170BE79C66996EF8337AFF85B90C5D3A4A94455AE9FA32E211
+7A63E59001F052D5F6223125BFAFA40901E98960ADF7BB886729DCA82FC3B8CC52B37FF2517299E1
+D769057F8154FB95582F02CB0BECC873A9C71796ADBD3E91324FAA94F2C41CF57C30B5897D031C02
+D256C909E080E70BFD1F32E69EF67031138C2DDCD1A8E4B65E485C23C3E450ABDD9815512D6F34A8
+4B9DB715DB2C7A93BFB424316E1AA44397749CB01088428F149A3B4324737ED9957FD388248462AC
+1B2610D72BF5C073ECA567E7385CC959E37CAC7E05470160FFA5A9F63B8E9B082937E911586EA165
+374938F492EDF28CE6020953A5B5CCEC7737F9D9CC8538C4339567AAED3794ABA3B9F4EAE65466E8
+E326F6C399B36355935FBDCB9972F10B13494DC25097FCEC5A6398F275C8C151558E74C5175F7BAF
+4155E36B733F75CF9D5C5979B0764F14D8306E06BA24BF791141E404C69F3F8FCCD91B9C58C2C671
+AAE7D4F9E5D6414E46ED633A5F78AA5BF04E652246A066EAD9E582B181CC196EA2D3CFAA383B5D0E
+4CAC9336E119C08CC6AC55CBFBAE147C623B400453BBF447E96DE036FC025624384359EED7C7D5F7
+858DC0521377CF647A157FC3F188DE5EEF094DBA125510FDE34C570D7BE76AB5DF0A28BF45DDAADB
+EA7EEEDB936332DFE93081E0AFD3FDD46BED08D6914B2EFCFDC41662A33B90B03D76D34F48D30FC6
+BBBB600E90E6AC7243FDF026762A44B4D6E4ECBEF48C9D7B696AF29EEE063E557D8FCF0F09E0136F
+45D17E608DA36E59F2AECF8493F8D62536119B5F7E1554DFE3F6E8D7C9A2C6F557D18B4AF92C9F6E
+050975C3B5C54F9B5F4E39D600B6FA2CD6DE203A174028CBB2A201AF126D1013C229BB82CFD013ED
+199D01E51EE2780FE896E01C63C655087A3E61A7F1029FA5E97EA1872F1B45F22282DDC317E17926
+7368CB52DA9444F6055A3C653659CAD2A1D8712BC2B1B32C1DC6906D957FB88524EE066156ED6BDE
+B8D832F9338F9912E29A250A8C4674E667C1C278B677AEC9972BE83CBA3FB779893FCB8F81A323AC
+91474BA2A2334A07BB5628E905C518E634F6761A3289056F83D5DD7B3890987EEE1C18FB2D379CC1
+905F1AEB3B3D2AD578F0D6C845D2D40C4BCEE3F71C90E68E5417BB8CDDD878D83BA80AD8485F4067
+E5C3CABF28AB56CBB219C0AAB8FFC6C7E192BEC8CBCA1459AE4450AFCC81B9548F40CE2622E5A7C2
+81F74DCC02DAD57EFD92D072318DDF05BF42F1EA8163071E23949B0179CF7DE64677CA99B23CB926
+B3E294194EC13397EA1DC9A5E1CDCD828156CD71F81B64167D4FB01E6002713BD8AC6F82B20CD369
+9C6CA4704DC5C65A2D66EB155B7AF1C9BB46469416FB49C1C7E17A30A5F045271D7DF3FFF2F42C6B
+470701C381E3456A500C6BB3D0E47B4D91C5F34B49BB6272F1F8698B307D89EDA3A1565DAD1C0864
+627560CF922DCF5B34C67860352390B282F95394AA2CDE0E97CE3ED39546A6AF1C52BFCF81A29BE8
+2C47C99E8050E4889E4575B75F39E662F2DB7420673797E2ED3D67CDA7AE2C15D0A0A794D57D168E
+BE13214E89E0209AB2C0EB7784E9491AEFA3C02D0DF3AE5365A0FC4AE023CAB528162C7A1B173664
+9DFADDACA8DA5FA18B7D6489E4229E9E24D38A620464A744A5C60F6F9D334B908706B738AED18669
+8A8B278341FA4D65A0A88680BA484694921512F7DE93337FC1C02BBE6E64AF2DAD07603279D87329
+1D1F4D39C1DD6D89C90F65240F4808F6F1115CA55B88E242565E59F3BBF1F10EC7B88872E9AE61D4
+4CAE185463EDFAF7DF63DE4D2207D307AFB61501892965170D2945846FCF5973A1D458607F50C15E
+06E5BEC715E0C156259AAA6C735593E5564F65F443B78CC7512EC35A56F126DF9D30974A40872E42
+65E1AE5FD483CFCBBBA26DEE426CDC4721F19C3FDA86ED7AD4FA1120F63669BEFE7002B128CEAFD8
+C63E8AC09943B6CBDFB3D2476A026C00A8FF81B1F651B97F310C82ABA5F388CC1DB5AFCFF5996D52
+52A6A42FA4D972E41EE56088F78CB966F9051171C472C774879AECFFF08BFD9CEA40D7C298922ACE
+64F28C14E0B81F4DCADE81D71DE3983D87D905192EF13CEE71B2D3FF1A88AEC671EC318917DF98A3
+C9054E372D22A3CEC82FCC217F47319A40900312F6E32B536B9E7A7FA0837EC65CCDB5FB0D414371
+17596CB39D9382262DE6E65379D3A9709B2CFBABF5FC5D5B352425F06F88CD31012A2A4147B112F0
+C1C0ACCC808CD625E0228EEF66661F70AF96D3DCFECD402700E4F6522AC9A856DA466D55C84F65BE
+2810A1565163872D62EB81333A698ED7B68352CACCA2D7AD38AB55C19E4F5582F75818302F5FDADF
+1DCED09D94872F2D48FB636C8E38C7563C72C771A08C6B1F041F3532BDB39006C89A33C09BE1E3E6
+03622D891F98010BF1DE5355F557A1E09448D486ADEF565705277B31B8BF2B86761E32631E3435B6
+88B79D566F1747BA456DDB43CD239FB47FF7B425EAA4C657C8EEC26EE01AED07CF916E77D53634C1
+37AEEA009C6B515B6342C54BE2C7B95955B1A9DA277A0ABCDA2346E88018C726F481F71D6011AA42
+F8852F2E5749518FE3B3AB668213FE1A05C10A1C53953D75312631D6BBBA01D418199DFEFF8CF548
+6109B099FE8E2F606165FE30F532C03567785D5362AA873C9D3EECEB20F1945D55F49B0CCAC84967
+59FCC7292E46938943C262D78F3212D3F9D0F7B103157F423D71B1ED54B2A603F4C269029918F238
+EC6828FFCEC66009DB9C9E59534EABB183F31D7AD4C57B1BDF0BD2CE5A421882BC10CC1BCE6A970E
+2B586BB221567CCA483989DD0B8DEC424C1D1FF042DCB7834423CF244EDA28D2D969B17440CAEAF0
+24A6119DB010CE366821AFA424D1B8299609C04148275AE6E5257A7ACB3C766C747CE99CBA2D703C
+F19B7CF301B634D8B613DDC4AFE4633A4D77BFF8E00CFB5E289EBBCAC90A24307E7941EC1685CBAE
+400CADD876FCEF7F6557EEE167D2035A05120293527700DC510B038A496BE1D5CBAEF24ED39F7421
+1A93AADF22214ED606A80582485AFE358E3A46D0671148998A3B3BE209467009B43400870359D418
+9A8CEB4D5866AB52D16D9CEB1EAB71C07E6CAA34B70E3096BF7604C22C40D5FBFEEA616DA3BABD59
+DCDB97D883FC8742B8267A16A99B7953225F7144568D566E64542C92E538AC140C851E5D295528EB
+7CBB49909B1CAF6409C9BCCEB325468FA0B5F7CB2987382616B477CCFE4F4AC79E4A6F7165363543
+F04DE5B6F6E1C2E910CDC3CDD6C4C92737198F892337DCB6647BD226C820AC99C65D8E7772BBB74F
+E65DCAA8A22C33BC168BF48E40A82700A3A7668C5A9A71E397ACDFEE7D556C5C19467B7AA69C260B
+727407AC837BDB7D67DEC055C1F45D8BAC61048C45BC9FB3CEFE7549EAA2992D2EDC126FF7A05EAE
+58613332A2BC1465B2BC0429162B907D65F793D236EDDD8D35405866D71B25F62DC4A7E06D4DEE82
+840ACCAABC0774F8A63E9C0F7FC980B3583E7A8B01C46590E3BC04EBA565C2EA94F057D964A78A90
+EA9F52ABFD70F84E44E434BD10A42E98C794065724341F907E35D3CB257161E01C7084E3A0166D15
+CED65DA7BA87DBB2EA33D39BD99AFB93D3548358D08330E807F8552CECF63C84F805205491BA3A1A
+622E70C232FADF3BF2DCFD6F0539158D3306506F150B0518371912A25EB96163D73E9EEED42EDC84
+D688BC7F7708D9DCA348FAB4DF62E5809BD094842D0A31DBB7C4B41F94D946810C5EC10B69AABC2C
+91A59500B2E5D37F4755DDFB7AE4ABF757F4C5BCF77C7F95E6A616646456FE8F18407080BCABBFA5
+7704287AD26222DF91AB2613951E2D679472F8ADF06EA2A20205EC19972299A78BAC52114334470C
+5F5890C2F846B4C6042D73945127F2E3910ECA1C4CD7A16EFE4B4BE38A15AAA710682C3836A8CA83
+FD384970139D8B46FB0AEBB002DD224199672FFA02250FBCFA4E649E335428FC71F50F45E498419E
+DB0E970F46894A48F65580881C9C4250FCEF65C9B28699408E18B26FE6DB7F1CBDB767564E73CB59
+54C6D639CE33220C894F36E70F71C9F9AA3FE2AE0AA0E3F2E304EC5ABC661675CDE2E70519E4220A
+E26FBACBD01D5169EB844750753E6CED53E3678FDCD08AB93E10067E9C64F38B40B76D99B6CD92BD
+F4155A1EA5CC824998B59AAD06E09E5F15EBB2288D66EA71B296616734FEF2796F07FF0D8B047074
+A1111D68B99C2B70FC56E74A51B062F4998ACC85B1943C9477E436E5CD7AB18DBC898D21BB93475A
+623BDDA71D7B895BA2D4C10F4B90BF335126F4FD57D73AFA50170F6B3C364922E551D40E35DA75FA
+891762FA23401D39260F2E92C7807C746F13BB35CEF9DBF2E76E66A72FEFF095DA482A4DE8A42091
+7065736CF4DE904FB52E649A32255E2030A7B31B686353492F31C064A3C4B0448C4BFD44B8E15384
+FD809B8761EE26A7DFA1758D57CE4F0BC376EB2B3833534B15A83436BA553955ACB5A7A66796AC5B
+92DB5388BC53EFA27508B08E82821E5CF669BCE52BB860780F749B4F38ACDF5FF12726BF3EC2743F
+01014CDE96FE6B4C40A034E9EAFCA2A35CCC776C2669E6AD138070A40F48ED79136D7FF57E993E09
+B81C543FBADD350FF5B5F7A46F060F88E30FE2D8233832D18B6C323EE017EBC1DF5C838321CDC8A8
+4CABCAB20B60A1A3AA028F36EA6E87C850AF8AF7CD50AA6359038BFA8818821D02CEE8F51DAB8C05
+F7AE9797814D97F3DB8CCDDE45B21DBB15CEE292FAA534A5F317B357F4091F3DA357325B8B9F5EDB
+45865415973C143E5E5BAA483FBF2D06CDD4246675EC58B84C6AE65CA743117FF00F229243772561
+31A7F2BA26A9115AFD96C18216CFDF41B7220ED0CB3FCC26C36380007B382A02AEAE428887DC8BE5
+FDD630AC57EE3DC156C7B8B29E687F24442E35CE10BA4087295A641F7139C831F7CCDA6CCEB5DAFE
+537CC1A97C5A337D3C48A6AE947F58A30DC08CC7B58DBBB4737AD52783C573FC1E9408F55495A80E
+7FDA61F0B9C4F090158F1A416249EBBA936C27BEFDEF19D1BFB839EB70576A010706D8B95657B218
+9C2AE04C11EF9E57FE09880273761FB4302C388BD608FA0C7F00F033C9C00F4E3D5CE2D903E0DA52
+E69C7745EE9FA75E2AD93DC6CB5CCFCD3782A699B807AFC36AD1F62B05856D5DFD6F88831B90EB3D
+CD523582A49732E3FD7253126D39E8AFB8458B5F7AD7F94A8DAC13365F433C857AF4A42C0A08C4DB
+9887C4957259ED22D13CFDF5995DA957EA5A0F620B0214FBFE08AB6D552DBF048D62CEF6EFF12F15
+3511ECA7833E0E3E95F85E6AC0F95438AC4C126E1F1ECF336ED31CCA7EB216D279877123FD9FCD8F
+B5E52B587CFFC4428456DDCA816819A8A4A211D8F1629E5D42BA4C5C356E580C8A22C61D987552FA
+A97893816DA73D423686E4EBD44375C257F031318865A20F22115E72BF1EB9F93AAA169C140A33A0
+6C35BD4526A38BE79CF40AD1EFA10411E8F3300A8A8B97AB140EE6734E1BEE6C8EE443D698D34159
+97649C6F10F20ACD80236422E215E146D744A262DA3FC88DC0D86FF66512F49D3F957D3C5CFFEB42
+4823509F33F155057A4C6F37B52F4667767BA94F6B8B62856B553F307E5D230C44CBFDC9A97A45B1
+39FFB2F2565EB0E22026972FAD0FB7B9576FB6F368B61979943A398773600E7EE1DFEFBF26D45D40
+BDA66EBB96A56EE9CAE0B2420C5DD83E24DBA9FF885BB844BF3D2BF93B07325DFF60C0CB5FDCCA0A
+C8FB5A2E119D5AF26E53AB8E3B428481C2871DDA26EF0B621CD8572B3C664BC7AAC01A1D05B98F79
+1A7080D294BE81099BDA7982432F3DFF4775C44D23F4F1B2E0162B61A8B2CB5EE8564BF98E2ED403
+2219085FE6194C19DAC98A421826CAED7F1AB1477AB327506010217283894235D7DBFC1153D5ECC4
+8AA7293F19592B4D7E95FE55151889BCD1D7FA7DC2370D2DFE11D7E4EA34B5C7A8E73BD3A348FD38
+9EF45B6167FB90BA44C23E912F9A4F2FC0427ED070592F7110183BFDB2C400393BA7569058227926
+351F07FED4F33633BA03A72AA2DC6B598E49B96021DD868DAD0F352E5722FB714F667C15C68D49C0
+3D822D82677EDFE86FE9668E537DA284068C9B0AED83074C92A5B939296D505B837E6A9DDAB1AEAB
+7455A08A114C2222B339284674B74BF4CA9EE0C020BF2A148B439C71C6BE51A94CB64FBE4A7EB295
+5A455047CF5CB348B062ED4F6471CBC3E9ADD9BE9B96879AC7BC71BCE02FD02F17C6063985A5E898
+3D205AA1489DA13C408990ABA1C54F2F501AA172F530480D789C848118C0A74EF98D5F607A067BAF
+F6030D887AC6A6497F9A0B38F9705F328AAD4BFBB634F739386177B07F22D5771282444E5EE17335
+B4D0EC86117C697E79A5F4F65FDC08E4904DAEDAB20067EAE2448FD4301849E456D085F392DD1316
+7ADF75CCFDB723E2904A9C0C976D6B84DDEF9D92B0E15FB246C3ECC2D0BF314CFB957757B3A3E8E5
+801F520644E4601D291DA0F7507C06F3B9BB36FC1C70EAA444E14E56C0CFF06C7F853DF36DA9D8B6
+AF2544B853DFFF535A7E5C6FC145250CDDA229956019659D0D253A19A7B51A4E538BDC01F74D7704
+9949C2C97C7EC6392C2E61CCC0992B66DAF1AB08551063E53180D2A67DE496716CCBAA45462D9F91
+B66A22545962DDAB120511FF08627131B95E5DEEB8B4DD9643E7B2AF65C0FDCE11F5F1E8DD468DA1
+8D41C8C4F00EA73836F4F70EC50FC3EC6D358C0658A4261C6D15A582A2C7C994E7882E661855B352
+014576858A265FFBC425160669CE159D07EDAC04D060B44E5800A7AAE8E339C29B929AA81D2F515C
+46229D2080D5917AB20AB6B34FDCA8E4AF64ED660A3173786FB1A1D005D575C2A5187D3F7CFDC94C
+CC44A38C5CD523E9DA726D8EFA6DA7B6131DFF3435FEE838B2C7D6B97934295F06202D307FF78D90
+6699CB9C5BBB10D1D4DEA5FDA5BFB094E704607083B646D37F5DA1FC7AD21B813F44D8C1AFEAB666
+55AAA19703BEA2E77DF3BF350E17C74B3447A452235919452B5175570A006C7680AC05E8950A62E1
+1D7E3ACA35A397D1E19630D094A86807593C97F4C484E4E06BCFF708B6DCA972E3A0009E1CAC0EA4
+141530F5C1B8AEF5E1B933F37FDDBC4BE22B74FE346D1A3F5FEC0818F8E61765568A2AC04713E828
+F98C449D9A1CCE52D10D61DD8BFD084C8D099A75D89DEA64D5A7CC68BD5B0593D97953DADA976383
+F5015915618AEC56D71D1DCD55B89736395C609B315A3F1E1255432FDBD37F38CC43C354FB4B7C44
+F1A7318B0B7E99C3C08C33B953727B6A6328051783A0A33E3CD9E498346A3CA6A77B517096EDD52A
+E443B87643A646C3A7BB97F742888D33F9B3127E61942F4103C1DBDCD8EAC8F9E259773066736CA6
+53CE57E8822651261D847C131321BB9D6626A1AC50D047C0BA47B411DF2A995545BD68EC0287CC9B
+31D5DDCA8755EBEB10ACCB3903AB0FD5788E984220443B8459E7C078DA4289F1350905881AD6DFDE
+C47302B0ACB0D4AF8CAED02B4B70DF3CF8FEC118F0FC2D3DDE3E494CD160E676E300BC464BD4400D
+B50EE43B314E0517037BF971ACD7CD327CB2134893B8A0410E68DDC518F5DEC966C7884CF5FDFE74
+723177F20DEDC039D879056CAAB4BF045062D3904F615C5CFE109AC7A35599C94024B41019B9AFD4
+04A80ACAA4837929F5C9317680A13D157A03B59A5588DF79D2E113F5F51021D6F6F90E8BBBA2C252
+FD10651BE80BAFD59C53A3367BA3C28DB6EB9DABF1EA99F47B503F627E15DCF3FD645FC52C5D5D0F
+2F07DB4C25C0D1E1C00146E1C4D973E613CCDBD3F9450CC0F5343D79F05E9492E86A1BB889ADF405
+03BD7F3E7543436859184A5B20BD8A172F350D846B7570803990ADAA48D4B9155A2B4C4BFBEF1E1A
+065C08E03928559735BDD442FF1E83E1FA20A5DA57D8BDB2FF5427C034CF0128AF111E6E73099E04
+6E0C240E80A73D7BE72B87834E45898D475521CA3306707631F5C6136199F354632D1A085F12A1C7
+C473868B62E534D15F5484323E63D0574196A19EF175214EB35A90873EFCFB92D6CF68761D45E37E
+AA61E1A1979A82009507CA193E44B36A806486665CEDBCF387053ACEAB979BD35D30978FC7659ABB
+E844F4ECAB3303318ECE80777A5FA5A9DD91B3D06804C4B4E9B4EFCF07EB89866D0DD8CA390CFD15
+98651417114D78776B1A1D36B4BA17746D6BE7FC123D473EF1EFED1C3BC1D555F914536869FD5B0C
+35F9C83F65B0E6BF7A627B9202D787D72C600DDB6BCCE613D88492E13CA0AAAB196E8A49928C62CE
+A4FFE2D0208EDA334ACF47F20BD793124D2C5546C03F4A364369A76A0425262F9D9118AF54E37D32
+E33AB25DD533A49DF5FBF1BAF4CEAC2D9D378CDCD13B00FDA432D9042F623DA41AFB80699B5538A2
+5403B0B3EABEC9E8EFCF42FEF3EA9F91766902CD206B0787C187D5370B60AD6DCD002DE2DE8DCDC0
+B4719A797C5E26BAA67665016DA0D967FA1346F9588AEDA174CA001B31213617FE19EA218EC23597
+79D979E2663166489C06993230B0D07973A117C4E3F4A4C93CF8428248DD5389414D679C69644142
+67C7FEA17E35B0CEE456667A9B1875C81B2302BDDEA2818D6019FC1622A82051F60584ABC904CD91
+8676305DC03FFBCC64FDDAC8D8AA9CE2EA00D6C97BC63C8A617DEDFC0E40775649438E9F61AFD179
+5E3B20560B01BE5E0983F136CF48AB206954E41DEE0D9DDD953DFD01CAEB569151D6BC0DFEF29D70
+FAE3E198E7EDD8922C0E0BCB8BCCF1C016142C1A8B337AFA7A05A9D7534B184BF3BF827F371E9BD1
+9A71244ECA1BA73D484CD2FAD54DB2F0EEFBD54B536EBCB5094E6BC2F5B2AAE41F05B4B311115876
+ED42C34F8E643B53372E3F6350DB8A38445822EA9A33E27FB0CC42CEDCD1FE2FDF723FC47C996EE3
+56C402112F24D0AF899B2D00BEA1CFD427998BD22B2A09046D6737814448ACFB10D387547D7009FB
+384AF0562C85694C071584236D0F1F3D3FCD0CFB38B77C81889061E668BA7AB37AA60F58A3967DE2
+6F939B79CBF10A9DCC42852561D8D6754F1B660D216AAB1E133FBAA321C56E2584BE5C9BAE20CCF0
+0E8DBE6D9C2FCEBEBAD945C3C04101D2387351F132628786F6D9D4CAB83419288D31F9BC600D9664
+12E6AA457CE6CAD26A4C0671097B98C2384C81DD8B9A3222D4F4BBDA7017895C3EDC26662779AEE7
+40D9D7E24185FB821970B0A3A94041A69E4805EC88EE1EE521981536F2844FB8F5EF645F67D42CE5
+148E2DDE43AD5AEF200EDB3A2C7866C98458A92666E5F9E070178BCC39F65A893102A10564AF4E8C
+AAA5075D2F8CD7FAB0401C03AF299EA3515CC93066744EB5AF7CF0ED06675BF049A6E3C211A89E16
+DE5BF0445A7CCA6EE8EB0347454950485D884606651E5887FE8B24323E2AA16DE22FC1FC8C4F06A8
+2A1FDE5758976024068197E1F4506E4D3D8A16D40461A4586338B374A592DC60334402F76388AD6A
+457DC3F54E6169CF7AE3959676E966A45609621055EC3AF80E182633300A4418E34A66DDFA6B569E
+5A13C9115B5FD3EC1CEBE50FBA247F60803AA83976F00117536342DC3D9890C49B2AC701D370E43A
+955118967827760F7091469C5406F08F18D7E3548148CF0E312B1DC71DF67A5E7A1656CF2F47F3AF
+F3DD50FFC2FCDAB7177285B29C17CA43019F62AC6FBA52D1493ED7C427526470ACC8389BAE827759
+4958908F517B2863B83292EB5AB3F57FFFB08393CA610FB1FE905D88A0A16AC395E2A2A6DD033D6A
+0D68992F830B2E1B95FE357BF672716E88FFB92FFC3D62945D1EAD22BC68C51EE0E10A43011DB94C
+44685A5C4576F6EF44CBFB45F2A4BF110A01657DB51FD499767E78058199B31DFD60813F1A344F86
+289F9378231D5B151C92385E3650B4FEB1DC91018EAB8474CBF69FDC1496A4D078D2C351C8196451
+247A9DCF8117E5B637371D8E22E248C64D999015C3FD2311E9950B8EE0922FBDD3D7BFF766BFE9E7
+CE0BE12F318FF2A7B5A9C6D00A54401609304ED2C55F5C1EAC3D4B38355BBD85D66D61636FA6E30C
+2E82829376BEC979A6FEEE040E452359768ECF90CC539A546F17AE906C76F14F86FF697797322B05
+1EB311A759FE260C1EEE5DACF383816AAF1294CFFA7BF87A4D9BC595EE8F2C2F86FEEE11AD959D86
+F22FDAF4CEC098942A57E57813A0FA99239E994FFF353C1E781D666B8928CFC648FCF0869FC68468
+BDBDA7D280DFAB8B0B3A4CA35B074B686DE8D372C61FB32305169A1A9912F6541DA16CD6316A6EA4
+51524757BE5CF6E820011BE3859FB8B8578C100FF029680E05F0E0BF11D33FE19460C85EA5E4C0EF
+28E29407C8AE6BE01CFA0D5022BF9FB01416FFF722A784DFC8FCE330EC95737A854471D334FDC58F
+AB42867A7B62836A8B56466E9A6C1247D46EBAFFB905CD4321970F59FB8D6FF65FDDD34BF913AD32
+2E68455C5FF2D23C1A5EAE687F259BC982B6A384D35440F7C693CF50B9ECAC0B5578CAEE87588B56
+2EB6B7F42034C9F2E545EC866316552354EB3728C7D26527ED75174EAF635E048B08DC5D23E88981
+070AD5641A652F2344956E9CF4C16E652A99F4A644D1787D6D36537489DA4D74E61B2FC4DFDF1D1D
+9D58F9C26C5EB63200526AFD168AC57D5611ADE4D4A382FC28BB60F9E7D626A6C67AFBCCD1183C5E
+3CF2EF210D0BF5CFA7BB10FA3887BDD4CD96EEEAA8F9219AA2F10ABC0A960C3B57C0EC0313AE10CC
+FF1F522124CFC8D2D49BFBB0C193EAFFC5B48FB3FF30B21CB76F0A4C0F1377C9223145BB0468A5D7
+1B9BC25873EA12E1C60334571C67385C00D0B570D3FFC6C7FF0DE62C183C76AEEB12DFFEE1459E0F
+C818C621B8D12FA1357E2B55D48935D70BF140B4CFFE8813DEFD479350B20DC2EB1D3CBB1A2D3DC6
+EE975D58C89D61FC50E6A0197DA9A586B72255023DE47DABEFB11E8AA02414C2FF6258A281219B9D
+DDFE41BA7D7977D0D6F18224FE22F7D4E9355FDB35BF7ED3418F4F68D093AC48F7D8FE4194FEB6C8
+0B9DC1F74E023C604DEA27089F98C3973FF9F4AD7BF7BAE601DB89B08D5D8139B95EDCF6C885FFA8
+B3E4B0477E7040225733826BACFD1EC4A0DD72DC41734856AB9FB700DF83CA2CE812913BD142D84C
+5C83C0B2583768198AF9E885F2BA74877A414233207234AA5F18840557CA11682AABDE8993533887
+7C6D404BDE4153C9827EB16D66C1D73A8143C8A2D3604FF72CE579FAA3C5224BAC48EA83BA848429
+9472007DE96466B5B29ACC7C03B05DCAA38A48BFF9F214DE43146AE4E04FA705421917F99BC54533
+F0EBC01849E396216B9F0794E6F6C6B61B52EF1B1950C0FB609895C3C55FF574163FC8B6B09E66AB
+AED1810E698FF37CC1F926B2CDA3B48C7D77790EBD2D514B6F385D397F713EC3AD3954EA9C846158
+6031D369E8B99E53408A79D64C34EB5A56DE8A67DE91837960E98A66FC04DFA0EBDE21DB003234BB
+78665B039D0A469A0221BD541AF7149A2A659C300132C14581EF766FFFBECBA8B58A5EB3F95446DE
+F49AF863A8113D17B2E7E6ECDEAFC3834D4DF900E3475596E86FBB4E2974C090DB4AD61A737D611D
+92B4535AC291C56AD8B1C031D2F9B505BB77517B737D70AB3723DB52AE2ACCD5DD2F617423ED3CC3
+9CA882EF41757BF7151806A9B8B0F312808863E3673FB54DE939B35CDECA7FBC4DC3BDF5A5F47D35
+E345916C39366C8B4F439CE1C6F1835C320BD1E67375B03B5DE18C93256F251761A4C8CEC01019C0
+68E34447BCC503B9571FE8000627A6B3DAD5854CBC0A2D69E5A8F46BC78F6A7B1422334EC7A98ABE
+FE9B83E01DCF3C6C9273B346F3240EA225AE4A4083CC7B0EA141A0773FDE940768358EB4B13D82AA
+304A1386D450C1C0C6A7D5A8FD2BD313F78F85248B5196241E31E5595F3BC01F37700A2DD3D4A0EE
+2DD01A36569CD507130E8F5B1E96CB560BB7DA15560CCADF3B2C9804A11D9E8055C9EC70E48C1D21
+3EB756A1376F2EDCB7189D78CD3D6CA5865537EEC31C17D801605EFD860B0B629472690588D02575
+02C6F7A75B9A1C1B397781329832CF3EC43C09F1559CD562C48FA9500295CD3B0A790DD3FCD4684A
+7C7AC49AC9BFFF36B39A9FB148BC28D37907433943CBBF0CBDAB46D3EA86DC8F81C859C52D15302B
+94A9B51C199B7104DEEC9D769C2634CECF8B700CE9C04152CC59C9326BDACBEC4312DEED92DD087A
+1C4840868D9F97CAC046581F762F75E8D24D6445370A3F1E0AE74A6478D9DAC37E7FA5BEBEC0A1E0
+81AF89C1BBF7F51E3E2E22C8C405E8671BA85F1BF0DF79A465DAC7EC07F731E00632E017D190A99D
+83E27E5C2E63D7DABBA23B2E88334C63721AC5A4CBC5D45F4C177259F34C2EADE01FA008AF65EBC6
+01D8DD16436D86AA94C99F3CC0A2F87134E73BF22F108B825A8963B49C6C685474AFE4A542C8641D
+C0375D7EFE9AC1168D9700459BE52D0DA399023E141969F25C0DAC4668534B6647EC85454BE945E8
+26B26DE6E3C4584B97A38E2B40A0D23481BCA78084FE80E00A71A790BF31DF468A435ECC88E60A57
+860BBCA3D65930186E9917CBD209C230E8F8255A7ABC7D3F043AE4D7AD63D9980BEDF062B7D5C298
+C40225B6D03F29A0339E0FCA02138E526F06B9EF47F5E7A8068A846CFDE2BFDEBD24F5A73A66C079
+18662AEC80B43246284FA4E2EE0D9AAB172B1E59A6CC46B801149D8C0DF6DEC9A55D8E1B0EFD9D30
+2FF618075944CCCB6831D336B11617107B0530D09885E5CA11A5F1FCC8D69D603DA16BEA51116D42
+CAB1AA1E4D7B9B4D79993F2BFE53EAC904FEB70B2D330A89780EAC10D12CC0C35B8399F218AC2976
+E57A26BAD20CE2FA2AE2363D3FD2A8A971747556F2959DA74A8963C20B504711AE1CB0D0C02457FF
+2E9BF696B159AF031DD5155F21C0F5549B0471A3C5DC8918B675CEBCB23E29322B959ABC05283A70
+2E878DE8EF25EA760F3C5C7B7B49D398283DE2ED837FD59F7C22D62C58FE4448B1049FDEBFC8787E
+67D7DAFE9774979BB3802254DA59BCC0219F98C219F84D995CA768B8B5D9D4A32525DFECE003675E
+E4BD5D8DFFC11025AF2B468F9207B5B2B42349B98232BAC0759758C1F4A283405815BD7145C93FA0
+8F3ED2826655053A3C2559073D8ACD199DEA2C5BA5F616A2E48548B4370EC73493BA07E197165DCA
+774438B0766867819C1154D1959FE6E01E6312E0AB91FC2E2BD240FC8652A2D456A1DE7F34EF372A
+53794D4C4E050BF3CA5B7BD2F1B8DE93B4C8002485CB219AD2D029739FD3C81CC6E78EDF38723576
+1A57143EEDE5CC887F282FECD261F6A25D0A7E154ECDF5DC38E426811BE86AAA458577E5E0C5F0F7
+5AAFA9C41E5D1DC9D91ECD79B514F8CDF7A5F1A189470D35FDF4F9B8788879CCBD91B427822ED658
+389E981E0EE5F7FB87692A3E3E931DF8A1D1573E3B0166204240B7080089A09EF7487C9AEE2D665F
+5A82F94C877FB5B0DC531CEBF1E71C6592CEA2401E4B5122E5091DF03D203DF979B9A6EFBA12E2F6
+B422FDF15D49AC0914D372D21E871DE65CBECD105FD4A3E4714B9CCA5C6803FA39DBB015EA8A88BE
+7913502E562E5B170B87BFC8572DC9DF49AD63694311EF1334444BDF0B4CA3245271C1F7A4D7FAF1
+703E3AA0E1EA8D5C6E821B28707EE0C9B4F22F23796FE87356C58AE2CADC191F4C58E1FB58DA03B4
+5A25AC95DBAE13A293474217BDB214742B9D9D6AF35F70FED2891942EACE3E625E55FFB820543FBB
+250A062D3D395BC0F219ECFE0D76686AC148BC41476A887BC494DDBD396BE200FD3E03CFA12EC9AF
+6B934A283C42AA05589AA6B4A8D16946BB51F50419CABECEAEC5AEF9085C9989289E9B46BAFB6FB2
+782D84DE2B068F91A9744AAB237CEB1BA513E57E4C307108E993C972A3E0A898D5A8D27833155031
+FDB98863C3BE7FEF3004CBAA5CB60A1F2E3EB4D7290FF5FAFA088B1CECCB6CF51A58DAAD998F0839
+6CDFD68F5ABC9C1CCB8F6514107773C69C26873E889D1F79D10E866910E4684186FCD71C965ADF62
+39BA3418B313A27AD632300969B6F284519366ED85E7CD968D64823F8C59B5911A72D0A20EB72B60
+3A61E36F52F256FFCDF706B4560B4DFA5D918FBC530D83A4B3C01BDD3CB4572E24242D141BF9E775
+36693A0407D002E09CDA5B195BF1CCF430AE9824C07928A050D0B460F2704BE8F9E647A4884C4567
+0A81EACF7CC038643EB0FF18A376FF6F32B6FE4F197273327FBBDEC6443A299CAD4B26F7778A99F6
+5A11BDE047153E764039EDB251936AA43DEE50DDFDF8856519056AAFC4C5AE6F2051AF0579A9ACD4
+1D00775D7DBE70022CC263DCA5E0A25B9C7C4F5C418587666B2FE24816B1E0EC92F9074F1403BB83
+AFC3F1D52CA79C387BDEF864366E34C90BE52F7AA09935373A07E4E026224E76F9EC3CB9E7EDE50D
+EFDA48248D61F3CEC880A3B8843306375D9711E58645F3625BDB8E87052DA67F9794EF4AF8DB0BCF
+E00677C3A26907DC651BC838C40EC39E2B5A5DC0DBD345944A6C32226089D63C52490FA10B215AE7
+03CFB663EB8A47793B84CE7364DA1C4E7FCE32DFEF09490121222774915BA59C78C2275F829D15CF
+4D8686B095C38C731B83D48738C25F40B8ADD487C350A2EBE846C3916AE384CB1050F9F5DFE09FCB
+D9129C6270FD86D55A459618FDFA4F907E6B4746196BB717865AB378414029017551161A52E9D24B
+E4F7EED553A927933D4ABC8F25DF607779A717909CB4D810DE8F5762581900E224E4B91598149BA4
+71CF8068ABE8744356B261600BFCC57FB8BE45036CF6571D9B2A95304933BD4F17215F8EF53F8E08
+1AF61FA7F9583C34EB5655CB0ECB82246959F09091F36989EBDD646BEDCA614B9A61AB7696B3FF18
+1058A150FA6EC1BE2EBC7F64357A3FF2A2B0491D2F4E0B970DE5B7788B467CA678039B5EF55C88A3
+84578D427FD2CB16C87B0BF0A3D37CE8ED43E0F049AF2436344D5F47C948C632C94A287509282561
+6C64C5D262FE5B24916FFEE982A69A6CCF888BD01D62EA591EEC51F4B7DDFAFFBEEA93FE08D736C2
+0129E345D06B10246A5F57151C198D407730713F32299638EFBDC01367E23EB59AAD42A83AB41B43
+2DB462652E29813740F4680A5D4BD47B18328FAE6BDF4200CFA4CE3773809B45E8887C9B2E423698
+9F6C48D64F5986F563D9A7538A8716082F81936AEBD0461E6F4BD470436D8B7656F0FDF89108E6DD
+02ABDEF907731D458D690BC608EA9CED09EB1E6E64C0790C7A2378201CE997FFE0317679EE1D4EE9
+F91157449323E53B4ADA8096CD628B5861BF794543A98F2FA2AB54FF0F25A13DAD43DAF9394329B9
+5AA53CA32749FECB0B2BC035DD1EBD53FF9FB5AD8BCE06CD89E5568091C1CC314CFB1D9821D7F9AC
+7C55F55E0A16E39A87D43148201B928F3C42B110FC056189DEF183745F3B637441DE8BD4C3C7EF12
+F4258E306B2877ADAEC63441010750DB4E6269A4C78A0AC01BB3603C386651FE814031CB5D8C1F14
+9EEAFF652A53E57BBD4C8C0CE36A84A319A53BC1E5FD3F1ED1EE72F4C1A9BF264B594062FCAFB22C
+C1FDE3F2E3D3C17DD3F7FE0E15EBD812D550227C06D01127385374A11438ABD50048E17255FCD2BB
+85122A6FB9B7DA9D5E9DE8A747FAE0DA45A1FCEFE92B9E70A5B2CAC668D4D07527A5C1403267D823
+048BE671F725CFC7474B44FC5AAA348420B2D7C23C6CA066666FD6F2208E329878D90CEF1C2E77ED
+22D3BEBB9D547810B189F08920A27E7107F208591A84D463CE2576C70C3DFE6643E4EA93F4E1DAEB
+41D46F0E2F56FC10C69AD5034FC9859D31CF27A3A1EE256C93111F81C11ACF1FC0CE20B90BAC9AA3
+27A5C85A7985B951519FD4B03C40BE637162AF41B2FDA68F0D1E9B7602FE2659D3D75955C579AC51
+DF6A552EB9581AC3F712F083F19B52A6C4F560F36C59CEEB0C996AAF1728A2AA45DCAD79BD7B23AB
+388D5B0B64A2B95154B6259B730B0F4A72C8C7F7CC93C7D64D9D8810D1F63FF8ABD4DB89824E2D26
+4FDEE916C41E299211DB1A53256E1DB5CDD04862F034D9404B73183A99D3D13D642A663F129B6D16
+7095BEB4EAEFD03DF2FF2F0B6B594C1EE90FDB203DA89FACEE23F1BA3901FECC75FE1811BD701259
+343011262B6A0A9707AAA6316BC3C17F787BB80AC8DA5AAC942D90F80C5A3BB59E47EC767244AA95
+C63E50BF809998957936D3BF6ABC24B0A397258F9EB4DC8F65692CB023D9091FB180C69498CD0C08
+BBEBADC84A7E0016E8F8BEA325D924EB0DF82E75D2CC2CCBF039B11934363D4332C5FBC5EC556BE8
+5EE4E707CC2753CCC43D2ED50558E51A104221C9323CDCB0199B7B83454DE3FDC810D0F362C0299F
+5DD981B31D8E3DDA284FEF9DC8F9C8DE138D3065437A7FE8C30572AD06D62E8527AD37AE39AAB0B2
+25F76A25F6C6505241ED73BA494CF923E919F688DDEBF193E188F8C4C154F21631080763B4D091E8
+AD1D2FD6649E0CD9360E8D1A67A5B5FAFC67547CA31C95A5EA8D4EB5D68B9F6D6532DB9B54584735
+9558542A2AE58C09F3BD2918EFBE1699E9C8F2C2A11EA4D224C726D2ACD4A8D8ABAEDC6588CF2AE5
+66528B94F55B823A2A1F7BE19000F3E7579D094E047075DF18C8C868760295533B26EB3ED90635B1
+29C17ACA679C3E88B06998CE5A7A2544B700229F5A6A504BD3E45B276471959C8A3F81917A534287
+39B5EF9E3D463B3BA7318448E2A3E79520D2D245A2A72F31FF7070B6E4624E3A5E216BD103640C8D
+F387E49D732529C611F8B971073F17EBD2F6EB18F9B74A67E1997926DF178D4C9EDED435B9682F1A
+279C81BB9F60DAFE125845A2FF3B02979E5481C78A45C479BEFB9FEF3CE2BA9BC46C77B50B03E48D
+A6D17B76F06F3AD118371ADC69E178C52B5FB4B261C9311874ED07DD6D5B3226A005FDD7A6D53848
+09E7063F036CDEA41619122635E835D2D74CBB6AA9B38CAA4D819C26E95115FE0DBAB4198FC5838F
+2C91B7A87B07D734C6D4F4F83444C1E90AA9BFC908A2BAC4B3DEF9157AFCA5248F2DA31CA87BD363
+AC25E9E77F741D4B2C6E02F04987A6F49D30E9038CEFC41BA172DD675AED8B392164411144E5B738
+F3210B0E66B17A13CB9631C33D44484E792A7C082DD0A5382F34C5637653261B1EB6D2035B08B4D9
+1FA9AB770CAF40A103629511F7B43F2743D7E583433DECFB19C21FD4FD0AFCC22A4119E77C87BFE6
+FE50068B22479015BE5A9F06BEAB4D37412E062A45E0CBCD7BB39FEE747E96306F79FC4F2E8942DF
+5D9DA0E55AACCDA547DA19D30B8404FA121298B44C9CCE198C708C69A8D6BF17591C5C50D3FC5BE6
+961F7ABA8F366DAE957A1C3730DA4A5B4F035A9274675EE3BBF0CA8CE9D8349F50CABB1C3EA4948A
+BE6F9F143592F1EA95404E6909A909168E3279A957AE1924245C356331A75E7008BEE92BEAA304BA
+40B7C3F48F74D9018B3247DF50EBD7CE541DA48ECCB1B0BE51A455C3C13C279D4D8676078C3EBE43
+08748D52C9B041D3E7244C745B1F2F742D010A9E60695F3EC4FDC1050AC082B905D6A57E8F407A3B
+472F731011A5798965B7B1A307E252FE02C8F79CEEDDEB6E165F1A94D7FFF18DDBDF79477F14E9E9
+3981ABD200FE7771B29D1D2D120EE79D28B9543818527039AC74085EAFF241B56D08220C958B5D9C
+87C0C04A14D52AFD475B542D391BC54FF33DEF8D9484AFF6873BEED32DDA4B371112B523B6CE22B4
+0D1B416B64C9370F1CDF2C548F4CCBE9E12E21C36CC3EA52DA232DCFB65F66B22B5E2EC04852510D
+5E264EE939BB67AEC4764B87062AEB7F680B40BCEE04AD45C7519EB3B6199C9E0E332661463647F2
+FB7EDF303EFEF84891CEBCF0FAC5F723A9D0476C3F8C092604C87FC69C7A90F4D64AE45A478EE8BA
+2DF50FB93F55A3546123F0B0E2C1C40C98EAAE9F0F26B8F80FFE6E6B94B7E27D2884D58B8A119662
+2DF6BE608C5569D7864BB756DF2EDD184B90812B44ED4A32D001C31383A40AEEE9743651F7950846
+15C48E402DBC01C818D477EAC0347795CB2792E9C11E8FD4A02E194EED1C919D4598FEC003B6D9A8
+A0BC7D456047A1C0579453FC1D7CB2D158D466939A23D7A7B8ABED7E2777EC7487973E73F2266D9C
+250CE30729E3C5223AD93B9AE8443B35711E446A3DC660123ED45CE1942A1A2AD0610467E081CE2C
+8B92A6C82F0B17B5D2429E99F1A6268072C6B5AAAA6EB6283A872C54D3694CD825EB2926E57DBBC7
+C1663075E687A144E4D61C225781D80FCAE1497B442342B4A3F1CD6BDB50E31791CC3928C30835FE
+F845B6BE5E2D7E3F2F5F085AA3FAEB45CAD0D76BCBB1ED859A9CEBB9F7457036F0BC3F195CB1A98C
+9C8648F6583CDBB23894BC719D68C2DBD8003B10D08C8CAA40BCE784D7BFB4EEC9EA5359AC056E57
+B8B0F2EBCB1F4CE40C87FC7861180133E0CB6CE2FC4FE690756D327A2B5AE063E3021C0C0BD420D0
+56F0B941E6B36088A55BA11D0C35FD0132D5F48E5D9673572347171B4328D4807B972831C0D74CFF
+A5638C145B89C989E6EC942148207D6DB82257585958034D9F9D4221C7C9F7013790DBD130F277E0
+BC88BB179DD09E27062379ED06F25EEA8B7FB33C35861A0034776E3813D2E9E5C10E227CC569AB36
+CB2D9DF2E7B7B44758F9DC4FFAD7A24AC7E9F47AA850C221048C3CB35A37CE8EA75632AE65FE3212
+175146FECD6334AE3D3C5F492F067F795E1E8FF386BA198CB74F0BB4DC0000DA383BC4CC3F070DE1
+7721431988D69C8B1A5AFDCCC83C22E16A87E01C6D3E79DC7AFA3DB0371B0866EFB8B6F88900472A
+FEF1C4A878243C52D4E02E82658979731C841C489A6B97E271C4C93800EC7D91F93EB9B9C659A554
+E1FCE42A5EC65AC39190EF4B66DEAF6FC0569A000A9E1495F42F706FBEA4D32EB7EF11A648910259
+6A65CF899C2F322F5679C6D123469192A9BF1A7F1F2C81C554ADB97BD19ADB746A4F81A4D5559E60
+AB94C483DBABF6CE2F28CDB412D50FF3FCFA3B3DAAACC6A83CFED910CCB3B8D2C19590AFF4D75303
+4A6CE7F4156896A13808E0DFEAC547E69D3C886691728E4A35ACD575B40D721E8FCC5385A2EB28D7
+08101DC50811529528F5CB0C009BA7E3C88468E37768FB0D83895AB54DB2DD5426562AF9D8AF304B
+F6EDA54E9C92643DF926F5C3578269750120302A37CB140A18BA56BA01108D4ACACE8FEAE640A6C6
+958EF156B588ADB0EA5F3B0F37BBA12B7BCB221C811415387B024B7076FA4403A3AD6EBB5D9C26EF
+EBDB7ADE7C60B444AB9F90EA493B658B7767AE2BE649BDBB3FE85F460F1ED137C61BD95F7CD3D8B0
+15CE45138538930AB62AA0E54B4CE1A5EC5FEC0A2B28B345B67089A4E4AE14D2E1F5A9C8848DA688
+CA298F93860649EC3AAFEF3E820D86988C8E3E5A4D4BB937791827994AA3E81D0BB3EE115EC36D5F
+B9A392D09E79AF514D11C7B3A03C9F9C13355CE79E119A19177FFDCA34704D38118A8976D1EE5AA0
+2D14FEB1414419F5E85244ADC5C0A765A522EEF36170064BB19FEE3B5F7B441E4DB967DAE0BAC2C4
+8FC6A836E0EF5A69F073BEE1699F55E9C757EBD6FD8B514E2B49D6333815B7DBD1E0694695FCA3D2
+1320A0C4B852D9706DADD8369A95FDD917328BE93DD33818954DBD2C212D2CA81560ED5BC284EB04
+7A5F389E24E43F4FA8C97FECF46589FA7341076555CF55B1C21B28E0C1CBB00AB8B6F67472F27BC0
+D11148F407824B0159B5188D4BB7386FBDBF1C0FAF34721B7BCB5C0FCB7C4010DCB6A1284E9D7883
+9E3C2111A05D29AB7997073B590A81C6168020F1D48951BC7D8476D5BA593F4F23CAC1F9BB0E091E
+84B4E99E5C584D1370DD12DEE8DF16AF8BC6B7B23E2FEABDB7F32779AF8E2B5094A6E9B7A7225F24
+C43A8E5D2B977E1E19E633C26771E23017ED233DBB02C64F8CF03992C6484528D0C8464B46F24F9E
+8380F385D5D01B8893C67FC103498983CF939432AA380CA576D09030CD52FD99BDC3BE16C7204CDC
+3365BF76294A83A1FC14A236F5FE5321904E779B13232A76F8FE521F425562678436359C2461BEA5
+AB27209541F557AE2AA60009C9CA0A9FC7898C14306CE35A50017BADEFDECBBF94EE2905220706DC
+806409EF87DB1D73EAB0698AD2DB72CDCDB293E7FB13C94D9FC87E74502E6927A212F0D7D2F2D194
+64F7A66AC07872E18CB1DDE8F11835DCBC5C4EF039333FFFC0FC1456DAADE7DAE3EC2EE0D3415B0C
+ABB69FC5006F4D14A4EE1A5CA99AD4D5E629C0DD1E0F097B5B93DE2DD001A8C418234C9C45E8C13D
+1AE04E9466DAB8CF1ECB88A4E059C111A6468D2DABB90DA79C7C79E94DB28F6968B1A632F8C57D9E
+565FF91C6916026FFAC0661856B9FB8DE9C81661816221B1FC159CFEF1751E7E403F5F2CE32529DD
+540792FC17A12A3DCD7C50D38EEAADBD10ADBF5D8A82442AA900CE6150EB7A4639DD9FB6E385B2FD
+093493DCCD9014B23EB172E21AA89643A6CAD1093343D85D81261972DE0ACB16A4C6B5F0BE4C978B
+FA12D3CAF0134F9EA49F6E9687C8F99A456745EA252F0BA9968C7F9586E3DD841AA92DC7705BDD68
+2DAE41518A09DF0E209F321D7FA3417202F4BA76A984DA3ADDBC58136885362F02F0A24EBC439B3D
+BBDACFFD8498EBD29F88F016B1FEABC10785438EAC860B554525F3266097A675299AA0967BD3B7A0
+EEEE3FC578D1BE99D3533BD91571AED904BFC9DA1A1451FDC5406E1CD614E0C7FBC733563CD6CE6C
+C31E9237CA153F1F0411114361D731636BCF98555ABF12848AD109371A42B63675A4130B81E97C2A
+2EE2BB5D8FAE2640156001AF0F55D9D5DF8FF23C8AEFE14F120000F14149A36E5C94CD9081DEC277
+C2C34870D05011F99D48B0875A5FF542F067F7E9880109F586BCF2B50522A1F23ECE44349E539E70
+F84E207DC9BEC7CDF856A046F1A03226AA41F541719AD1AF88FF211E57DD0C1275DD0B7B47440DA0
+89B98C6EE92A7D94700B83CEBE19EAEDD8A615F6587587BA8BBA3CE3AA5E8EAFB1FB0F486BE3609B
+169EFB178A4292F4C0378AFE5D24EED1CAAB514DDC66C696D8E37F294A6579131DDF5488E9436609
+ACD750C3DB0A940C84FE022B22ADC2676F62E91E8F891225F891FBA537679B24547BBBF35F04915D
+20B11739F620D18B5B216921D222F15044368569AA302980B9225BB839F494588481B94B0C724352
+B2DF600A22B062561D86CB8F81514FBDAA4F8A043A0265F992FAB71FC9124A45B8475E1EF3DF6B6D
+E35CF329777D45F08325E8505EC0D979F542807AE77E57E453525F23BC59A50740371EFA98678AEE
+6C425374AEB745B99DDB5D8D908FDB551FBC0DB15832107BBECC4E11A1A8DEC69358A574A2ED46CC
+31D564549EFF23102D92BFDCBB2BB985F78F36033E34F59C0EBAFA3BDD71338736464CEFDBA91398
+33995EDA4207BFD4A9867D32E867FBEB7DE60D132803EF9347CB17BD91315484EF6570892297DD8B
+7D966103339535E28A00CB1EECA4A9775F60A9F5FC9BD8B06D78FE8E6318C31DA2E847E3F9CA587C
+B01AE2BA0A2EBDE308314413F4F230A758184ED60D4F71F6CEC22A93A01B6C54E0449A3860FCA895
+4A347B7588329A80974ECBECDA1070FBC055666375229F13DD995E99265DF870BC8B8CC6347FADBC
+1A6AF64599271A475B9123493D46BEC41289BEEB67EB97A8DED7A9C9730D37C65164CFBDC22E5CA5
+89D2E7954C7136EF4E084C43A6C7F361A3E96989239BDDB9A593CC2A80BA16DE9EE90E95CD39393C
+212AB22EECB677FD36D34DEB46C4AD0D21BF7E6D7CBD0C8083842FCD87B18FEA7CECF939987E99BA
+34C214E44DD84C176C9CC5A4CEA76D380CB316BB4EF9DE73D73B4AFD4ADB54451591DEF86621D138
+D5A0A29441502BF6C2ADE671CEC3CB5CAB903A657EB2D70C943F976C110E46C5D9D29BC00A875F27
+38E5D22496A43E096E009C5D3CB724B4CABB32838DBE527F83B18CB457E57B092C302EE557FD4F00
+DB9C56E66C9FDF4EC9FFAAB85F60D02BA79694FABA476A199A0331C30A78A92E10417BA236E23364
+8174C826331DC1BAB87C5F95027846130C6A2B4027930EBF9A97BA1B039D386FC51C302648E25980
+212F6A582CDE2778C677A01FBFB3C5D1B8A374ADAF6ADBF7DC94075F25ED66D440B3922C5F255FB2
+3FD8F6E21EA65B1D93BB225684B50F11310E242B087575973345B229BA62C1E2C35BDAEC04D10148
+F5B2F3BCF7399BDFDF1F3F79119714AEA697245BC647316EA157484ECB951BE367234FD02E8B1F09
+1AAC3D29BF282DFF4011BC0CBA8E55234D943DB3017CC7A766720BBC29B2D097A956C0F1067177F0
+12D42ADCB473CDE8D1BA35B4030757FA1D8211989DF3BD22CE5D501C21EF8708FB3449DF47D88650
+9FF7B59B76C0DBAE443F336FEE2D615D7EED1C284F14335BC8A26BF4621E10DE9611FB2F1DBD52E4
+B7565D8C65B54EA36D508BCF0C578A49A2665227CDE1F9768EFE847F9D94F1BBB7DB83701C232198
+5C7283D47B2E40B27A268428AAEFE75F6B2F8764A8494E5827573758CB9CA46FA93208836BCCC8B5
+564A69F5AD882052AF1C1417C3FA7F580569528682C77080F3688B65E7FC24D2A3AEB61574B4A321
+5927281544DDD7A6EE0A3E9388F8F631CE7251724DF70726E5912DDCCC8C652DD6C9608F8462303D
+867F589DE0F2F71711B35142EE6EF93B64D6326C4DD7DC83278E057100EE772082E6BA368ED91A55
+53ECFE2293A481E42F83BC8F9148C70EACE91F7B7D9CB8A72415BDB3AF66F68EA733A17ABE9DB005
+3BF148629132969589F38D30EABFA96A01FAC72650B5A6FF3935670198A1EA33810A9B11E330EB8B
+451F24F93544263436F669AB5A90A53B16CCEEAC36B1445574EFA7E802DE73522BE725E68704822C
+B7D3912717333367895BBFBE06966A5CC653AAB5E9B3596702086BF0010085B900711932A95ACF15
+CA4DC45A754EA334E9EB84D6FC8E3FC4F897456BED64BB93B593549FF0D5352275D8E417172A6664
+C5E0ECED1019494A7ED49AB0B965BEC1A82E5873766BB38D7D856049CCE2FCA65AAF61E961B60634
+E2A69EF059754C9D8163D87F928C222772D070D83FEC6FA5AC734AF65E40BFDE521F7D9CB1650FDF
+64754BFF21EA3FF0AF7611A93D525EC9B28C51AFECB04E7FC8323DD6C9B0D8539A34FC3CD8CEB795
+8E8EBBFED4313C77ED469C199552A9FF70BA5423B03B6148D4EAAE17B71C5B39DC436AC53D6BA8A7
+AD81AA8B02335A8B2B11E9F4FA913159A725B8AB60F52F1A2EA50EAF4D56656E615BF382CC68A690
+BF83DFF24FE986570ADC0290ED1A37C1C2AD469CE789E0EA0BB5CE01020100E729721AF3B5BADD33
+A2DAA6C33EB8F9064F5292F715F820B4BBFDD56F76D42E7A1A068C1CBDCE4640082F6E7D582D1939
+990CE6EE8D270015A2C461798B37DCB5798EE9F7512168B76D26C28BE4A49A1BF96C89D235F21A1D
+B6A96E5DA474D0B19B808D13D7A11BF39EA8647499C410ED9894A1ADF33D41B6FC2E614D8087F4C8
+4E437B136F3CB32DB8393C49177A0675A0C9E7EECEF448A97AFDBE840FA01FC7E5F2E8FECEDC1884
+84C312E8635CD79195475DDBFDD4D38D5A0246DE2C7F21608F8D2C0DA1371D302E941572E5792A3C
+F4E51A33228B93A814D03FD4FC223C314CF3714BB3A34BD4F7ED6348577FEED9DEB082C4049E57B5
+D3CDB7F26629E9F3BA36893E09E3C7463D02A22D7056BE76B87763260E46E48BB832B7EE13F8DC05
+37EC8E81E9BDFEAD8C27EBDF1AD706933EFD11131E12814F236EBB01BE85B7F1B2D627413B324918
+D247604F56EC128909873FEC3857028BEF76A3494364C2A7002D104D486236C30B48E2B75D851C34
+EA50BA7FFEB4E19190898AE21768C157C0CAC628A2181A32796FBC1A7271D2473CD88E5395DDBDB1
+FC3AA8DF0F3D588637F19A8B833AFDEB5F655A8838EECD684E2315B72C75CEEFBCEF94344ACE8D6A
+DBE355008EC72FE7CEEAB01363A895F4E73F867639BE0A0BE67333848816B05B419221BE8F9066C3
+62C23FE85B7F392930BFE4C12B9526FF2FDEC38F23A159ED61A0718E7115C24597D849FA76369153
+54A40C965D4D72EC94DA61A03766AB39AAB684E134FD1407A5B1B19BFEBA52AA0DA5D99CBE5C82DB
+AA663711E6DEBA180E1D4A39C320516A4350D296BC19BF1BE054859A0889C7E9727A021F3176FE62
+0FB0C837E4141FECE531A950C03D319E3255703220B7185BD20FE5DBA673F8129AB211EFCF36EE39
+4C7E00EB0876624BC840FA86E58B2F584754CB6BFDFD76810E300741EBE4544E5AC17413ADEB21C6
+2F66CA4F075C32381796BA709782DE34A675B717A2C7F6D88104CB924FDE5DF775B4F0B68E0E2E5C
+2F788BBDEAF06D8E1FC2105CCBBD5827C0B03FD6CD64F0D073F3192D5F94839644E5EC6C5185BADC
+F04112A65F49A8C83174A9AE958E76A2F5AF469E8B76C833782C5FFB8BD7B1BBBB3EA0CB7C9786C3
+BE2ADE5E7AFA8C8F20892659A59BC421E28845A108E34EE17864042EF587A6D67DECDFB3F510EB40
+D2229585347A0035670FCC76C2837A4E4D68304FE113C539B35C1F0234B5079B8E32934546982978
+C5E4DF955A454EA263C3CA5D7101F31A318D82A3F9FCB5A8AFD7A65209663B0FC9DA400B26F285EF
+46D0E1EAF8ACB1F1CB805E3986D04BC585073FC64895E4DAE1CCB749BB439CB32EA91176D5C39C36
+50D10AFB9C9884D5FB90183424CEE67EF2175D01D2478D67511EC9F54F88763C152697B06D948BED
+49240096EEE3D06AB4575E8E8B2CB8263B5BCF4FA1608720F52B675309833071879DF52C3EC2871D
+20F398B5CAC8F8A4D41D0F1D47584DD90DCDAEA4A1CF160C4B3BF1AAB890B5CEB6CB3488672AA68F
+BD938281DBC1D8BCFE92FBF514DA5358443CB6E0147254E91B38CE6787B2BB0DEDD2D38F5938737A
+977B5EA42892520C58F8FBB53C994B57382379E9490F0D6970B980E1BDF8CF9F4C3C5E0A18F66E86
+EE93FFE7FE546DE50F41364BCB3721B637072571FA1779F1D672FAD260C16D7F13CBDF3E4376E7FF
+56D2A710AC5AC35FCBDBCE2C9C17E523BBE6218617B13C1FA6679B308979AE7C61DA6E68369324C6
+CBC7DDEC364E5A86707266C0B459EE7B2C03FE584E529BFFDCE98C90A2F3D9305AA74D3ED8430DBF
+3A49FE2ECFD9C4BC9FEFD22618FE9C8A973AD072AB6F713E4DF02DCDA7AC5359B2D652013E131B76
+B3ED6C75FD53BA58D862846264627F6B9E70D8800F6D9B32242B747A67BB2B45675840D34F852AA8
+062FA6B01E31ED24DAE02F6CF788A17F7B9368175195DB0072259CCE0FFB2C1035C1D26E1777CCA3
+D56A827C3242069E76D6DD69B653768614B9ACFF16567FEA61508D51454BC02F6C60F755AEF6AFAE
+3536BBFA1823F8E1A53C41124DE983E51CEC92AEF4F99785D554488A51C20885346D1F761DA79017
+940A0C557D93F1DB6B3D00FFD61D08E96FF3AFCE5FEDF545CC9F47A2B1BB26713431D6D1E47FD6BD
+6E3C668B0368241F0EBB5FA9C991DF79890E52E83A3675EE699B61BAF869DE91F67278F510061C6F
+E41DE2D883F48CD0E068E2A652B244128D82E5CD52F35F210DDAE3054691ED55A7D99088AAE8FB04
+F525C2084AC09F5EDF80A4EFAFE981F74C0DE9D194320709B3464F3FF2C0F6AAEA6D973D9C323F53
+DE3D741F698FBF01036716BBD62957CB32CD81D3A2674560FFBC5BDC5C6E4F547E589AD0B1CFE14F
+5E17FED1C4A8ABE4E67CCF8A49F32C4C6044F1431E1CC382E7758722A6D0DF9ED23E51F8AD14D11D
+7B6428E27443715EBA4E9C05D6F238378F9498AEF0E7EE4FE6856622CC8E6ED141EE5F109E343CB6
+695C4BE1E0F66601C27975983BF557C04ACFC19227A1AD7E6C44C00529FC7EDD7F886D24B7E029B9
+C395260088BBFB96972199A7B32796D27257DE83A7402291C14FECDF7998C5C96B1EDADE0280F856
+8A8F5007852EED303969180B3329917973C2D32C080C9765B6BAB0673BC7ECFDBBFBEA980C263843
+39B7F1052591D91667D4FEE413AFC23DE2D4B9DA742F4269C6C939F5FC32A38040730A018155AD73
+3F231E4D5B9D01C03A58EAE7B5F590CCFAF25EDC8552CFC8D95C60EBAE1837D7A97CA137E9D4A4BD
+2CD34AEFD68D64B3F4F62326AC429921D7FB3C235184FE0899690A0B775F1A566EC29D5830D32372
+6526F7E7F5AFDD71B77E07613DDC4FC63EDF49051AEB59E6337AC0A4B6DD872E776C9CD0CCB86130
+5322D816732124F5978A86C186BF0A0F88E733CE38E4D7C1BA5378C5629B1EFC97806059990ED42C
+5CD183BAD7E94070E4058569DA2E51831FFE0D080301AEAB4350BA290318AEC582C78D05DD92E5AF
+B4424EA808629BC972E68F4FF2489C245593F07555CA6A2B25964794CF31CBD3AE5C229AB9B8C298
+06C01D116EBD0FF0F159ED2D3D7DFC73EAB4910BFF5B0B0B587CD9EA6E6FC45D63C09766224D8346
+1F0588140B258B1729F70BAE7962189B1554483392988CF230AF4077193E53330519394DD99BA135
+6D4730AB221DC6A66019BFAE564893DDAD7B177DADD16ADD21D396CFA6C3DC818052E2F71149FD59
+4A16DE0C2FFDD366C99B486C55A6E991E4D22CCB15843F0C3363676AF2F5B2D1B7EF66CCF2F12DC5
+0D63776BFFB058D70A9C76DCE96C754872D72C82A0C33F90D49C935402CDD26B6D743B1F43BED5D8
+B539424849C1495DAE73044E885A7D0F307F1816DF6244A6F2D97BFD4E200E93F69B08AF39EA21E6
+E347A47CEEBF803F73B978ADBFCF056789BB8E6E2563DE87DD9A8C877157B934102DCEDAC54D487A
+1BB2694F0034093C48F10A17D32E2BDD0C723CAF59ADDD1BE373AF8C9BEB4415AA5AF36310C31F24
+354A53C0B962573148BEF91D994FE3F3D8450DD4D686725799F53C373A0A3E3C060C2E1A3E800504
+9F26D716E1F381B9F83125E4683264A07E2D8938F605978E2513DD2050B3D8A1012797CBA8961632
+BED260916338A812AE751C7B657E086A0C7DDCD3BFDDFF3E48B84751925736D1310C4910FC114387
+F3ED7FE163F91895EBF55FCB425CEF5729D99BD8F2C072E36C310523E75CD8E5DE49C031C4263410
+9D56E91A46C8C8E89FD92012A00C33D0DEC52597B5C6933291A7BDC5CEDA95DCDA5600F9AE1C8250
+54E7EE1067458CCB66610704C58E4A4FC0CB5FC933D0322A716B2CD430A3AD48DAB3D4CBE9D23F2D
+092368CFC4E1F5495C133A92942EC62118D45C17723646E69407B4A89DCDFD2AB3FFC099A21D9D29
+741D68270629AA3A414FE58658DC9170C247B6E23F35C4BC5FF83009F462F2EEF4DBAC5FD158A658
+57F9B6DC1F5192DFB169DCB65621CAB2F1B07BD22F4155A8E9E2B6388D430FDE5EC1C834D22EA035
+C52E1E34482EADC36B4CAE902AAE89A7284E62B3C84B608D6BD05F75BC31310B2DD3B2C08A00E073
+7F104F03A41989D5F6B9A2C38B22F1D1803EE5D7A4D8DE44E4ABD496A1DE0C0E12C4BC96D0122846
+3F0EA9CE9509FEE987139F3DD3F9D0DF4313F555BE85433718F6D05F197C41A9D9C7A8B0D2740196
+82D49F58DD5F66B12A6520D9F226D1DF1F1B65CDFA261F980CA25A92645B86B64606293F8BFDE364
+C47D2AF2C709BBE77A70A5712F2CC26F3D66F5BE2C307A48E6F887F681D30121E32BBD87271B5DC4
+615D28C309F15AD263FB37424E56DDA6E17B998B45BE6C7FC6C28E3394A8764C9EB2DF5C06626593
+B5C665D550D4600172791CD208AE9F37BC082B0B242B0A504B751B18F4D7495172B697EE217834A8
+A4FB7CC16D6F9E8BB400BE8AEB0850960283DCE725249FCC4DE97D9886745AB6066C3E2F64DD8AB7
+9AA11667F11188D7965DC11EB760B772E282DBF13249F31986AC6898FEBFE23E3E8B8D2C33E00EA6
+FC493850ECB2E6D831D1EFCA3C2EC8EE2E394599091ED58BEDE97D7A43B6F739EB0F845EAC1DF6B1
+EBFE876009CC5D804B15ED4B56761B3CE1AF59C07B49DC798A44532297AD73D5101ED47F36A3678F
+818297CC27F6AAA2AACCC9AA9B6F5459911D8C56CF499E390AE607F3790450B2B9C9BE0F006EDA0C
+715B5CA0481734CFB0597478E7602B0D2C1E4F78F03C68C17C70E4B42D7D2D3C95CF40F73488B371
+8E2CB05A549944D86944D78724E266C3319AF89AE430E777E95F0D792B1C654306E421F3D63A26B2
+1E74B6E8B21B2E2B9DC596D013CDA16D08E65E8F24A84B12B2BADC653E6E1110DE2E709C1C1BED13
+707B70A421B384F20CA7A9A9D20324DD383F28B2D3C7A9C53F5D4C6B7C378D26DF11CF55238BE1B2
+4FA70DCC178DAD3D35670FE4919085EB1CD905971D76A368FDFCF9D2F0A23739851A3A6D2E02D65D
+54DEE69ED5D81315D3EA5E356F94EF256DD267FD1E1A9EDC9CD63E743F299BCC4A4506233B8DD765
+2CA067F741603F93250C087D368F9E9CC4CC1A6DED567487C05BAA992B0056A77F630A72008E3946
+15A9DB24FE56A956650EC9DE90A6C2259189440247970541CA198748928215C0E132A81AA13208D8
+63C1FE817F70CA573B54577D10B73100AF8EA088208A44FB92ACA314AE5879706180788C17BB1D0B
+81B6B95A1C4E0F9EA66F9B39BFE12444A6446691A7BDB03E0F03D9F07A10A7598F2166F108529F34
+CD90E601FFED3479ABCFCBDE8F051C348E48C61D95B00C59EA1287423F05666C3D36288844067E83
+E14F6B5210842C742B89F13ACD126B9FC50ABE2CA7D7ED513D43B6AC7F41EEDA416BFFFCC5C844AB
+2D23D4DC09B2D510504CE98D02E72020D9E669DDAA344C63A1B75632F912A1C0DA3885DA4AF7E243
+E4A4C6493D6595BB6D56B0359106957259E59E336BAAF35BD1CEC5CDE735272EBCCAE8D4904AEBD2
+B32610C6FEA2B69941D6542ECB44D71092A3CF067708A3D087AE99FF29671AB7DD8758759B971A08
+AE1BAD78270D2FBEE37AA2DCB119D72F6C7B0C8509018A70D0B0BE2C6830EF8E0B24B1CE1141EF87
+3A4D7DCC501F808BFD94E4DC0F2915AA023076BCC8006490A43685EA25AAFC187302EBDE7FE1965A
+04A5A398985D29F08E085127B56B057334D88EB638A4DDE64AFD204974C3939536B1B66A54B4DB81
+151853915718F70813F096CC1B0EA25E363B49264C2AD17158A4489F91453FBEDBDE15D7B74D7F98
+E81DF23251785D58295BA297F295AA6248A912CDD4F1111E6B628EECBB5139709E76EA4AB743CEC8
+26621D08E6BC64691CC90B3C3C1778931A28D3D5B1E20E96C643316613FC487C9B604C43463FA453
+3BCA1236286E6F5A6EEB2F1D9C34BDDE4595495A365F88055D9268541CF1654ACF478D384A5496A8
+772EA1402751A093582A6625A0A44816B5FDBE166835D598644296249B92CC90AA3FD6445C9A19BF
+27F59CB0616C7306070F33C7DF4E1DE64AC8C5BB2FFAC1EF2B1B30E5A0275E6004CF64BBE2C6710E
+DCFC3AA4ADD60106334708862FFA6652825BC84842736E47AE6917180365C75B27505EED3C6108E9
+898A780E20C3F606A860229AC46D0471ACA0187D6D539A1B8820F620F72B41AD1D3BF3834BF48CA2
+AFEA8BF535AF74C4562DEADCB63D2F5C7585722B77C989342D190FF926C8A5263B4F25286F99CF6F
+C62EE6E2AD61C82B29D82468AC10FD27764278E5558CE8B41BA111CB2F040914451A480C93084237
+CAC8F66BB7C6689F340B8ABF0150E06D5B1177278A4C08742FE22F42C28680F190900344ADFA486D
+59718C25D37275BCE4DF981AAC35D2C7E85C72A0188B8953CFA516FD545AEE0BF4B8BA301CFDE214
+4241FBDF3D204E3D2823301572E23F204C97305A82401660E12926EE7BA6EA1A81FF5C007933AFC7
+3266FAC4C134ED818A48E7DA01C71A46335C845F9DA5E960B25339D551582B375814148D94CFB781
+FC56093827B78578A73D4FF67B6B87F40CFA5E3F4325D9108CDB64BD06427B88C84105187316FA29
+90B4E3E8EDB6C78ABF164F4A9717D523794B2FE772A04DABBE688CCA977090979B5F47CEB90A1DBC
+167D305EAB231C9F4260C4AD10889CB785169902FC0BED78DA15B8417453BB65856EA0BEA5245BA0
+573F623D215F6C0CF801851C305B355D26B52B0B343645FE25C78A3526841EDA480919A1BBE5F56F
+C10ABEAA3E1FCCA7C43EE560F067F1AA2AFD642F769D1ACE8E2AAAF38850F0D757CD808C921D716E
+96FBC07DA7860DFA70CEAE2888C0ED3CBF9586443532B68DAED9A926655C157A416C383A53D8F283
+2A4E67468112A09ADC837ED8EC95F70852921F50D4417239FC42EE3624CA97F682745CC5E76CC7C6
+7BD99F2180F8C0B7FB49539C8CC474C25C0DDE491671FF329E51BCFA779346D4686835A3AD6633FC
+B5E0F67E0CA9CED8F215BEF4D240453EB2EDD6ADB22278AA5B985FA140C9834D38753DF2014F8C0E
+E6DAD19E8FC54C03C1F6CB0F858986691D99592562CAD95FA0A5B2ABE4A8B54B457D42E8C33A2D19
+51C0419A72FB94FDA78ECD92BD2A1416459E9DECA9469F35E4C47DB531726DEE8F203D7042EDB32F
+025DF3D582547BB1D45F7A5B70D317DF4EBB16E36B0D798E0932FD2A85B04FD67143E4B287A50416
+2C1F5A037CCD780088C5476385AF8168E12D97D44B0630621759173C8F1E3006B5B1C6D7138B7EEF
+C3CC5F54E24B2C3CA7B41AACFD25E554880AAF406EA4C3C6E21D3B550B040FB1952598A7E8E6488F
+E38288B2AEB6C4718338598A2BFE4D2B9D14C65732DA304C16FF3E1F8F03046EF095B65FD609DA87
+EC24A69278BFE65C905CD0329F6A486B8525B7EEA4F7AE56C2633CD83543269E8ACD6D71F500D82F
+DFBDE7F7F7B1AEE67328549232E26CA55085B6E84D9E2E7F74068F93A90C4654F2F396E57C5F76F7
+E61CBBE523DBFBA6E76638BBA3064DA025A79E3A294FE7F1CC28A3B4C57DD6FDC48E541A85534B25
+E1BC11B4F78019457239EAEFD4BE9007D205F1D985F389DB22400B279C10948551A6B4A17FBDA0FF
+C9428B18B43DC76EFB15FC2182216F1B60B4E344A03AD6C00F141EF99F89F24C819C3E32877A927D
+84C2D006940F39CA8B71E5951673EA9BFD1749923219DE38929ECAA9CE43B06CFA7DA1BBEDFDA56C
+61FF6C24F40E59B13870D5FDEB82D981154FAE5D6D5152DE69339359461A41A9713B6BBE47E868C9
+33CD74C75DB71D13BAE4DEC85E02FAA14EAD6C0A253B16C79514657B15E68CCFF9EE6AA385CFF9E2
+C53D9AE40F85C793E4E8FF50B2B7420F4FE69807BC5F37C3E300E6B3C3549D1D3246A2E70F091054
+1135BDF805E0A698E236B6496702D061241687B7B8D1A0E517DF0476DA09D89667A7AB375FD2672D
+CBAB8124E511502DDBD08BA04D941DF1CEBDCCF7ED48405CBCC33774A68C5212FC6F132641FF413C
+984F8B43BDFD7B1A2A3435F15AF07EF4970D3E4A0BB947C181E9CA27CC14A35BD1BD096875B45873
+8CA244F88C28728B74E25CB8C4FC1095A56CA75E4569AD3082EF194ADD11350DB3B74B96761D4538
+596FF7243B1E1B724716A144106E080D42036444FD472998460CE9ABBD05B42AF9389AC452BDBBA3
+A13A96890025789F16B9D92251FD3B3BEB2C61EDDB370A20456E3BFE5F4039E2557C451C524F8087
+015BAF3FF05F51869FB97512968BDB2B49589C1C7AF1E085250A47657465F480B7023E24C76731AC
+0EAB6704123D77977D3A2C4C56B691346EBE589C619C04515D34F81FC6A17527D5D8319013C5D4FF
+27CC3925E24C99231AC7FB9EAF0BBA482D3B75807AC85D03CD09DE5D9AE0B07B7A813F0449786500
+0AE8A7E00080300F0AB8C399057EDDBA273DD2E1B2A0DCEFAD3B332E6D4AC1FFAD846167DFD70E03
+46DAF84AF292D4F424256ED5AC4E104F80697050D50844A708EAC9E7F7784FD01646F3BD0C595CA5
+1EE6BD607D254E78ADDC5E15C3B6AC4940EC865A5C23105B6BE09EA09F2C05D6D76960A843B81EE4
+33977FAAC3CBDA85CDD2F4DB7C28293A77825635992AF8F3B38B4480D9A139B1662345A8ABE1634A
+77496C3F57597D2985E9E54717AB2E99CA35789441BCDDEDE9A9E2106B401D9684ADBEFE40D607F0
+75C179E9CC03E59E65430DB70B441D43DF03F2AA6FF06F224B6E455B01C64FB89EEC9103E48453A9
+749B4D602808C7E408A8903091D85E06AAF635D0D529C3CDD1B8479AC0F4208C284BB678A547F2BD
+77BB17C86D4560434F7AD1937760A6AA55B614CFA9FF8C9C96561AE6C8F2121C4E20237428BC51DF
+2099B6C49E3EFA18E6D439E6E6981E746EBB1DC461259D8EA0F8099C47CCA27B2D982B72C9A07CF2
+1B3C05D6E26E6E286E348B8944078E24809F9C5F3D014B4CBA02533F5621BFBA1F0EDB776C634746
+703C9F73BA89B1960A496420C68F54E5B901A6D733D7ACC79F275FFFB253F389AA480084468BB34D
+A1E797E43B7F6E8CAF5E8C93069A3A2730E57EC39B677BB73E3F07C2055599F7062E53B37A5F0099
+907D2ED87FF7A82C95FBAEB888033BDFD67BA3A6031A4CDC56CB1E4CF5B06B46E16D988BECCEFACB
+9E1C037023D7BF5CCF5D65AA66A17AB361BE7981F132A578F3ABFB97960A6034F052D9D5AFDC0679
+782EC90F240F943A5F9A3D969ED7399254FF67D89DF668F7C56FCEA1FFDCF20481474AC8495D3AF4
+B6D7EE093E369C057F0B70858220693B398ACF8E8143558132E4391405E30A73937C53402E459F4A
+A3539CF7A99A3F51C0307D045DF8B77757E92EA2F51BF0BB4F77D3904DD355665870C2B59F1ED7F8
+4FC71FDD7F0B6C5D3182DB77827CA6A2060D2B8C83C4EA4A432EF43A4D0A952CC6CBBE52A9F0CD66
+1A538973DE41FFE9C5CF55F2506B9EFEE51FBAE5E63BDCF5528499A47C031163C88D3022606784DE
+2F46A9C9235AEE3D4F71D4959B0CFDC5B7E78C8C0A8F9DC99440C2263DBACB343C5C648577F5610B
+50EAB1CF7FD02419EF3941C7CA0B0E64EBAD4B2CB05A0793DBC38F1946D44767BD287F5E9779C611
+CA0DAAA1E7393DBE0683C8D3455CDFEBC0E64B54B737E298DDA605227C0C4BBA87AA3EC7FA6EBAEC
+39E6EF2537D5974391D31739D9FC42983D81AEE44711C823F35F8E2321AC74943871739D2DBE9748
+FE68592263E7713F27E0D49B9B5CB7A4E55DE54E6B800D15856450FFD3AE5F287B12AE4F438B20AE
+9E27E6CAA00F3EAEADBE08432684FDF9931E925544A680182602A3C1997DE5D0630BD5A010535E66
+E1C123013D23966B3545C7431C39B97295BFA4099D14461004C42C85095EEACB9B47C593BC6DB863
+533A8619BAE09095DE8ECA432D4DDD49AA600D277E75DC3F5C6631E2A05382CB007825FADB77438D
+CFA78E252D79B6A196D5164C2FEB85D75ECA25FF80B1D97FE10E87960CA0FC47C41D3A213BF141B4
+8BC3AAA93FA86245064668394665BFD52D12C3BE4CE39EFD8111754398A944C3FD1AFA98EC337BAA
+AF899D35E804CF416AD7FE45FFF13FC6354007501043F98FE8428DE8013901BA6A28711A2CA85A27
+0BB135B72F1D5026E8217581860729E94F2F1878A0E96C59E9F62714FB5F8F25003DFC7347E99007
+8A9A331CB3A6A535BC61866F02513DEB982C4A13ADBFBAC3FF70A7335F40D5489E48E5EDEDEF1619
+1973D932479C62183B0E25EE8C4F76D4F1AE45DAEA4A12AEDD9EF81D248E8D19F8C8A5BECDD1EA1E
+98783EB7A38149170851B1942C96C53DE06DEF80913BFC04E539EC67C110498D15B78268853E5C72
+F485F8A27B768569E54241F6115875E2973292CF48FF91D45EBED627AE9F0766D22201B20AFDD40E
+5B17CF337F2999E0BD15B86E46EB3C18FC12B7DCADCF9DD50C6C7E3F37E615A892DB3F57E250A072
+A49F7277DD6A2C8042698233D35A699B17ECA5DBDA6D250ED4A16FCC893BF0DC2E33FB1EBD7DEDEA
+3C1C39603C8B7E1A5A833A8FCDD5570BD088749BB232615366687962C7E56ED089CD7B092505CAFA
+5A80F503C4CF337F07ADF0D106937E25670839D491F7BFF7A523DB609D126328C16113ECBCBF9C40
+04904427A108618AE5D4ED809F8CCAF72251104C94EC5BEE21F91B179D31DBA79CEEE5EC7FF698EB
+84AB1D2D1A624F58B3622A78844CE51498B2CEF38EAFE259D22C7BA61104651A862008BC1DDDA58C
+C45F663EB26428DAA85E7785363A69D2790996EF5D9621D53042F42F794962FEA46E46F37B8AD1FB
+76FC8D5CF2146843F8CC625139C75FB42DDA71A752BAC48F294E4C0C8289FC46DA5EFD9C91BDA6D0
+27518B7E81E8B21F755A9615627D5812ACA674D1527A1185EED4E3C628196E7D0759B1CAE6B9B7E9
+01E9599A65230F1EE469CD33B9BD9C104C44E3C1AB966C9678BD0AD78111A4E0F2D07A01A038CEDE
+7036D0534D684A1562A17AD64A00F279200C0371B1CBA61747671D2A21D3F9646CA290F6B82418A9
+6FA177C6278277504B7FBA936325F5FA124AB018A15DC18D2C5E8F93CDEEA52BEEDB78A57828D81A
+3E6C38B9FAF3DC4EB7273ECE3EA4482A1C6242A335862C2C3717F9C9ED95F77B140C4E1569B2192F
+C7DCF702D0BC9A50428EC406F8BD0CAF886B4D979320D3E429816D88F7C7146D960AC12E70F2CB7A
+9F4E3E366665AB3F1B4B6440F55EEA26DC9EE0096BB7763731740A537766490C8C174723BF0EB40C
+53701AAD12B21D436ADCE22203C1053A9DC4E9F17AE617888C4B4E6F3A720E4E6366BA628221A387
+D8AB15E04AD69387C310D3528BD2FAA5B22BFF3FA494F5FBFAC4F771C9C7402B95580C5AC4BB3AF6
+92A70CB2C851FA5CF1173EEC3EC29B5A05A0B728BBBB51D3B7AD8B0AF17A1563E82FAFD93F8B7118
+1FB7AFE352874F4EC6D334AB6747519AB8E847B7BCED33EB5458A828E074E74BA621BDCD03FEA604
+7F7B6ABDA01FC7514BA1AFF0D4D0C0CB8F4E42D5A87E395D9ACDD02CCC220C157153422018725846
+009A3ACD8C8CDDB66BC6836B4026FD9F526AA275D06C813179E5924F26A25094E7BDA8BD26AFC4CE
+B41D8964D4FC4AF1DFB0595BC5D6714C32F15DC7194E9A3A73013C45D8FA55CC0550A12D9AAE8E9F
+F199FA28EFC2426D8D1DEFB93A65717AF3EA8E2D5B4AA8EF0EF38E9600F7D4E7D9F1D67A2E63ECE4
+789FA74B159BFE2F91C19B0378BA52E93DF12830D99553B6618645E26126842AB70262D96E35E5E7
+50ECA0CE3458B3E51BEE2F21191136DFDBCA39BDC07939E521E4F492F392DEBD029C1EA237BD89AF
+76BC89F618D530160AB16269FA6B693CF14BDC4EC7C630025703C5337F61458FA09104EB15C7CB20
+AA4C9BDB7CEF3A09F25BC7F3149951A7CD75372993B80CD2112F7674CEFD6AFA764AA3486730D2C1
+897A264D82A91709FEC4A21E30D812F558451804EE6F3DEE2C4C437846BCBDA07C5B6CBA1D94AF02
+9163B7383CAC6E088AB1DC14ED3743EE77E26EA7AD3119A76C0B5F925C4DE305CD7BB3A09A453947
+5B9BD79BE28FC462D8718CE05F9D94CAF3387BA55E6E447BF81A9EDDD3A34E17BE66BC52B0C0BB6F
+86F6F008829173816D205182ED2ECED319864A796AB65D4E3950288BADA94FA32B6F453AFDFC6C39
+A4FCFE60353A64627E2057D4B379D3240012B3BB0ED0C7876CB83C1BA5EFB6E2A03F340C2B576731
+F848F762A7E1CCAF267EE06D621BC33FC245D0E1547ADC12CC0EB58B26BABDB8EAE9CBFBAB93836F
+FF22BDA1831DD01B7346AD377AA298D84628BF1C07433284B0A90FC89F5AEB2651BA2CEA405D4F52
+DDC0E74B871D43F71EB4ACE0D2B401F9348EAC3A2EF0AD295036BF6CF6F870D58E00B619D50EA7DD
+77BC28DEF91D805CD527DCBCFDC16C042BF9B874E3B1567EBA4C1E70744B9E7E5BD1FDA6A5FF6E10
+1613FBE58DC46CFAC1A65ADAF65E49757E9304E2AC9A91E0588600C709A61D4231730073A36D473F
+518A145E141D0A5A494441B9EA99AC23F60F54F8127B477E1CE698BB4129B4B1DFEEDF10D9E665C2
+47A62F112F5CA30B0AE5DBF3E495FF06EB28EB438CE8AAAD84D5F50FB56A3AF002C23BCF66ABC270
+7AC233FC0F2723DB99D2CFE7D3B3667732A531F5DC315CE74EDB9050BF75D29E6430F57CB6778B2A
+CBD57DFCEF896E6766C8FC5C9F9FBD701CD62CACF33EE0FC95E78DADD205B5F42CC63024624BAA0A
+B4DD447832B4E1DBA77BDFADD223989F8E958C8D759AAA37930664C6EFEC708116248A2A7AF3D656
+DDEAFD009B7F5333854608E67E5E588A857167ADF9225CF6C641F5E19C3E08678A281199EDDAC831
+B57223B1BEEADFDCBC8F6F25D32FCA2336C808162E8F381656E847FB6CB13969572425AA05AC830C
+33DE6E030F86A3A85D2A66A77F103C7042C97205526DC882EA9A00EB8BD5519847EB424C15F808A9
+1652A6CC89B66A5731126DEBADE123C63D88A2E550FACDEB3886FF98646000C64B3A91078012CA30
+904B71737CEF6BECABD43DD702880538F5A70085E6CC6015D2163681067C3D513A8C66032C34A0FE
+17A58AD4BC97CA69BF41F11D5E910FDFE9729652D3EA21F8DD8CC19160A8FC77573B1E9CEF4E790A
+79D8AD6723B6804E9616466C935303E063DEE29CAA6C3BAEBF278B818C2EC2F13ED645AB452397BF
+00DB8B26E115026E256746CD0C78A959364FDE6DEDDCD0F441A61A1EBA32C7BC172BB09512148D1E
+BAC9E791B7D51B71CAD2DC9B83B2F99B3726607D9CBE58B499A13753CE87FCDCE21C0AD0528ED0EF
+B9B2C927F57C78C626248AA2B835A0791244C5896686A66173EC9F802C4C633A42B086334D2A4878
+0E53D00809247BE64E529F96AD2F8B3922A6097D414DDE1EC76F9552F9B8D58B8E34F359AD792B2B
+E50C26DB05035E7497162E7C49C38D3CD9B98D620AA67492BE5AFCA3A81A7080185C7F0B5105223F
+1FA77805502A2E8C5FEEA27699858D84A95842C5F2FB68686D59FE24091FCDDE139B6463BC6C7B1E
+0E90D20A83651AF00C85797BB9F53ECEC1675C7EE636D0D9E77DBD8F89670F855EE4D4800FF3F695
+0EFF09BBF8A0DAF6B8242840CFA5BA73BEB95115F4A78BCC02D85ECCE0C0F2EF6F328AD1DD6CC049
+5A3315B414A4D61DA50DA46D7ACCEFF6EE56451805D26B0359AF193531F95F6589CEAD6FA041AF15
+3067F88A0A2FECD135C56682DB2B45A71D1FA737C064EE9A4F404BB72A70B3AF0330359393247EC7
+81512482579865240A23CD8479F21C2C44A119EBC4E81B308DD8AA86E60C3DD8ADA50E0DFE8308EB
+1A7F201EDE8DCFDA405AEFB47E0E6CA7DDB376DCB21D37F7ACC4D3E9F26B03A8DE0E8940CA3A9E75
+963A389DF8038D2C486072F61C0CEAF500753C7A6352B1CD0338D9212B42A4D3DA23D5BDF44C27C9
+4B88A415A3242FFE2E1B332477A21D2B9CE075EE479C6E657A4D8874A8C53964229310E01ED4F3C6
+86FEF5258EDF3B464DD6FFD7F1CAF473BBE722D60FB14AB4918E93878A8AE4773930B8CEE110F476
+7F42A52D9304C55BE12846C911A10AB9B2E036BF9DFD597F5348D42233315FA80D0F563C388BC253
+2103F05E90DBF1923F229F980A2F4585C7A373511372D07DCBACA583099EA972C03E5AA67E663882
+6DB134564DB993CEEB6E7A6659C7C5C05C310267D5F8A24EEC2D5CC3E3F3C808E6D6068D1A57646B
+37FABD98ECB7BAF99E7D9AC4414A491A73CA34C52F394352F6B5A15F0FC4D88622DAC694699C2464
+84ADAC3B1D366AFEDE2A2CD2042C90516A666A19A91C80248B11224BEDDF1A320E230739E755D098
+B6A67315535F4C187CFA67ED817A035056353FC859BF286317996FFFB478A2248B908FF12ABDE705
+402224A3EE5F463DD3D243875C84E02DB968ECA1CC52C75171EA50D6A88CA91327A7AA5795019F36
+C0A19C093A1C9D3723C7568F9D41F2E4FFB712FD47F897703D7A620B586B81936C84AAED61D84332
+B3BEBC4F95B796B93EF7A1F565C494F8A65EDB21E2EE18DC025522EF8E599887CA2836069CDDD889
+88E5862977B7472584303198CCE97EF9F9E1446D1F1F5ED1CFC666A8A0C3A03E1792EFB60A9B4065
+49E0DEDF6ACCDBD98742568B4735A747D8E5DE21E630125AE0C691D054E42199C15B1F80CAFA6E7B
+B2005F374A9A5F9900ABB7409CCD50C3AFCCAB1214E6A856F7C7EBA89BC3291801E1343DA9DAD2C6
+ED075C8ECA1423B43E587AEC67E6145272814B3F191B3C285639F9E2D6E148A02DC2CBC0E054D629
+5CD05DBAC1950400A9189316F0265B86A732D302C5BEE8ED233768F237C62600CBAAFF3A110D5EFB
+6CC7CA3B92D965CA7C5E8D3E64ECF239FE2507FC797FDBE54C1112B28D4DA44C60AB09D994C5BA78
+D663A2591934CC052BC70CD1DCA3325C66C9CB982E2039F5DB70C848D3DCEF655B1C2CD0CEC8865F
+E8E1C0A267BE4F707ECE6F5A3DFCA3CC1EDF92C760439F51AA69A4C1801E96CA4D6EA4AD980258F3
+D15C893913ABCE09101984C61B91D603053E49A97CB82FBA707DAE8AF1D579FD69C8481CB7B712CB
+CDDB4D287BE995E32C02B399602A08B9DD849039B5673F1930BEC7BF366EB082D2CA5DB2385C8CC4
+5BE3FC0E31820191A814EBA7C4F23B1938E6C4D800732787CD2CB97F762DFC85D4B798809B5F2254
+D826CA42B32695428D120298B44CF38494E56240B75DF1E41E46E53C44DC505452256DFEC819408D
+605FF14D6C1F3F152F2FEA96EA0AB3B472D8704E06BE9F8C3E8395CAADD06D6DA033E81ADE5DC3B8
+3DAFF743C6E9E48716003D358DF63CD7FD3E2F727D1F2D0C29962F76D5C95ED44B6F08D052025A66
+5785F264A3D5F5593677B630E628B5EA81FB37CFFD7A30B7FAD226B6FDC82B0878AF4C0EC4F4243A
+807B9839EA62BCBDF7C2E9B30A623876E632E084EBF4A21EDA04FC88A1C07021D0C72EC3E969D449
+FEB08E5826EC20E55B21EA71EA59F6E3B0710B0DDAB3261B4A2029ECAB68C19ADD5174E55D5E984A
+4E5F38F592A302FEE6ECE732DDE841A28672C620CC5D687455A5C06FA9FE688394A04F96312ED025
+B7AA6FBCE2925F3AE559CC1886BEECDB70822E2E5CA3F732A87404B1536AAC469989E9610CFA440A
+CE43875A70CA51F36CB6F629D9424C1E35A88F92D5DA3CD8CBAE6E8425A36968E21F4F30349749E0
+205BFF8D552837D6FC39532525370BBAC833F75F1854C93FC533A4AA53ADF7008173A70D94A4EBF5
+38EA9E62BCDA7C20E0A073BEE2EFAC34D2EF1D03BABD5147659E50B557045B2EB89DB303749B04D3
+F54B43FED612FCC68206E001A7AFE90230D9C12F74A32C7EDB5D0241DC3A5D51481FD7C8FAE08FEE
+263FBCED7C7D911B3A303C835AF5FADFD218F61A9D6DE80485ABCA88200047B094441F7767B97A24
+E8C612590FA2407BAB1E8B56C71914EEF2355DD97CFAFCC192BC06FCE063D3D9D1A629AADC75E3BF
+207234C208E7E30663EDD691043065C9CBC473D97C6D4DD3DFF59D6A9ABCDD4412C3128F603160AA
+D8F81C6E7A4DCAF35F3A99B4EA10A34375B477C2BF846521A7EABD4D28078E9340452A198F3F5ACC
+3DB7E3908939FF6E3709C6A3FD9889439A4AE3E10B618CC92E14B68429A3AD2C80940A1079452EC2
+66F254657BE7D79A2A24084AF73F6DF71FBCD32BF6913A3FAB25F977787F7BB0C3A3E8BAB38D7A2D
+B0B4826950643DD1E03BD7DD1FB149A33862A89226B7CB454DAF613128C2075470E42E70A9444A8E
+6ECA526345AB48E6F5160BA23B5BDDFDA6049EC44ED1461C7E0DD514B16E2FB285F72039DE3C7982
+EFD40D7F6C8E8F4CF35AC71B467BFC578002E8D2239A2FD2C4BCCDD8AF3D7DB1F4AE7F2D2E0811DF
+9D0155BA6EDE50B5F052F14F6AB884FFF244D8806C07EBCB49ED22D85DF696995991A954AA97A1EC
+D86ACD76E061B7541E87997FEF0657A826BD88EF3A4A5920462C6595E7A156F453291CA044CED810
+860C3B0149BCE73BECA713040664AD0591304106129600AF71317B0D2907839CEAC99515D357E980
+B1937B6E1200AACADA205421001F1B2F91753E80D2263C56AA164A74701A8D5FD28E46480B0DD963
+A683A1F355D7FB4463C7347C94EA5E2CA40B60B56297CB22D972C5BB10E56715A955605256C1541D
+9F3BC5768A6F355CD3B863F0FA1A781EDB49368F51B29481CBB41D4AEB07AF9DBE8F52C5D0FF75F7
+FB6431D37D6AED84D78C778871CB0F715B4F07580F23B586C969C81B471FF6A6C7276F7E141E02A8
+584D4B9AB00E7BD643D2C3FAAA299B1F1E25048461952EA42D4882768A70DE46B213A287F8D31AC4
+6D5436F22A796C05D1FE50A9BC2A928066627A0D87DD57A3AD91DB446404B41557D1457873482005
+EA20916BBE46C613F456C849D46BA79D20627B446B2F49E3FA309AE14F8C420CFD94922CBC0FB9D3
+5A0F7DBEF577F1849A1A80E0011DA8AC082A8C6F61658E65AD177ABDF23EE17C8CF0D26B9FA3A6E9
+4837EB9E930336889767A8D7EA3CE980A8EA95528B004957BE6067CD9BD8E02A0F23CC1762CCA656
+D33412FF45E917FD4A03EB6E8C1F43FDB0A8965A33B4FD26BC24A20B304CA817E88495BA9B361A3E
+933717FFB0271F7F70C5D3CBA1E86D0F51BF3ABA194DAF32C35C796627D00C7B2271ACE2463E37E9
+7B3C826CF3DB60028F240F9452CBE08F7EBCC5FDB1BCBB3C327A9F450B9E5671916101D6E3E5E458
+CA31F04D12F592F83BADA2C3683D3886AA3B403963AB5DBE220FEC00037A745839F67A3635DFD3BF
+F08F367482962DED88ECF6322852D643A54D5D303EB04BFDDEE9BBA1EBCCBA7C653B3A613A8E719A
+DEBE3CE1BD7E754E5F4977E863E3C2D388A65227B451D4F3A4F94E06513CBA4AC1F2F511613FF035
+611684CCC461599000E546E4D972CA6960E095A526E4735A23421A4C9B597ECE08AFA2753592BD16
+DED93255A1E33DEECE3C5EB77B94670E8137F2A4A4B98AC193258E7DEA5DB8408A806188F2D1DDC4
+40CCF0E9A6E2F0C78FDBD7B68DD4939D2458C1965BF8BED4564B32462FFF3EC892C03B11D3EA813F
+AB4CFBE8D3016329C5B7E3DFED0F08284D44AA0B7A2F6BC96EA4503E8EF52A64C22BED6B452581AE
+8FF8917D53976471941A9116A2D878FB2541B561767ABD4E31CCD8A590CA03494C62AFFD64EA0A1B
+C779173DAD84999C7A8D844EB1259DE7BB5B25CD023537A474A524EBE4660B22568949E624D8FEA0
+AD37F4CE1EC75955EEFA49C6BF1803BE87E9C9865FF3F6B8525B8C15FE8835CA153D27E6C0FF0CA5
+1029A7A9185D25F0F14D86FC797DCC1F99EE97E2054B9C2A2E06FDBEB8DEF6CDD368BF23A858D9F8
+C1DEFDCEAF1B4A8DE5EAFC604CECCF0D285BE00AA912EAB66EFF4D37AD2EFE34853BBFD87CE09B18
+749B489943EECAE7887B006FB827D10191DAD18466CD1F86505879310A8B171F902EA0C26A388E13
+B53C700272CEE2BFB47ACB58247C13449C6BB9D01232C32517358F1A3DE064D43C18F8827D53789C
+CF3CE2EBE78949A6ABFA1A6B8414CE360A5E22AFB7D1DCE6F5A06182C3B984B4F9BB1A905A9D5A14
+83750A1DE0A857CD5C06945EB7D4A2A6BF1237F32A154FDC06D51A703D44FE052FD3C53E9E8F417B
+35D1C851F9203A8997521529F21AD8498F96930AA77EBAF82EE02A57BC77C792D9F220294B45F48E
+A8FD94E01CD25645D36D168923562F3FDC93CB79DD4760DA0C103C2675722D7A1B79FCB4245ED12F
+A0DB52492C9CCE58B333CFEE822812F7DCA68E802C451B5CFAEBAC608B950386B6C58239D1C62D62
+4DD5D15782FC552222CCA06DDF387B373E32C3C2864C63C768350C37283760F3515A5B0AFD66C48A
+B522EB3E808C061F5CD6BD96CD18C9839D30508E7D4EDB88E8F11E31E10919B16B7971F06D7877A0
+58D8A4944C84FC6CAEDF3341B48B6E0D3C7B85D710E0C35F5B5053CF4B4798B3778CC28B2DC7AE0D
+F3A49F9F3BCD8E95D746C35C3F47D68B8AA35D97AA08E711B5FBE70D1A623C82541EBDC51A827D0A
+69E6C049087AD26F256EB7577F58CCFFBCCBA5A95D093DC29464C9A38DE95BC6B1853963B2DEB0B5
+7AD1248D6F1625E115EEB9510B5772AAE4E3C866657DB0B3BF0E0AC345E116F8D4976B770876FFE3
+748C36165522991F46A36F193DD1A1C94713673C7E4C81582391B636C72DE94CE6254374F99B623E
+5686C13D8A8322E83E11BB0B0A896C6A8C2C4F756C5385CD7017F26D23F7C3EE97372C868C8C9155
+81723BB6B76B4C3CE8998E4FA6CA40B633DFDAA59BA902A4952DA90EC4FC3CF0F2676ACFA7F76F78
+236FA2DE10FD3545357215246BB7E527F277C28B353CC6D79DCEF21BCC8F77603CDD58A2CCDDBE3A
+9802F941CED8E035313875319548C41992A2BE939A17CC109426E33825AE59BCD17CB19F50D972FF
+CBE7D9B4B0BB095303D9DC9D406696C2508D6CE99E11CF00F6461147E97449ED5F486D480A86D3A7
+ACECB7E9A945984724EFC21C5079B1FD03ED803C2DEAFCE3327D2D7827715FD65D9506216C88B0FA
+26935E95C64114A51919D419038B1A7E9C1E829FBFB53275093752DF19891A97F3CBF7719C1FD6CB
+17019A6D2D25360ECA804C4B35172662CC4769D2B785C6C87E5A4ECCE31704E59F71263B7C3CAEC8
+ACB4C7426EC25F11A0042323EE6C3EEB04284DBAE2C770BC419DCE79BD4560AEA41571C3B595F525
+60191DC7A8FBF63D413A77A0905E517441B16C2B501EA2F9E99CC38D052679F288FDF1894542E3A6
+6989A0090185EB2E75134BFA3D9147C3DB8A621D9D35E37786853779E157B47F71626D6B3E633005
+9159C17596C1B87FE2B4FF47ED9D78FA4C2160077276C8B58CEF5DC030B4A5D83CF257096C047FE6
+4DE307C598B815058E72D5F57DF5C369E664E137DE29349E2F9DCD8C9F4EBA6E765B6327D7A20DFC
+B20711273FD8091CBA605C4C494248076F7E03DF65A6A50164980BBBB708741E5BF6056E6F996DC0
+7FFF408C5B8EAB8DCEC315E92873228C805D4440A6470E3EE3983758DD211C9CECDBFAA4C9300CBA
+00608A4B2404A3C7AF017A3B7E67F39F0B51ACF950D3E75CC7BC2B8D3480202FA958E8EE0B240501
+5232EE0D264C7CA02C18CA45CB3C2DE322D3EB7F00F9455DB6C5B1F4E59C3E95520EC36D7D903CBB
+625D70B54BF6F8255E412604BBB29FEE026CC660577F91DB1DB4A613EEEFB20CF7AE3CD89D565AC8
+38416B01B5DE4FFA5550D17FB51FBBEBE21CF1D56038863EE931B90DEC2E211ED42BA92EC244D4CE
+2C4EC5CA87A026992772DC2AF754FC982B94F36EA7B7BF75E0ECE90CBB2A6AA1A012E8898BD679C2
+3CB3827C35D5D02F0569C7AA82615D4AA67518ECF668D3B57D6EF1A8013424AC2268BA0D9A74D588
+79EDCF6382A89D397864940303EAEC45A38304BA8B1CB198967AE23EB81054BE74B16909A405E8A7
+799CEE3C270FE2A6DC50BD7370B6B2C8FDB9A87D88D5D40348D3984E39C693B6F4486D994778607A
+80A3122872DD65E40492107C71C3CF708A9717E9EEFAFBDDC239C53AA9645B711038E59C8B861B37
+411AB2039BEDF9CFD00F08D9C5D76154427FF5DD39878CECC5D7BFB3F1F035087185C0981F3C2139
+BE84872FFAD3408531C4EA9387B89F5E3EC779E8850D50992DFDCF9132BC551E985943B07618AC10
+D1150451F0844C0DC41D6E17EB508DC8689EC726400D5A7F6FEB3CC7BCE05F09228B7CB2C5393664
+D8DD9A4B96B1020EF25D70AA2D91CAE93AFB5F2BF0AA18CA5C599FA1A708EF35BF8F7FFEC9AFC1F2
+42870D028B2B1459063B493943EF1283829783E1010242E5CF4DA39D93D506F3892936E7D6CF1124
+70A521D397438733D053944CFF12D6FFAE8246F20618684F263715AA98E15D72A526383E05C23214
+B78338E5B476F0981D90056E6E5D0DB66B1DF2298E597B2ABE1D817E18BEB056E65EDB4234342D96
+00470B1420C9210419D834E431B82F58608C87AC361A02D0F1FE4B470A3D71E0D21BB87E1023D428
+E23D596CB9E1A2184403A16E36E644BCCF9BBDE27290485057E62827283E7380AF786BF395B3961B
+A5EA469C315763FA59E0F176EF81985F38B882DE56A74D128E256D1B89939728E55A92ABA21A6B78
+44FAC1BA7BBDD8B34A18194A2984B000380FE9F672E83EFDBF276FE797A325815B0F25CC95C97A9D
+ACF56D583486305D7C9E51A7E337D14E3B900333EB38FD93A99587DA2341B10C059C71CE080FE753
+3C0F059FA40E560AF9C4A41A4BE6FB45846FF8F78165E10B4AD40F264BCF5596A1E8EF8CB6EA4B1A
+3A5C69059AB1563843679ECB2511A90E8898F54295649CB73D277760D8D04ABACC7BCC6E777A0530
+E2067CCBC08673F9C8C178F9D672AC8A15E5367F0C5651B53E75E0CFA57C931746AE1A679C246D7C
+9417F1CD89DDDBD1173C2F880B7B3847CBCCEBF99F7122E832D7C9BAFE2B54CBAA1ED48158DE3F36
+238B76B0E67644A28AEA996DDC006F6AC0242E4B667639E7523CBC90A0561193C1AF34481C2EF402
+EE43A82E1EBF4E3D601BB36B2D95CD93550D61CEE7A94E72F6D30C32C8F91A61E964B1F66ACFC398
+7F95D4028F116E9A9A8474AA29C1C1A984BE0E393BDC41DCEF6A6F1018DB60D52024899D8EB5D55D
+324D73F39BFA47377B9E15B3B06A7585589FCF52A54684173E5183367E7B0952DC4BC2767C4C6247
+B1D6103E52BC7B7EA6298F454C5D97AC575F19C10ACDFF4E10C7D3755CFAB4200CAC545269FF1D8D
+B0D607C7AD47F40DDF257AB4E7D0750577003C13E4941960C3DD7B0774DDAC18E8ABAF8F53E03CBE
+F6D57B44F24CF821014C064278FD51B3427593D17694B4ABCE81F49CBB984C5878CDF0C38D1ED7FD
+99B0B9A3BD8D8FF6219588B3B8FA59D0CDD1D9B2F65122AB45E48F1757467B9204926140E3C350C5
+A927A2E700173053EC35D3F1DA2D7258714C97FAA857F0898917BD94625C6D1E2D77138EFCAAAF51
+7B17FE187A2212C24A881A2C6A647DEF6376ED80AE4175C5EE80921F001995B44E49F0D33DD9075A
+CF33BB03671C0BCC34AD5784AD1CDFED3A6D9BA103B3DDC1CC2DE74DBB576A0277715275218CD19C
+A8899209125266D8BF1286F881DCC2C383749D1E768D670F4099F7DE959EDFE852583183C9111601
+2881A56A24AAF020EA45CD5F39660DEBCE30AC1C7B8CFC60387B1B0C3E361BE612FDFA9F01B7E4B4
+A18839A2C7E0E393EBC5AD9A8A4EBC316A740C1C295D9EF5F4DFFA0667F9582C0BB837B142C4CFC6
+B1798E9476D0631111033B8BA75A10FDC800E2AB1E0E829632F869CFE4737BE9E2800759EE0831DC
+7D1195EAF80555771981DD6DC6606812D92CB8EF86447F5F6C6F626D0E265C67E52A6319189EE349
+D48E49DFE6A9E98F76C414A1E3217AE0A215A17E54AA498F4ECDC50242ACC7E2322F63BB2FF2189D
+057E7354E32A3ED1803116176B9B9D0129930F919E2FEC280B2C8924E49E7BB75768A2EE1DA8ADBE
+D4E3589906DF1B923AEF84C1BD327438B731012E69BB0D43A1842CB88BB54EA4516477F704CFEB28
+6E3EA483445AD4D74586FCF32E96D366901084365F693A53C5FB532FBFE7BC0CADC404C4985042D6
+8DBB90A6DCDA3531EE324D558A214F935CD9FCC9A0CEBE9B5FB0323F4B3820529599EF48EE068B5A
+CE85004FEA2984F0A86F5AC9D56163BBFE1142B774148F1EB0A4DC89C3349052533A7DE66729DB24
+41B82F8F7360111DACF69293C9B281A0534F3E9E9224A75C49A832F28B2E497262475507B6DDFA9F
+01CA0A6696E3F5AC7EA68595EBA0C2EB8A47813FF936D84AC1B23ECA7AA2862B793CCBB0DF9FDD49
+31BEF354CEC12FBF478559FEC29F81ADF4452E83963E56541D31F3691C93A50F0BBA5E9552C4F2A2
+3A6E53060729854A3DD71CC4308B91957DB19E66AAA18FA67055A950F1C2CFF78A03BC1A588CF624
+696068068719AFB1001C4581EE072113882D9052B21E355D401ED8CD24D067B99E616BDA5A0A5A93
+36FC499632B79FF2FD0DEFB096EF46B75E2D4E0F48DAEA239719FEC4D9A29818F5875FC5041A9EDB
+D26CAF0ACE14CC80BA49BBA59E918EB3D8F1E541AA16026585A2F72DF7D83541816DE46981FB3EFD
+0C30E458CFAD04C79421AB7C4925E23AEA07F9F018431C790002596D26BD9663B51B699DF53E4882
+CBC34EDE88EB55045B889B6062E35FD1E018BCE785157B85EC3B9CA6C85D4B16238275385B8285DB
+012D8FB7C9F5B946A41D7A0FB878FF72C39683144D8A007CFF631B43748F2D5FC690300F9BC0C837
+006B92ECEBE0605E8C3A4A400E18AE8997D1B45FEE10068E247C647CF82C6DFBE5E881D511FFA687
+B7AEB78546BFD07D5F7EC242DCEF4930D8AAAD8C6152B6642AAC325963FD147F236BB850A9966573
+9D06CDBD7CA79A527DCF461E33F22BC9C5DB00DA2BD3DDDD8C99D99793BC98282AA8872FF96C3942
+85D82D9419EB78B6AE37A5F519397700F75D624A09BD255B576E955A323E784E8FC31131F003B0E3
+024A4F58FEF2A6C043796201FC425482E1155E229D1B2D43EF7B0D22322B22EF5C9A1BE026A1C3D3
+75EDAFF99597E1E5477952A4E8D2ACF5D014BC00DC2A272FA62B6983E27D228881E2EF2B8B95A681
+CBE90C5FDE16331C85222FE2A16F0A3C3000A63E2E21666C0C119F8AF89A543D37977069A5ACF155
+6324F05204CE8CAD50FF4FB630D9CBBFC324DEDA584AA56A99D3A76FF55BDC2C2EA3A021361CCD4A
+83C7A5E2768D210FA6DE889FD48A39D679C94EC3C99A8D33FF11377DA7F6F1B71A2A05B302ECDE95
+4F26773F39AC881542F0D0969C3995C3519A8EF70B4220D86BF01BEECC6462855E7B686E1AFF1CA9
+1FB8FD8B4A69E10EE0C2AD94ADD44449506F9B6EF43641F2026EFF6E605C670560C2B74706FB949A
+A7E8CC6A2D0D6207E457E7FD87EC1B9092DC68B9143947CC8ED14AFDDCBF8FDDA228A76847F96802
+E561F67CEEFDE45AE587673983FC04C96744DBAA83F2DC838D633943C75DCB9E6410474EB27B348F
+26E505F0AB90878940E846C5E9F3C5FE8C3558C3236B1B88C405716949B8506841CABE1717474BB7
+C30DB91CDEE33B0F844811762FAEC535BDCF84C1C747CEF9B1FA61D2AFB5A81335BC42C06A94D7D5
+9B7EDE55BCF6F9867AEE107555CDD084B7684C2C87087475A39A9DA6347BE281CE5635A4D07865BA
+98CE26C1465B1AB0343F49FF37B4D0CA9F3BB693D78DC3B21925CB996A038DCC172527FE57C07460
+EF39C07D4396E7FA970D9F22ABD21A9C794B64AD96762C7428F59A8757C36D6C4FFB23216195A04C
+2A2C2E7B10EF7193931544D782FEE4B91E01119C5553BBC6252270A8D8C56DD62D448F5AD8DC69CC
+B45E1F17F0AA1E445129DD00F000005B23D38DE93A3BE55A4C041947F36B4E4536E307D0180553F9
+2E46B743881CB5D5386C48C7D5F84C2BCD06B9C501F78C7EE61FA23516791FCF4DB278AF688A2E60
+10A56692AD92008497487EDFE4BD5FA083FA544138B20D6940020887E35D46E093B71F7A04A67460
+DC8116B4D4839625D7CA6959D6831CD93F81AC4EA2709036DD738364FDE71113BF22EBF13DFE1642
+E564701E6F0FFE7511EDF03FE448C2B28C64FB7D54B94CA576E481FA56B2B18AF10C71F699B6BFD4
+7459CDE1869D0FD306BF489A6F42E5B2F05CCF55BB6B9526973D19CB134CA7F13F1DB3716F8CC217
+73A832568C16250B5CDB16DF24BF81D49F5B37018BD310262EA7078107868AB0216CEC83CEFCAB1E
+9F2C665A31585CA04DC01879CAA79AAA5AB201B516F7052B01B16BEE5606098393B0E5D9F9E5E3F4
+EB20F63C958E796DF41CF28839F5C62A0431648745D7837B519F3AA36BC6C08EF040CCF53D9B6D8C
+0C7D1A84D707EC57A3C6AC9A62AB37251A01A5ED40FDEC6F5BE6E34C6A91D058319439778A2EE5D0
+363E2E1F33463C33327D05FFC0CBF08D5BC457C7230448972FB9B4D0D782BA7DBF10D3FFEF8BF523
+6EC16D4DD6D0D870D9D5EB5C64C9A46A4F583D4F831FEE74B0E5B33A09ABFD4444929BD8F638CD72
+EAB99CF2E9551DF427683964A592E49D186F285258C5D5F62196A98532421D73E3495F82695FEEC6
+E1952C562D546B28618FFAEEBEFF03A57F4D855021F85B0C7BC37FCC6DA9AECA099B646B99D41896
+09D3FF2D56422F8C37E97640293EC7C90E3380887836F4938FBF495CAC14FBA5648D89282D8D49D9
+1AF73ED36581139D8BD42551E263E830EA3C6EB381D85C42D74C50DB0CCAEC03F535ADE92128A016
+0E811C34748309AF7604919B66CD43EB5CA975302DCB6076FEB6BDD6FF55976FE990FB0CE9ABB11B
+195403FB26E3D6C6A0DE1C5BE79E171A61E21F79EE8DBE7A832519813EF6B33EA098C2C32ADEA219
+AB2AAC8B093F40000995539D1276D5F2EF84CCD099B71FE4269BDBDB6A8D59C86F7D2E3FBCCF8773
+D0FAE97640BC1AD43CB4B992BFADFB09DBD0CAAEB8CD9DA264187C4F97300E9A6C9DEED5525479E6
+05C65AE336CBBDF4E5D7F79AD098F977285E065579B748FEAA97F2A753E1F962FCAB68D72BAA8EE4
+FF6691C23E31BC0F3E981A96FB440404856AE1AB32A7205B17D411D8F21C8C93B704D07EC594422A
+BC368CDA2B1610CE6A973F4474E12B78B532666797F5755D269772C9F5400B3BFC6C58395D38527E
+2CCCF29B56123F7DCEF3BDE5DC1DFC5B0293BB125085B1D2D929BC3EE84F4FAD571A4991C3DEE03F
+2DB3A3097E52B1A7D5C73CCB6148EAC62E8E36DE9A71C57638C6E4D5D9DED18174E8C390E50B4A5B
+913C074EEAEBE390B214B3A68F02862B9A296DB4B409769649E51D738CBBDFB7702E15C73C2AFC6B
+C37CE15171F4E822CF20EFE55D9F061AA43E648989628FF79E65932390CBB15D8E621333B18B11C3
+BDF96F841D7434E01AD501FEA964A75B248A35CD9DF9A37E48A1E5A09C624B93CE44F0042FA00D7F
+9EE89B9F7AB785E9C718CF6E7228F743271C2C9BBA17E5208B920E44E765D99D86650EB454B0FAAA
+112753AA1BD3A24239E9C5FC47EEB1547AC9D23731B8DC48B9707830DAEC60C8D3790BBA1120F776
+4EFAC542CFFBCD5C05F9510B27B2534B704ECD36C8B041FD49A96881302FFF5B0163A2DD09C751D6
+D6AFEA9170A4F4C4AB8D46E62F763FE1BDA51DD1CE4A27E772F3A2869155F762FF26B7AA6FCFA4F1
+292E56F03AAB6322BF867E7710C34D43B5D85B45AA68014AD7879EED051B1933E491496E3E26D9AA
+8B80A07BF2B94F1077E84A9726F08199887D66DE7A307BF33C30DD9CF3DA188088C03B2BAD09A217
+6B110DB2C868B53DA9A66C85737BA66C93C58A259860E294AD0191E3A72C73F40B0BD98699AA08DA
+F03587B78F391F3A4313C58D9F29B53C70785637BD0C58310109C54091AB0A34CBB0C478613A7AC0
+FB8F0A8B4645AC966395D8BA775262CD291136AFFDDF01C1D83DD4EB3B59CCAD18057FE7D92A8CD4
+A58F22508D9FD7CF356571F701BBB23E749BDDCBF8A317FDA0AEFD952BB18545610FFAD3AC143D35
+1B8DB3F66293375E0E50235F0D0466932181D377EDD32A5F0FFA4E22B5A0CB4F343D9A7E4A342E9D
+09DFF6C697630CD3971802C277A5590B8CA94BDE6B38446C794D072BBCCB724D5BC208EEF1B018D7
+39373BB910D668882CAA779C2D686081DE6A2606417B54D7C20E0E7F722648D893E4EDBAE8F00D6A
+6DA3712F91AE860C756D1127D133AB828E9D80023B50B162C5A1C5CDF70CCB3FDD7EA060ED20838B
+E1E50C4094C9E79E1A0187CDF780CAF45A725964F004253E034C5BE46BBF89D94631F1A33BAA35B8
+4FA2A9D08481C6674126CD96ED05DCE48BDA069D902D6836D5DFBA701DC0F98A863E64F0E312145D
+8DC0B77F25B43AEC729A1243B45B08CA228DD6101CAA2AC5ADCC8EFF84A4CA3F254176C2CC711EE6
+C273835D0FD3528ECA2A976B88E51FE347FDB60F32370B66D338931D6581630ED586F349C638960C
+31AE4204E89521A96E1219E696B913DEB2AAB7A3B022D06F34FDFCB810A04E60A4FEBE284C2F063E
+0AE9EDF87704921CCFA193BDC912B747E13570066223A49F1F6E2AF0D4D65DA04CA876FF7A462FFC
+9C0BA2CC545C3BD36DBE762F32B2D6BE5867C59F479195C92440DC165098B74EA5C3AD93CDF2D410
+B04C16BC7801E7956F4E5107450787AA592493171C3628E6B8F49D4F8429EB98DC52EF025F001387
+BC1A7093F7A99F10B5D2D7DD8BBB393BF6E56F08F4F7FA1A343F220D5A1EAE7168C74D41BE1DC1A8
+3BD65B72B982F4F7B34F24F97F9EC9A91011064031FACFF2A14921A32024385F4E061CD07D152E74
+1BF97156D951A342488FA7F5EF934CCAD13E2753A0AB7A1F565C2F7F6B349DF03BBC25BBD972A9AD
+F809BB5C5048A8CCEF9297B2ED3324D18867F293CC66E88B3A39D107B610DFE79A3B4E83A96D3D52
+A17FE8A62C9FDD271130148366942C9CE57558D023DA5F7501319EBFA33DE9E6D1E76D7C20DB8A09
+B657839DA99F3D8143F1EE6253A3295C9651FA4366547893C2DC7ABCBF4BB7609DE5D001E0A36D9F
+FBE01F7D0903B3208AE8547E2E5F14EC1AF4C2535CA8F4EA37E3F3CE172C7A1E8308995B1CC23E6E
+81190246BCAB6E755BF868D449BB02A2AA87C44C9CC0F571ADC72547CEECBE104BB274B8AC16DCB7
+5D5F458D356466B921ACDEEAE384E2EB1DF6EF393B41B9747F0A4FAEB4AF1928D9AD6FB7E06FDC62
+1E4C6FC98CFB43F88584BD55D9B97CC9549093EDE586912161931162B1B1D52D0443260DABA02AF2
+B4432100D5506546013DA703573FA8013685CC798CE501960093DED713FFCCF89CA2B9106390198C
+29A00864108CDCC1984A8BAB53919028C01B26ECC7925E38CBE6CCA8978EE21C2B06E7B3E48FBA97
+8E2A7D186E563C088F84AA23178B60E4729EE87D67B1091F3B6973676C1CBFE6530EB773C62E2C24
+97014AB0E8B71A1F4E86A378AA26591511BEE3CF3D64C94848582E1354E1605B6457823F2C5E640A
+D3802946BB2E7E8E594E8C04B430C2385DD40746CE8534F50842E74D7115F3DB0C72D1C9C607C657
+3B094AEB73B7A79876CFFC3E2F8C9FEAAA07D3BFCE05B61F7749A8793BE90CCCECA2D7077F25E899
+D3331FE161A7E86C842495D584C6E4A0880B2951D8A13B88C4672080A0B1BE36BF47C3ACE7288CFE
+41A8C1BAA6F0814A947FBD6B3AA72B6C73A8C578CA51CCC96F2352316C467BB960E981F2B6485BFB
+44B577E71EFDA16E7405954BC7C9F0759F5A9F1EBCD2FA9CC9648D5831A68887F41B15081A204C24
+B4B992A231DEF9E698D4C3A25B6F5474F5BE6A601F2D337A58A0D21FF37FD91EB86D1D738893A03A
+69F0CD743F611CDFFE69DB2C6ED0E4611D56F803BB0DC06E7FE85A303839612707647B1BE9FAF8D6
+84122CA9E5CB8BDE2936D3F4FF254D31529D7538BBD4D35539489F9E7316F24214B996BCDCF1818E
+749A71CF0E8845AA1E2A58AA62A48E02BA4564625D20AA220EE719608521D7D7A7FCA0BD8904A401
+9819D371F3F59D46C1354E5FC1A6E5F79B20CF4ACA2BF0F2DE73DA193A6F9ACBFE0B4731C4BCEBE6
+D96FE822965DE965232282A3A130361F188B3AABDA95A8A2790D9240BE008B6A6DE4BBFCADA05B67
+86B9BB8E0DFA0C30043A3B07ED46277E07B9808422C8ED16758B9C396F4EA929D769785B2C9568E5
+70A83B989B25CE200F1727D41E2B702E7F88F1784F4C83FA60A74EB26B2DA95126E508ED519A61CC
+151DB6804F61826C5F86D8FA89D06E526FED97A0DB88EDB432FF32C1ACC9B622EEDF601081AF7B96
+3C9CFC1D13E4A9C74FEA0A1C8E3D8653CD92A944D4CA6B0D306619AFD503506D77732D6514F604BE
+4610C2560931BDE0B40939BC1D126B0E97F72AE1B4A9252123B54F7A27E0CFA4425B4546526FD741
+CA77952B10D13E0AC2E32006A903808FF0CD013F936238C74CC75FD915244C56A8412F37F0134840
+347699508D6F3D7F3203A25B7C70100719582CD588590EE34B3AB13E255B613A6D00386A0104CC5E
+D2C646F09A88888D3751651D5646C5227A3C80E8DA1B0A331121DD2429F1F4775D30564DFF47D01B
+BE2C6C72CE4D1FD9A2077C04D2B0274B8916F6A9D1A4A6964A534F47CF241D5A8E34B23F85BE9ACF
+FC2FEA961F277539F215F8728D6788F67BEAF45502839BCF23D8763C3949352F00C579A9A4FC408E
+C625E310DAE61512DFE6844E82D36A2F81709E1F05B38AE9C222ED62C961EE63593CED7AAF73CE2E
+D3667740C77B309B93EEFE1B4BA65D48575A66BE86743DC9E5D3C2FF418D11F7F211B86E827EE1DF
+C3613E7498030F07050524536D1F8A94DDB6698BE7B963C55CB3F74B676CD815A7B3DF4B1A0EA2BE
+1B0B9A11FFBFD5B1FA49668AEE14629316AF436A0821C20BEEF7B3480847934A99F6D85B68F4DDF8
+859A754E009428AF89A90D1852C220A607FF0806E8080726EDC94D691D214B4521C147C4273AEBDD
+BB4A697EF16448CD9B2FC95293305858DECFD406B89B9F3FDAE2AC579E80CF321EBAE5701FB2F7CA
+D8ED04B4A63115886D45D6120F69AEF1A21D80AD3C2D35D2899F1902242B96CD349E0AAADA40F7A1
+1282B6B52BDD97708E58DC5E2D22D1153E5FA3F3B300BCDFAF98DEC2F4E3C82A1C85F985735F3987
+4F557579F422664E07CBE19DA680EFB0FC82C323EC5C4644C51709AC8D674608A8043C91E6C7988D
+430F10BA6CE1FC7FC0604FCD8F723895250AEC36CC35B3FA14FE2A0D24095DCC30B2093F2298F5F0
+A97676A0BE66C3DC9ADACFE2FC0F721A20E945AFC1096A619075D5E9A264C796EC6C90EF1AEEA8DC
+089B44FFC13D27CB2370070A52D4416C53F364393E46EDD7EDE00799960CE6E0D57E4909E88ADD64
+BDD2B0EBE2D73FA6ACF8B40280DAA0637E705C65AABD523B8815F22F23E9FF81E7829C7E4BC980C9
+143AEBE1A04DC0D253396BBB7268BD5AEEA356B610D5DCEE03135E00AE34388251F31714A1C40E18
+2652C48CDA2211A22CB6F02490E69A44CECB169754C53B16028D352E0119F5D5FAE0BD7EA1CDA647
+12A6147374B64244E21E9EC9F0D1381AD22D5B6212B26C3F9AA5F6045F25DD9F5EB4489EA39B1945
+331AC70510C5752557DE21D0A6CFC1EB10A98FA867B76DA6E4249469F591FD154D39E89364A43DB0
+07AA0D7A911CFAE6CE2B557997FBC44F55A27F622BD7B8B10EC9F5D10F2649A646FD964AE1B111B3
+5B46A252C4DEE44E7426EB5739F24E8A390694597DB3A1FE7800C97E59558322F0E49A0CCE2AD94B
+1E2D1026AFA771723E3F523916F55ED866C9FB4A2F759651C613A2CFF362028CDF9D38F05D4C7C60
+24C533E930B64B099FB1AF04B01F5FB9CA6867E6EFF55A772C5391831059987E10CBF987E3F378E0
+1329F73D54DC0484177D3C3C06F67397955FF1CA4EF8AD1606B70455255D631A7D6EB92BFDBA14A0
+FF28B2ACE7E81AD666EA9B3A0F5A6BA3B5DFE35044FA4B3D8ED956009C60E98CC132F2E84967F4A9
+8A67B336D5EE7CAF7DD1F74D1FA08619941361FA7312CF225D89CEF97E864C8369EAFAB94D97F056
+5505D825972B754F6729596EEA91210B75DD8F645382ACE36DE60819A02B3B48DD00F5485F9264F9
+FA926D732E2C267B0BE8CA98526F124F97EFDB86132C5EF16B103908172FC51F286FFE45FF253512
+E0033F037FF182BA536A9EB2DF2D1DB257D9C86C46E1B002FB32AC70CA9462E6EB48994752CEBCE3
+9F08ABD4F4B0889283E55500702185A841E328
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+cleartomark
+%%EndResource
+/NimbusMonL-Regu-iso1252 /NimbusMonL-Regu ISO1252Encoding psp_definefont
+/Times-Roman-iso1252 /Times-Roman ISO1252Encoding psp_definefont
+294 310 moveto
+0 0 0 setrgbcolor
+/NimbusMonL-Regu-iso1252 findfont 42 -42 matrix scale makefont setfont
+<4558504F52545F505953435249505453202B3D20534D4553485F6669786174696F6E5F68657861
+2E70792C20534D4553485F666C696768745F736B696E2E7079>
+show
+294 398 moveto
+<69666571202840574954484E455447454E402C79657329>
+show
+294 442 moveto
+<20204558504F52545F505953435249505453202B3D20534D4553485F626F785F74657472612E70
+792C20534D4553485F626F78325F74657472612E70792C205C202020>
+show
+294 486 moveto
+<20202020202020202020202020202020202020202020534D4553485F626F78335F74657472612E
+70792C20534D4553485F6669786174696F6E5F74657472612E70792C205C>
+show
+294 530 moveto
+<20202020202020202020202020202020202020202020534D4553485F506172746974696F6E315F
+74657472612E7079>
+show
+294 574 moveto
+<656E646966>
+show
+295 691 moveto
+/Symbol findfont 50 -50 matrix scale makefont setfont
+<B7>
+show
+370 691 moveto
+/Times-Roman-iso1252 findfont 50 -50 matrix scale makefont setfont
+<46696E616C656D656E74>
+show
+595 691 moveto
+<20>
+show
+607 691 moveto
+<3A>
+show
+294 797 moveto
+/NimbusMonL-Regu-iso1252 findfont 42 -42 matrix scale makefont setfont
+<2E2F6275696C645F636F6E666967757265>
+show
+294 841 moveto
+<636420534D4553485F4255494C44>
+show
+294 885 moveto
+<726D20636F6E6669672E2A>
+show
+294 929 moveto
+<53414C4F4D45325F524F4F542F534D4553485F5352432F636F6E6669677572652096776974682D
+6E657467656E3D6E657467656E5F696E7374616C6C6174696F6E5F70617468205C>
+show
+294 973 moveto
+<967072656669783D736D6573685F696E7374616C6C5F70617468>
+show
+294 1016 moveto
+<6D616B65>
+show
+220 1128 moveto
+/Times-Roman-iso1252 findfont 50 -50 matrix scale makefont setfont
+<6FF920736D6573685F696E7374616C6C5F7061746820657374206C61206469726563746F727920
+6427696E7374616C6C6174696F6E206475206D6F64756C6520534D4553482E>
+show
+280 277 1 308 rectfill
+2125 277 1 308 rectfill
+280 277 1846 1 rectfill
+280 584 1846 1 rectfill
+280 763 1 264 rectfill
+2125 763 1 264 rectfill
+280 763 1846 1 rectfill
+280 1026 1846 1 rectfill
+showpage
+grestore grestore
+%%PageTrailer
+
+%%Trailer
+%%Pages: 7
+%%EOF
--- /dev/null
+
+# -* Makefile *-
+#
+# Author : Patrick GOLDBRONN (CEA)
+# Date : 30/11/2001
+# $Header$
+#
+# source path
+top_srcdir=@top_srcdir@
+top_builddir=../..
+srcdir=@srcdir@
+VPATH=.:@srcdir@
+
+SUBDIRS= tui gui
+
+@COMMENCE@
+
+docs:
+ @@SETX@; for d in $(SUBDIRS); do \
+ (cd $$d && $(MAKE) $@) || exit 1; \
+ done; \
+ cp -f $(srcdir)/SMESH_index.html SMESH_index.html
+
+clean:
+ @@SETX@; for d in $(SUBDIRS); do \
+ (cd $$d && $(MAKE) $@) || exit 1; \
+ done
+
+distclean: clean
+ @@SETX@; for d in $(SUBDIRS); do \
+ (cd $$d && $(MAKE) $@) || exit 1; \
+ done
+
+install:
+ $(MAKE) docs
+ (cd tui && $(MAKE) install);
+ (cd gui && $(MAKE) install);
+ cp -f SMESH_index.html $(docdir)
+
+uninstall:
+ @@SETX@; for d in $(SUBDIRS); do \
+ (cd $$d && $(MAKE) $@) || exit 1; \
+ done; \
+ rm -fr $(docdir)/SMESH_index.html
--- /dev/null
+#######################################################################################
+# File : PluginMeshers.txt
+# Author : Julia DOROVSKIKH
+# Module : SMESH
+# $Header$
+#######################################################################################
+#
+# How to add your own mesher (as a set of hypotheses and algorithms) to the application
+#
+#######################################################################################
+
+1. Create mesher plugin package, e.g. MyMesher.
+
+2. Create XML file to describe all algorithms and hypotheses, provided by plugin package
+ (see SMESH_SRC/resources/SMESH_Meshers.xml for example).
+
+ <meshers-group name="MyName"
+ resources="MyResourceKey"
+ server-lib="libMyServerLib.so"
+ gui-lib="libMyClientLib.so">
+ <hypotheses>
+ <hypothesis type="MyHypType1"
+ label-id="My beautiful hypothesis name"
+ icon-id="my_hypo_1_icon.png"/>
+ </hypotheses>
+ <algorithms>
+ <algorithm type="MyAlgType1"
+ label-id="My beautiful algorithm name"
+ icon-id="my_algo_1_icon.png"/>
+ </algorithms>
+ </meshers-group>
+
+ Attributes of <meshers-group> tag:
+
+ - value of <name> attribute is used to collect hypotheses/algoritms in groups;
+ you can also use this attribute for short description of your mesher plugin
+
+ - value of <resources> attribute (MyResourceKey) is used to access resources
+ (messages and icons) from GUI (see paragraphs 4.2 and 5);
+ currently it should coincide with the name of plugin package; this limitation
+ will be eliminated in the further development.
+
+ - value of <server-lib> attribute describes the name of your mesher's
+ server plugin library (See paragraph 3)
+
+ - value of <gui-lib> attribute describes the name of your mesher's
+ client plugin library (See paragraph 4)
+
+ Attributes of <hypothesis/algorithm> tag:
+
+ - value of <type> attribute is an unique name of the hypothesis/algorithm
+
+ * It is a value of _name field of your hypothesis class
+ (see paragraph 3, implementation of constructor of
+ StdMeshers_LocalLength class: _name = "LocalLength")
+
+ * It is a key to each certain hypothesis class
+ (see paragraph 3, implementation of "GetHypothesisCreator()" method in StdMeshers_i.cxx)
+
+ * It is a key to each certain hypothesis GUI
+ (see paragraph 4, implementation of "StdMeshersGUI_HypothesisCreator::CreateHypothesis()"
+ and "StdMeshersGUI_HypothesisCreator::EditHypothesis()" methods in StdMeshersGUI.cxx)
+
+ * It is a key to each certain hypothesis icon in Object Browser
+ (see paragraph 4.2.1)
+
+ - value of <label-id> attribute is displayed in the GUI in the list
+ of available hypotheses/algorithms ("Create Hypothesis/Algorithm" dialog)
+
+ - value of <icon-id> attribute is a name of icon file, which is displayed in GUI
+ in the list of available hypotheses/algorithms ("Create Hypothesis/Algorithm" dialog)
+
+ Note: All attributes values are accessible in your GUI via HypothesisData class
+ (see paragraph 4.1)
+
+ Note: The environment variable SMESH_MeshersList contains the list of plugins names,
+ separated by colon (":") symbol, e.g.:
+
+ setenv SMESH_MeshersList StdMeshers:NETGENPlugin
+
+ Please, pay attention that StdMeshers should also be included into this environment variable,
+ if you want to use standard hypotheses/algorithms, provided with SMESH module.
+
+ The SALOME automatically locates XML files, searching them in the following directories:
+
+ ${<PLUGINNAME>_ROOT_DIR}/share/salome/resources
+ ${SALOME_<PluginName>Resources}
+ ${HOME}/.salome/resources
+ ${KERNEL_ROOT_DIR}/share/salome/resources
+
+ where <PluginName> is a name of each mesher plugin package
+
+3. Build server plugin library <libMyServerLib.so>.
+
+ 3.1. Define interface to your hypotheses and algorithms.
+
+ Example: SMESH_SRC/idl/SMESH_BasicHypothesis.idl
+ NETGENPLUGIN_SRC/src/NETGENPlugin_Algorithm.idl
+
+ 3.2. Implement functionality of your hypotheses and algorithms.
+ Inherit corresponding classes from SMESH.
+
+ Example: SMESH_SRC/src/StdMeshers/StdMeshers_*
+ NETGENPLUGIN_SRC/src/NETGENPlugin_NETGEN_3D
+
+ 3.3. Implement interface to your hypotheses and algorithms.
+ Inherit corresponding classes from SMESH_I.
+
+ Example: SMESH_SRC/src/StdMeshers_I/SMESH_*_i
+ NETGENPLUGIN_SRC/src/NETGENPlugin_NETGEN_3D_i
+
+ 3.4. Implement being exported method.
+
+ GenericHypothesisCreator_i* GetHypothesisCreator (const char* aHypType)
+
+ <aHypType> is a value of <type> attribute in the XML-description file
+
+ Example: SMESH_SRC/src/StdMeshers_I/StdMeshers_i.cxx
+ NETGENPLUGIN_SRC/src/NETGENPlugin_i.cxx
+
+4. Build client (GUI) plugin library <libMyClientLib.so>.
+ This step is required only if your hypotheses/algorithms need specific GUI for their construction.
+
+ 4.1. Implement the required GUI (e.g. construction dialog boxes).
+
+ Example: SMESH_SRC/src/StdMeshersGUI/StdMeshersGUI_*Dlg
+
+ Note: all data from XML-description files is accessible in your GUI via HypothesisData class
+ (mySMESHGUI->GetHypothesisData (aHypType),
+ see SMESHGUI_Hypotheses.h for HypothesisData definition)
+
+ 4.2. Provide icons and messages for your GUI.
+
+ 4.2.1. Implement resource files
+ MyResourceKey_icons.po and MyResourceKey_msg_en.po
+
+ Example: SMESH_SRC/src/StdMeshersGUI/StdMeshers_*.po
+ NETGENPLUGIN_SRC/src/NETGENPlugin_icons.po
+
+ Note: ICON_SMESH_TREE_HYPO_MyHypType1 is ID of icon for Object Browser
+ for hypothesis with type="MyHypType1".
+
+ ICON_SMESH_TREE_ALGO_MyAlgType1 is ID of icon for Object Browser
+ for algorithm with type="MyAlgType1".
+
+ See paragraph 2 for definition of MyResourceKey, MyHypType1, MyAlgType1.
+
+ 4.2.2. Define environment variable SALOME_<MyResourceKey>Resources to point to the
+ directory where resources are situated.
+
+ Example: setenv SALOME_StdMeshersResources ${SMESH_ROOT_DIR}/share/salome/resources
+
+ 4.3. Implement your Hypothesis Creator and being exported method
+
+ SMESHGUI_GenericHypothesisCreator* GetHypothesisCreator
+ (QString aHypType, QString aServerLibName, SMESHGUI* aSMESHGUI)
+
+ <aHypType> is to pass a value of <type> attribute in XML-description file;
+ <aServerLibName> is to pass a value of <server-lib> attribute in XML-description file.
+
+ Example: SMESH_SRC/src/StdMeshersGUI/StdMeshersGUI.cxx
+
+5. If your hypotheses/algorithms do not need specific GUI,
+ but you want to provide icons for object browser, see 4.2 paragrath
+
+6. Setup your SALOME environment.
+
+ 6.1. Add your plugin to the LD_LIBRARY_PATH, PYTHONPATH (and maybe PATH) environment variables, e.g.:
+
+ setenv PATH <path-to-my-plugin>/bin/salome:${PATH}
+ setenv LD_LIBRARY_PATH <path-to-my-plugin>/lib/salome:${LD_LIBRARY_PATH}
+ setenv PYTHONPATH <path-to-my-plugin>/lib/python2.2/site-packages/salome:${PYTHONPATH}
+
+ 6.2. Set mesher plugin resources environment variable (see 4.2.2 paragraph)
+
+Note: If you use runSalome.py script from KERNEL package to launch SALOME, you may not to set
+ environment variables, because this script sets them itself. All what you should do is
+ to add <plugin> section to your ${HOME}/.salome/salome.launch file for SMESH module section:
+
+ ...
+ <modules-list>
+ ...
+ <module name="SMESH">
+ <plugin name="MyMesher"/>
+ </module>
+ ...
+ </modules-list>
+ ...
\ No newline at end of file
--- /dev/null
+<!DOCTYPE doctype PUBLIC "-//w3c//dtd html 4.0 transitional//en">
+<html>
+<head>
+
+ <meta http-equiv="Content-Type"
+ content="text/html; charset=iso-8859-1">
+
+ <meta name="GENERATOR"
+ content="Mozilla/4.73 [en] (WinNT; I) [Netscape]">
+ <title>Mesh Module Documentation</title>
+</head>
+ <body bgcolor="#cccccc" text="#000000" link="#0000ee" alink="#0000ee"
+ vlink="#551a8b">
+
+<div align="center">
+<center>
+<center>
+ </center>
+
+<table width="96%" align="center">
+ <tbody>
+ <tr>
+ <td><a href="http://www.opencascade.com"><img
+ src="tui/SMESH/sources/logocorp.gif" border="0" height="46" width="122">
+ </a></td>
+ <td>
+
+ <div align="right"><a href="http://www.opencascade.org/SALOME/"><img
+ src="tui/SMESH/sources/application.gif" border="0" height="46" width="108">
+ </a></div>
+ </td>
+ </tr>
+
+ </tbody>
+</table>
+
+<div align="center">
+<center>
+<hr width="100%" size="2">
+<h1>Mesh MODULE Documentation</h1>
+ </center>
+ </div>
+
+<table width="96%">
+ <tbody>
+
+ </tbody>
+</table>
+ </center>
+
+<div align="center">
+<p> <img src="tui/SMESH/sources/Application-About.png"
+ alt="Application-About.png" width="30%" height="20%">
+ </p>
+ </div>
+
+<center>
+<table width="96%">
+ <tbody>
+
+ </tbody>
+</table>
+ <br>
+ <br>
+ <br>
+ </center>
+
+<address> </address>
+
+<center><big><a href="gui/SMESH/smesh.html">GUI Documentation</a></big></center>
+
+<address> </address>
+
+<center></center>
+
+<center><br>
+ </center>
+
+<address> </address>
+
+<center><big><a href="tui/SMESH/index.html">TUI Documentation</a></big></center>
+
+<address> </address>
+
+<center></center>
+
+<center><br>
+ <br>
+ </center>
+ </div>
+ <br>
+ <br>
+ <br>
+</body>
+</html>
--- /dev/null
+# Copyright (C) 2003 CEA/DEN, EDF R&D
+#
+#
+#
+# File : Makefile.in
+# Author : Vasily Rusyaev (Open Cascade NN)
+# Module : doc
+# $Header:
+
+top_srcdir=@top_srcdir@
+top_builddir=../../..
+srcdir=@srcdir@
+VPATH=.:@srcdir@
+
+@COMMENCE@
+
+docs:
+ cp -fr $(srcdir)/SMESH ./
+ -find $(PWD) -name CVS -exec rm -rf {} \;
+
+clean:
+ rm -fr `ls | grep -v "Makefile"`
+
+distclean: clean
+ rm -fr SMESH
+
+install:
+ mkdir -p $(docdir)/gui
+ cp -rf SMESH $(docdir)/gui
+ -find $(PWD) -name CVS -exec rm -rf {} \;
+
+uninstall:
+ rm -rf $(docdir)/gui/SMESH
top_srcdir=@top_srcdir@
top_builddir=..
srcdir=@srcdir@
-VPATH=.:$(srcdir):${KERNEL_ROOT_DIR}/idl/salome:${GEOM_ROOT_DIR}/idl/salome:${MED_ROOT_DIR}/idl/salome
+VPATH=.:${KERNEL_ROOT_DIR}/idl/salome:${GEOM_ROOT_DIR}/idl/salome:${MED_ROOT_DIR}/idl/salome
@COMMENCE@
SMESH_Gen.idl \
SMESH_Mesh.idl \
SMESH_Hypothesis.idl \
- SMESH_BasicHypothesis.idl
+ SMESH_BasicHypothesis.idl \
+ SMESH_Filter.idl \
+ SMESH_Group.idl
PY_CLIENT_IDL = $(IDL_FILES)
# we copy all idl file in $(top_builddir)/idl
-inc: $(IDL_FILES:%=$(top_builddir)/idl/%)
+inc: $(top_builddir)/idl/salome $(IDL_FILES:%=$(top_builddir)/idl/salome/%)
-$(IDL_FILES:%=$(top_builddir)/idl/%):$(top_builddir)/idl/%:%
+$(top_builddir)/idl/salome:
+ mkdir $@
+
+$(IDL_FILES:%=$(top_builddir)/idl/salome/%):$(IDL_FILES:%=$(top_srcdir)/idl/%)
# $(CP) $< $@
- cp -f $< $@
+ cp -f $^ $(top_builddir)/idl/salome
lib: pyidl
$(PYTHON_BUILD_SITE):
$(INSTALL) -d $@
-$(PYTHON_BUILD_SITE)/%_idl.py: %.idl
+$(PYTHON_BUILD_SITE)/%_idl.py: $(top_builddir)/idl/salome/%.idl
$(OMNIORB_IDL) $(OMNIORB_IDLPYFLAGS) -C$(PYTHON_BUILD_SITE) $<
install: install-pyidl install-idl
# create directory $(idldir) and copy idl files into it
-install-idl: $(IDL_FILES)
+install-idl: $(IDL_FILES:%=$(top_builddir)/idl/salome/%)
$(INSTALL) -d $(idldir)
$(INSTALL_DATA) $^ $(idldir)
-install-pyidl: $(IDL_FILES)
+install-pyidl: $(IDL_FILES:%=$(top_builddir)/idl/salome/%)
$(INSTALL) -d $(PYTHON_SITE_INSTALL)
@for file in $^ dummy; do \
if [ $$file != "dummy" ]; then \
distclean:
-$(RM) *.py
- -$(RM) $(IDL_FILES:%=$(top_builddir)/idl/%)
+ -$(RM) $(IDL_FILES:%=$(top_builddir)/idl/salome/%)
-$(RM) Makefile
#include "SMESH_Hypothesis.idl"
-module SMESH
+/*!
+ * StdMeshers: interfaces to standard hypotheses and algorithms
+ */
+module StdMeshers
{
- interface SMESH_LocalLength : SMESH_Hypothesis
+ /*!
+ * StdMeshers_LocalLength: interface of "Average length" hypothesis
+ */
+ interface StdMeshers_LocalLength : SMESH::SMESH_Hypothesis
{
+ /*!
+ * Sets <length> parameter value
+ */
void SetLength(in double length)
raises (SALOME::SALOME_Exception);
+
+ /*!
+ * Returns <length> parameter value
+ */
double GetLength();
};
- interface SMESH_NumberOfSegments : SMESH_Hypothesis
+ /*!
+ * StdMeshers_NumberOfSegments: interface of "Nb. Segments" hypothesis
+ */
+ interface StdMeshers_NumberOfSegments : SMESH::SMESH_Hypothesis
{
+ /*!
+ * Sets <number of segments> parameter value
+ */
void SetNumberOfSegments(in long segmentsNumber)
raises (SALOME::SALOME_Exception);
+
+ /*!
+ * Returns <number of segments> parameter value
+ */
long GetNumberOfSegments();
+
+ /*!
+ * Sets <scale factor> parameter value
+ */
void SetScaleFactor(in double scaleFactor)
raises (SALOME::SALOME_Exception);
+
+ /*!
+ * Returns <scale factor> parameter value
+ */
double GetScaleFactor();
};
- interface SMESH_MaxElementArea : SMESH_Hypothesis
+ /*!
+ * StdMeshers_MaxElementArea: interface of "Max. Triangle Area" hypothesis
+ */
+ interface StdMeshers_MaxElementArea : SMESH::SMESH_Hypothesis
{
+ /*!
+ * Sets <maximum element area> parameter value
+ */
void SetMaxElementArea(in double area)
raises (SALOME::SALOME_Exception);
+
+ /*!
+ * Returns <maximum element area> parameter value
+ */
double GetMaxElementArea();
};
- interface SMESH_LengthFromEdges : SMESH_Hypothesis
+ /*!
+ * StdMeshers_LengthFromEdges: interface of "Length From Edges (2D Hyp. for Triangulator)" hypothesis
+ */
+ interface StdMeshers_LengthFromEdges : SMESH::SMESH_Hypothesis
{
+ /*!
+ * Sets <mode> parameter value
+ */
void SetMode(in long mode)
raises (SALOME::SALOME_Exception);
+
+ /*!
+ * Returns <mode> parameter value
+ */
long GetMode();
};
- interface SMESH_MaxElementVolume : SMESH_Hypothesis
+ /*!
+ * StdMeshers_MaxElementVolume: interface of "Max. Hexahedron or Tetrahedron Volume" hypothesis
+ */
+ interface StdMeshers_MaxElementVolume : SMESH::SMESH_Hypothesis
{
+ /*!
+ * Sets <maximum element volume> parameter value
+ */
void SetMaxElementVolume(in double volume)
raises (SALOME::SALOME_Exception);
+
+ /*!
+ * Returns <maximum element volume> parameter value
+ */
double GetMaxElementVolume();
};
- interface SMESH_Regular_1D : SMESH_1D_Algo
+ /*!
+ * StdMeshers_NotConformAllowed: interface of "Not Conform Mesh Allowed" hypothesis.
+ * Presence of this hypothesis permits to algorithm generation of not conform mesh.
+ */
+ interface StdMeshers_NotConformAllowed : SMESH::SMESH_Hypothesis
{
};
- interface SMESH_MEFISTO_2D : SMESH_2D_Algo
+ /*!
+ * StdMeshers_Regular_1D: interface of "Wire discretisation" algorithm
+ */
+ interface StdMeshers_Regular_1D : SMESH::SMESH_1D_Algo
{
};
- interface SMESH_Quadrangle_2D : SMESH_2D_Algo
+ /*!
+ * StdMeshers_MEFISTO_2D: interface of "Triangle (Mefisto)" algorithm
+ */
+ interface StdMeshers_MEFISTO_2D : SMESH::SMESH_2D_Algo
{
};
- interface SMESH_Hexa_3D : SMESH_3D_Algo
+ /*!
+ * StdMeshers_Quadrangle_2D: interface of "Quadrangle (Mapping)" algorithm
+ */
+ interface StdMeshers_Quadrangle_2D : SMESH::SMESH_2D_Algo
{
};
-#ifdef HAVE_NETGEN
- interface SMESH_NETGEN_3D : SMESH_3D_Algo
+ /*!
+ * StdMeshers_Hexa_3D: interface of "Hexahedron (i,j,k)" algorithm
+ */
+ interface StdMeshers_Hexa_3D : SMESH::SMESH_3D_Algo
{
};
-#endif
};
--- /dev/null
+// Copyright (C) 2003 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,\r
+// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS \r
+// \r
+// This library is free software; you can redistribute it and/or \r
+// modify it under the terms of the GNU Lesser General Public \r
+// License as published by the Free Software Foundation; either \r
+// version 2.1 of the License. \r
+// \r
+// This library is distributed in the hope that it will be useful, \r
+// but WITHOUT ANY WARRANTY; without even the implied warranty of \r
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU \r
+// Lesser General Public License for more details. \r
+// \r
+// You should have received a copy of the GNU Lesser General Public \r
+// License along with this library; if not, write to the Free Software \r
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA \r
+// \r
+// See http://www.opencascade.org/SALOME/ or email : webmaster.salome@opencascade.org \r
+//\r
+//\r
+//\r
+// File : SMESH_Filter.idl\r
+// Author : Alexey Petrov, OCC\r
+\r
+#ifndef _SMESH_FILTER_IDL_\r
+#define _SMESH_FILTER_IDL_\r
+\r
+#include "SALOME_Exception.idl"\r
+#include "SALOME_GenericObj.idl"\r
+#include "SMESH_Mesh.idl"\r
+\r
+module SMESH{\r
+\r
+ interface Functor: SALOME::GenericObj{\r
+ void SetMesh(in SMESH_Mesh theMesh);\r
+ };\r
+\r
+ interface NumericalFunctor: Functor{\r
+ double GetValue(in long theElementId);\r
+ };\r
+\r
+ interface MinimumAngle: NumericalFunctor{};\r
+ interface AspectRatio: NumericalFunctor{};\r
+ interface Warping: NumericalFunctor{};\r
+ interface Taper: NumericalFunctor{};\r
+ interface Skew: NumericalFunctor{};\r
+ interface Area: NumericalFunctor{};\r
+ interface Length: NumericalFunctor{};\r
+ interface MultiConnection: NumericalFunctor{};\r
+\r
+ interface Predicate: Functor{\r
+ boolean IsSatisfy(in long thEntityId);\r
+ };\r
+\r
+ interface FreeBorders: Predicate{};\r
+\r
+ interface Comparator: Predicate{\r
+ void SetMargin(in double theValue);\r
+ void SetNumFunctor(in NumericalFunctor theFunct);\r
+ };\r
+\r
+ interface LessThan: Comparator{};\r
+ interface MoreThan: Comparator{};\r
+ interface EqualTo: Comparator{\r
+ void SetTolerance(in double theTolerance );\r
+ };\r
+\r
+ interface Logical: Predicate{};\r
+\r
+ interface LogicalNOT: Logical{\r
+ void SetPredicate(in Predicate thePredicate);\r
+ };\r
+\r
+ interface LogicalBinary: Logical{\r
+ void SetPredicate1(in Predicate thePredicate);\r
+ void SetPredicate2(in Predicate thePredicate);\r
+ };\r
+ \r
+ interface LogicalAND: LogicalBinary{};\r
+ interface LogicalOR: LogicalBinary{};\r
+ interface Filter: SALOME::GenericObj{\r
+ void SetPredicate( in Predicate thePredicate );\r
+ long_array GetElementsId( in SMESH_Mesh theMesh );\r
+ };\r
+\r
+ interface FilterManager: SALOME::GenericObj{\r
+ MinimumAngle CreateMinimumAngle();\r
+ AspectRatio CreateAspectRatio();\r
+ Warping CreateWarping();\r
+ Taper CreateTaper();\r
+ Skew CreateSkew();\r
+ Area CreateArea();\r
+ Length CreateLength();\r
+ MultiConnection CreateMultiConnection();\r
+\r
+ FreeBorders CreateFreeBorders();\r
+\r
+ LessThan CreateLessThan();\r
+ MoreThan CreateMoreThan();\r
+ EqualTo CreateEqualTo();\r
+ \r
+ LogicalNOT CreateLogicalNOT();\r
+ LogicalAND CreateLogicalAND();\r
+ LogicalOR CreateLogicalOR();\r
+ Filter CreateFilter();\r
+ };\r
+ \r
+};\r
+\r
+#endif\r
module SMESH
{
typedef sequence<GEOM::GEOM_Shape> shape_array;
+ typedef sequence<SMESH_Mesh> mesh_array;
+
+ interface FilterManager;
interface SMESH_Gen : Engines::Component, SALOMEDS::Driver
{
+
+ FilterManager CreateFilterManager();
+
/*!
- * Create an hypothesis that can be shared by differents parts of the mesh.
+ Set the current study
+ */
+ void SetCurrentStudy( in SALOMEDS::Study theStudy );
+
+ /*!
+ Get the current study
+ */
+ SALOMEDS::Study GetCurrentStudy();
+
+ /*!
+ * Create a hypothesis that can be shared by differents parts of the mesh.
* An hypothesis is either:
* - a method used to generate or modify a part of the mesh (algorithm).
* - a parameter or a law used by an algorithm.
* Algorithms are 1D, 2D or 3D.
*/
- SMESH_Hypothesis CreateHypothesis( in string anHyp,
- in long studyId)
- raises (SALOME::SALOME_Exception);
+ SMESH_Hypothesis CreateHypothesis( in string theHypName,
+ in string theLibName )
+ raises ( SALOME::SALOME_Exception );
/*!
* Create a Mesh object, given a geometry shape.
* of TopoDS_Shapes and bind CORBA references of shape & subshapes
* with TopoDS_Shapes
*/
- SMESH_Mesh Init(in GEOM::GEOM_Gen geomEngine,
- in long studyId,
- in GEOM::GEOM_Shape aShape)
- raises (SALOME::SALOME_Exception);
+ SMESH_Mesh CreateMesh( in GEOM::GEOM_Shape theShape )
+ raises ( SALOME::SALOME_Exception );
+
+ /*!
+ * Create Mesh object(s) importing data from given MED file
+ */
+ mesh_array CreateMeshesFromMED( in string theFileName,
+ out SMESH::DriverMED_ReadStatus theStatus )
+ raises ( SALOME::SALOME_Exception );
/*!
* Create a Mesh object, without a geometry shape reference
*/
-// SMESH_Mesh NewEmpty(in GEOM::GEOM_Gen geomEngine,
-// in long studyId)
-// raises (SALOME::SALOME_Exception);
+// SMESH_Mesh NewEmpty()
+// raises ( SALOME::SALOME_Exception );
/*!
* Mesh a subShape.
* First, verify list of hypothesis associated with the subShape,
* return NOK if hypothesis are not sufficient
*/
- boolean Compute(in SMESH_Mesh aMesh, in GEOM::GEOM_Shape aSubShape)
- raises (SALOME::SALOME_Exception);
+ boolean Compute( in SMESH_Mesh theMesh,
+ in GEOM::GEOM_Shape theSubShape )
+ raises ( SALOME::SALOME_Exception );
/*!
*
*/
- boolean IsReadyToCompute(in SMESH_Mesh aMesh, in GEOM::GEOM_Shape aSubShape)
- raises (SALOME::SALOME_Exception);
+ boolean IsReadyToCompute( in SMESH_Mesh theMesh,
+ in GEOM::GEOM_Shape theSubShape )
+ raises ( SALOME::SALOME_Exception );
/*!
*
*/
- long_array GetSubShapesId(in GEOM::GEOM_Gen geomEngine,
- in long studyId,
- in GEOM::GEOM_Shape mainShape,
- in shape_array listOfSubShape)
- raises (SALOME::SALOME_Exception);
+ long_array GetSubShapesId( in GEOM::GEOM_Shape theMainShape,
+ in shape_array theListOfSubShape )
+ raises ( SALOME::SALOME_Exception );
/*!
*
*/
- // long_array GetSubMeshesState(in GEOM::GEOM_Gen geomEngine,
- // in long studyId,
- // in shape_array listOfSubShape)
- // raises (SALOME::SALOME_Exception);
+ // long_array GetSubMeshesState( in shape_array theListOfSubShape )
+ // raises ( SALOME::SALOME_Exception );
- /**
- * Import a mesh from a file.
- * @param fileName file name to be imported.
- * @param fileType Currently it could be either "DAT", "UNV" or "MED".
- * @param studyId The id of the current study.
- */
- SMESH_Mesh Import(in long studyId, in string fileName, in string fileType);
+
};
};
--- /dev/null
+// Copyright (C) 2004 CEA
+//
+// This library 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.
+//
+// This library 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 this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+//
+// See http://www.salome-platform.org or email : webmaster.salome@opencascade.org
+//
+//
+//
+// File : SMESH_Group.idl
+// Author : Sergey ANIKIN, OCC
+// $Header$
+
+#ifndef _SMESH_GROUP_IDL_
+#define _SMESH_GROUP_IDL_
+
+#include "SALOME_Exception.idl"
+#include "SALOME_GenericObj.idl"
+
+#include "SMESH_Mesh.idl"
+
+module SMESH
+{
+ /*!
+ * SMESH_Group: interface of group object
+ */
+ interface SMESH_Group : SALOME::GenericObj
+ {
+ /*!
+ * Sets group name
+ */
+ void SetName( in string name );
+
+ /*!
+ * Returns group name
+ */
+ string GetName();
+
+ /*!
+ * Returns group type (type of elements in the group)
+ */
+ ElementType GetType();
+
+ /*!
+ * Returns the number of elements in the group
+ */
+ long Size();
+
+ /*!
+ * Returns true if the group does not contain any elements
+ */
+ boolean IsEmpty();
+
+ /*!
+ * Clears the group's contents
+ */
+ void Clear();
+
+ /*!
+ * returns true if the group contains an element with ID == <elem_id>
+ */
+ boolean Contains( in long elem_id );
+
+ /*!
+ * Adds elements to the group
+ */
+ long Add( in long_array elem_ids );
+
+ /*!
+ * Returns ID of an element at position <elem_index>
+ */
+ long GetID( in long elem_index );
+
+ /*!
+ * Returns a sequence of all element IDs in the group
+ */
+ long_array GetListOfID();
+
+ /*!
+ * Removes elements from the group
+ */
+ long Remove( in long_array elem_ids );
+
+ /*!
+ * Returns the mesh object this group belongs to
+ */
+ SMESH_Mesh GetMesh();
+ };
+};
+
+
+#endif
#define _SMESH_HYPOTHESIS_IDL_
#include "SALOME_Exception.idl"
+#include "SALOME_GenericObj.idl"
module SMESH
{
- interface SMESH_Hypothesis;
-
- typedef sequence<SMESH_Hypothesis> ListOfHypothesis;
- typedef sequence<string> ListOfHypothesisName;
-
- interface SMESH_Hypothesis
+ interface SMESH_Hypothesis : SALOME::GenericObj
{
/*!
* Get the Hypothesis typeName
*/
string GetName();
+ /*!
+ * Get the Hypothesis plugin library Name
+ */
+ string GetLibName();
+
/*!
* Get the internal Id
*/
long GetId();
- };
+ };
+
+ typedef sequence<string> ListOfHypothesisName;
interface SMESH_Algo : SMESH_Hypothesis
{
#define _SMESH_MESH_IDL_
#include "SALOME_Exception.idl"
-#include "SMESH_Hypothesis.idl"
+//#include "SMESH_Hypothesis.idl"
+
+#include "SALOME_GenericObj.idl"
+//#include "GEOM_Shape.idl"
+//#include "MED.idl"
+
+module GEOM
+{
+ interface GEOM_Shape;
+};
+
+
+module SALOME_MED
+{
+ interface MESH;
+ interface FAMILY;
+};
-#include "GEOM_Shape.idl"
-#include "MED.idl"
module SMESH
{
+ interface SMESH_Hypothesis;
+ typedef sequence<SMESH_Hypothesis> ListOfHypothesis;
+
typedef sequence<double> double_array ;
typedef sequence<long> long_array ;
typedef sequence<string> string_array ;
ADD_PRISM,
ADD_HEXAHEDRON,
REMOVE_NODE,
- REMOVE_ELEMENT,
- REMOVE_ALL
+ REMOVE_ELEMENT
};
struct log_block
double_array coords;
long_array indexes;
};
+
+ /*!
+ * Enumeration for element type, like in SMDS
+ */
+ enum ElementType
+ {
+ ALL,
+ NODE,
+ EDGE,
+ FACE,
+ VOLUME
+ };
+
+ /*!
+ * Enumeration for hypothesis status (used by AddHypothesis() and RemoveHypothesis() methods)
+ */
+ enum Hypothesis_Status // in the order of severity
+ {
+ HYP_OK,
+ HYP_MISSING, // algo misses a hypothesis
+ HYP_CONCURENT, // several applicable hypotheses
+ HYP_BAD_PARAMETER,// hypothesis has a bad parameter value
+ HYP_UNKNOWN_FATAL,// --- all statuses below should be considered as fatal
+ // for Add/RemoveHypothesis operations
+ HYP_INCOMPATIBLE, // hypothesis does not fit algo
+ HYP_NOTCONFORM, // not conform mesh is produced appling a hypothesis
+ HYP_ALREADY_EXIST,// such hypothesis already exist
+ HYP_BAD_DIM // bad dimension
+ };
+
+ /*!
+ * Enumeration for DriverMED read status (used by ImportMEDFile() method)
+ */
+ enum DriverMED_ReadStatus // in the order of severity
+ {
+ DRS_OK,
+ DRS_EMPTY, // a MED file contains no mesh with the given name
+ DRS_WARN_RENUMBER, // a MED file has overlapped ranges of element numbers,
+ // so the numbers from the file are ignored
+ DRS_WARN_SKIP_ELEM, // some elements were skipped due to incorrect file data
+ DRS_FAIL // general failure (exception etc.)
+ };
+
typedef sequence<log_block> log_array;
+ interface SMESH_Group;
interface SMESH_subMesh;
interface SMESH_MeshEditor;
- interface SMESH_Mesh
+ interface SMESH_Mesh : SALOME::GenericObj
{
/*!
* Associate a Shape to a Mesh created with NewEmpty
* SubMesh will be used instead of SubShape in a next idl version to
* adress a specific subMesh...
*/
- SMESH_subMesh GetElementsOnShape(in GEOM::GEOM_Shape aSubShape)
+ SMESH_subMesh GetSubMesh(in GEOM::GEOM_Shape aSubShape, in string name)
raises (SALOME::SALOME_Exception);
/*!
// SMESH_subMesh NewEmpty()
// raises (SALOME::SALOME_Exception);
+ /*!
+ * Remove a submesh
+ */
+ void RemoveSubMesh(in SMESH_subMesh aSubMesh)
+ raises (SALOME::SALOME_Exception);
+
+ /*!
+ * Create a group
+ */
+ SMESH_Group CreateGroup( in ElementType elem_type,
+ in string name )
+ raises (SALOME::SALOME_Exception);
+
+ /*!
+ * Remove a group
+ */
+ void RemoveGroup(in SMESH_Group aGroup)
+ raises (SALOME::SALOME_Exception);
+
/*!
* Add hypothesis to the mesh, under a particular subShape
* (or the main shape itself)
* (or one previous hypothesis on the subShape)
* raises exception if hypothesis has not been created
*/
- boolean AddHypothesis(in GEOM::GEOM_Shape aSubShape, in SMESH_Hypothesis anHyp)
+ Hypothesis_Status AddHypothesis(in GEOM::GEOM_Shape aSubShape,
+ in SMESH_Hypothesis anHyp)
raises (SALOME::SALOME_Exception);
// boolean AddHypothesis(in SMESH_subMesh aSubMesh, in SMESH_Hypothesis anHyp)
// raises (SALOME::SALOME_Exception);
/*!
* Remove an hypothesis previouly added with AddHypothesis.
*/
- boolean RemoveHypothesis(in GEOM::GEOM_Shape aSubShape,
- in SMESH_Hypothesis anHyp)
+ Hypothesis_Status RemoveHypothesis(in GEOM::GEOM_Shape aSubShape,
+ in SMESH_Hypothesis anHyp)
raises (SALOME::SALOME_Exception);
// boolean RemoveHypothesis(in SMESH_subMesh aSubMesh,
// in SMESH_Hypothesis anHyp)
raises (SALOME::SALOME_Exception);
/*!
- * Export mesh to a file
- * @param fileName file name where to export the file
- * @param fileType Currently it could be either "DAT", "UNV" or "MED".
+ * Export Mesh with DAT and MED Formats
*/
- void Export( in string fileName, in string fileType )
+ void ExportDAT( in string file )
+ raises (SALOME::SALOME_Exception);
+ void ExportMED( in string file, in boolean auto_groups )
+ raises (SALOME::SALOME_Exception);
+ void ExportUNV( in string file )
raises (SALOME::SALOME_Exception);
/*!
long NbHexas()
raises (SALOME::SALOME_Exception);
+ long NbPyramids()
+ raises (SALOME::SALOME_Exception);
+
+ long NbPrisms()
+ raises (SALOME::SALOME_Exception);
+
long NbSubMesh()
raises (SALOME::SALOME_Exception);
+
+ string Dump();
};
- interface SMESH_subMesh
+ interface SMESH_subMesh : SALOME::GenericObj
{
/*!
*
long_array GetElementsId()
raises (SALOME::SALOME_Exception);
+ /*!
+ *
+ */
+ long_array GetElementsByType( in ElementType theType )
+ raises (SALOME::SALOME_Exception);
+
/*!
*
*/
--- /dev/null
+// Copyright (C) 2003 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
+// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
+//
+// This library 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.
+//
+// This library 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 this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+//
+// See http://www.opencascade.org/SALOME/ or email : webmaster.salome@opencascade.org
+//
+//
+//
+// File : SMESH_NetgenAlgorithm.idl
+// Author : Julia DOROVSKIKH
+// $Header$
+
+#ifndef _SMESH_NETGENALGORITHM_IDL_
+#define _SMESH_NETGENALGORITHM_IDL_
+
+#include "SMESH_Hypothesis.idl"
+
+/*!
+ * NETGENPlugin: interfaces to NETGEN related hypotheses and algorithms
+ */
+module NETGENPlugin
+{
+ /*!
+ * NETGENPlugin_NETGEN_3D: interface of "Tetrahedron (Netgen)" algorithm
+ */
+ interface NETGENPlugin_NETGEN_3D : SMESH::SMESH_3D_Algo
+ {
+ };
+
+};
+
+#endif
--- /dev/null
+language=en
+resources=StdMeshers:NETGENPlugin
\ No newline at end of file
--- /dev/null
+<?xml version='1.0' encoding='us-ascii'?>
+<!DOCTYPE meshers PUBLIC "" "desktop.dtd">
+
+<!-- GUI customization for MESH component -->
+
+<meshers>
+
+<meshers-group name="Standard Meshers"
+ resources="StdMeshers"
+ server-lib="libStdMeshersEngine.so"
+ gui-lib="libStdMeshersGUI.so">
+ <hypotheses>
+
+ <hypothesis type="LocalLength"
+ label-id="Average length"
+ icon-id="mesh_hypo_length.png"/>
+
+ <hypothesis type="LengthFromEdges"
+ label-id="Length From Edges (2D Hyp. for Triangulator)"
+ icon-id="mesh_hypo_length.png"/>
+
+ <hypothesis type="NumberOfSegments"
+ label-id="Nb. Segments"
+ icon-id="mesh_hypo_segment.png"/>
+
+ <hypothesis type="MaxElementArea"
+ label-id="Max. Triangle Area"
+ icon-id="mesh_hypo_area.png"/>
+
+ <hypothesis type="MaxElementVolume"
+ label-id="Max. Hexahedron or Tetrahedron Volume"
+ icon-id="mesh_hypo_volume.png"/>
+
+ <hypothesis type="NotConformAllowed"
+ label-id="Not Conform Mesh Allowed"
+ icon-id="mesh_hypo_length.png"/>
+ </hypotheses>
+
+ <algorithms>
+
+ <algorithm type="Regular_1D"
+ label-id="Wire discretisation"
+ icon-id="mesh_algo_regular.png"/>
+
+ <algorithm type="MEFISTO_2D"
+ label-id="Triangle (Mefisto)"
+ icon-id="mesh_algo_mefisto.png"/>
+
+ <algorithm type="Quadrangle_2D"
+ label-id="Quadrangle (Mapping)"
+ icon-id="mesh_algo_quad.png"/>
+
+ <algorithm type="Hexa_3D"
+ label-id="Hexahedron (i,j,k)"
+ icon-id="mesh_algo_hexa.png"/>
+ </algorithms>
+</meshers-group>
+
+<meshers-group name="Your Meshers Group"
+ resources=""
+ server-lib=""
+ gui-lib="">
+ <hypotheses>
+
+ <hypothesis type=""
+ label-id=""
+ icon-id=""/>
+ </hypotheses>
+
+ <algorithms>
+
+ <algorithm type=""
+ label-id=""
+ icon-id=""/>
+ </algorithms>
+</meshers-group>
+
+</meshers>
--- /dev/null
+<?xml version='1.0' encoding='us-ascii'?>
+<!DOCTYPE meshers PUBLIC "" "desktop.dtd">
+
+<!-- GUI customization for MESH component -->
+
+<meshers>
+
+<meshers-group name="Standard Meshers"
+ resources="StdMeshers"
+ server-lib="libStdMeshersEngine.so"
+ gui-lib="libStdMeshersGUI.so">
+ <hypotheses>
+
+ <hypothesis type="LocalLength"
+ label-id="Average length"
+ icon-id="mesh_hypo_length.png"/>
+
+ <hypothesis type="LengthFromEdges"
+ label-id="Length From Edges (2D Hyp. for Triangulator)"
+ icon-id="mesh_hypo_length.png"/>
+
+ <hypothesis type="NumberOfSegments"
+ label-id="Nb. Segments"
+ icon-id="mesh_hypo_segment.png"/>
+
+ <hypothesis type="MaxElementArea"
+ label-id="Max. Triangle Area"
+ icon-id="mesh_hypo_area.png"/>
+
+ <hypothesis type="MaxElementVolume"
+ label-id="Max. Hexahedron or Tetrahedron Volume"
+ icon-id="mesh_hypo_volume.png"/>
+
+ <hypothesis type="NotConformAllowed"
+ label-id="Not Conform Mesh Allowed"
+ icon-id="mesh_hypo_length.png"/>
+ </hypotheses>
+
+ <algorithms>
+
+ <algorithm type="Regular_1D"
+ label-id="Wire discretisation"
+ icon-id="mesh_algo_regular.png"/>
+
+ <algorithm type="MEFISTO_2D"
+ label-id="Triangle (Mefisto)"
+ icon-id="mesh_algo_mefisto.png"/>
+
+ <algorithm type="Quadrangle_2D"
+ label-id="Quadrangle (Mapping)"
+ icon-id="mesh_algo_quad.png"/>
+
+ <algorithm type="Hexa_3D"
+ label-id="Hexahedron (i,j,k)"
+ icon-id="mesh_algo_hexa.png"/>
+ </algorithms>
+</meshers-group>
+
+<meshers-group name="NETGEN"
+ resources="NETGENPlugin"
+ server-lib="libNETGENEngine.so"
+ gui-lib="">
+ <algorithms>
+ <algorithm type="NETGEN_3D"
+ label-id="Tetrahedron (Netgen)"
+ icon-id="mesh_algo_tetra.png"/>
+ </algorithms>
+</meshers-group>
+
+<meshers-group name="Your Meshers Group"
+ resources=""
+ server-lib=""
+ gui-lib="">
+ <hypotheses>
+
+ <hypothesis type=""
+ label-id=""
+ icon-id=""/>
+ </hypotheses>
+
+ <algorithms>
+
+ <algorithm type=""
+ label-id=""
+ icon-id=""/>
+ </algorithms>
+</meshers-group>
+
+</meshers>
<submenu label-id="Import" item-id="11" pos-id="8">
<popup-item item-id="111" pos-id="" label-id="DAT file" icon-id="" tooltip-id="" accel-id="Ctrl+B" toggle-id="" execute-action=""/>
<popup-item item-id="112" pos-id="" label-id="UNV File" icon-id="" tooltip-id="" accel-id="Ctrl+I" toggle-id="" execute-action=""/>
- <popup-item item-id="113" pos-id="" label-id="MED File" icon-id="" tooltip-id="" accel-id="" toggle-id="" execute-action=""/>
+ <popup-item item-id="113" pos-id="" label-id="MED File" icon-id="" tooltip-id="" accel-id="Ctrl+M" toggle-id="" execute-action=""/>
</submenu>
<endsubmenu />
<submenu label-id="Export" item-id="12" pos-id="9">
<!-- ************************** Hypothesis (menubar) ************************************ -->
<menu-item label-id="Hypotheses" item-id="50" pos-id="3">
- <popup-item item-id="5030" pos-id="" label-id="Average length" icon-id="mesh_hypo_length.png" tooltip-id="" accel-id="" toggle-id="" execute-action=""/>
- <popup-item item-id="5031" pos-id="" label-id="Nb. Segments" icon-id="mesh_hypo_segment.png" tooltip-id="" accel-id="" toggle-id="" execute-action=""/>
- <popup-item item-id="5032" pos-id="" label-id="Max. Triangle Area" icon-id="mesh_hypo_area.png" tooltip-id="" accel-id="" toggle-id="" execute-action=""/>
- <popup-item item-id="5033" pos-id="" label-id="Max. Hexahedron or Tetrahedron Volume" icon-id="mesh_hypo_volume.png" tooltip-id="" accel-id="" toggle-id="" execute-action=""/>
- <popup-item item-id="5034" pos-id="" label-id="Length From Edges (2D Hyp. for Triangulator)" icon-id="mesh_hypo_length.png" tooltip-id="" accel-id="" toggle-id="" execute-action=""/>
- <separator pos-id=""/>
- <popup-item item-id="5000" pos-id="" label-id="Wire discretisation" icon-id="mesh_algo_regular.png" tooltip-id="" accel-id="" toggle-id="" execute-action=""/>
- <popup-item item-id="5010" pos-id="" label-id="Triangle (Mefisto)" icon-id="mesh_algo_mefisto.png" tooltip-id="" accel-id="" toggle-id="" execute-action=""/>
- <popup-item item-id="5011" pos-id="" label-id="Quadrangle (Mapping)" icon-id="mesh_algo_quad.png" tooltip-id="" accel-id="" toggle-id="" execute-action=""/>
- <popup-item item-id="5020" pos-id="" label-id="Hexahedron (i,j,k)" icon-id="mesh_algo_hexa.png" tooltip-id="" accel-id="" toggle-id="" execute-action=""/>
- <popup-item item-id="5021" pos-id="" label-id="Tetrahedron (Netgen)" icon-id="mesh_algo_tetra.png" tooltip-id="" accel-id="" toggle-id="" execute-action=""/>
+ <popup-item item-id="5000" pos-id="" label-id="Create Hypotheses" icon-id="mesh_hypo_length.png" tooltip-id="" accel-id="" toggle-id="" execute-action=""/>
+ <popup-item item-id="5010" pos-id="" label-id="Create Algorithms" icon-id="mesh_algo_mefisto.png" tooltip-id="" accel-id="" toggle-id="" execute-action=""/>
</menu-item>
<!-- ************************** Mesh (menubar) ************************************ -->
<menu-item label-id="Mesh" item-id="70" pos-id="4">
- <popup-item item-id="703" pos-id="" label-id="Global Hyp." icon-id="mesh_init.png" tooltip-id="" accel-id="" toggle-id="" execute-action=""/>
- <popup-item item-id="702" pos-id="" label-id="Local Hyp." icon-id="mesh_add_sub.png" tooltip-id="" accel-id="" toggle-id="" execute-action=""/>
- <popup-item item-id="704" pos-id="" label-id="Edit Hyp." icon-id="mesh_edit.png" tooltip-id="" accel-id="" toggle-id="" execute-action=""/>
+ <popup-item item-id="703" pos-id="" label-id="Global Hypothesis" icon-id="mesh_init.png" tooltip-id="" accel-id="" toggle-id="" execute-action=""/>
+ <popup-item item-id="702" pos-id="" label-id="Local Hypothesis" icon-id="mesh_add_sub.png" tooltip-id="" accel-id="" toggle-id="" execute-action=""/>
+ <popup-item item-id="704" pos-id="" label-id="Edit Hypothesis" icon-id="mesh_edit.png" tooltip-id="" accel-id="" toggle-id="" execute-action=""/>
<separator pos-id=""/>
<popup-item item-id="701" pos-id="" label-id="Compute" icon-id="mesh_compute.png" tooltip-id="" accel-id="" toggle-id="" execute-action=""/>
<separator pos-id=""/>
+ <popup-item item-id="801" pos-id="" label-id="Create Group" icon-id="mesh_tree_group.png" tooltip-id="" accel-id="" toggle-id="" execute-action=""/>
+ <popup-item item-id="802" pos-id="" label-id="Construct Group" icon-id="mesh_make_group.png" tooltip-id="" accel-id="" toggle-id="" execute-action=""/>
+ <popup-item item-id="803" pos-id="" label-id="Edit Group" icon-id="mesh_edit_group.png" tooltip-id="" accel-id="" toggle-id="" execute-action=""/>
+ <separator pos-id=""/>
<popup-item item-id="900" pos-id="" label-id="Mesh Infos" icon-id="mesh_info.png" tooltip-id="" accel-id="" toggle-id="" execute-action=""/>
</menu-item>
<!-- ************************** Control (menubar) ************************************ -->
<menu-item label-id="Controls" item-id="60" pos-id="5">
<popup-item item-id="6001" pos-id="" label-id="Length" icon-id="mesh_length.png" tooltip-id="" accel-id="" toggle-id="" execute-action=""/>
- <popup-item item-id="6002" pos-id="" label-id="Connectivity" icon-id="mesh_connectivity.png" tooltip-id="" accel-id="" toggle-id="" execute-action=""/>
+ <popup-item item-id="6003" pos-id="" label-id="Free borders" icon-id="mesh_free_edges.png" tooltip-id="" accel-id="" toggle-id="" execute-action=""/>
+ <popup-item item-id="6004" pos-id="" label-id="Borders at multi-connection" icon-id="mesh_multi_edges.png" tooltip-id="" accel-id="" toggle-id="" execute-action=""/>
+ <!-- popup-item item-id="6002" pos-id="" label-id="Connectivity" icon-id="mesh_connectivity.png" tooltip-id="" accel-id="" toggle-id="" execute-action=""/ -->
<popup-item item-id="6011" pos-id="" label-id="Area" icon-id="mesh_area.png" tooltip-id="" accel-id="" toggle-id="" execute-action=""/>
- <popup-item item-id="6012" pos-id="" label-id="Taper" icon-id="mesh_taper.png" tooltip-id="" accel-id="" toggle-id="" execute-action=""/>
- <popup-item item-id="6013" pos-id="" label-id="Aspect Ratio" icon-id="mesh_aspect.png" tooltip-id="" accel-id="" toggle-id="" execute-action=""/>
+ <popup-item item-id="6012" pos-id="" label-id="Taper" icon-id="mesh_taper.png" tooltip-id="" accel-id="" toggle-id="" execute-action=""/>
+ <popup-item item-id="6013" pos-id="" label-id="Aspect Ratio" icon-id="mesh_aspect.png" tooltip-id="" accel-id="" toggle-id="" execute-action=""/>
<popup-item item-id="6014" pos-id="" label-id="Minimum angle" icon-id="mesh_angle.png" tooltip-id="" accel-id="" toggle-id="" execute-action=""/>
<popup-item item-id="6015" pos-id="" label-id="Warp" icon-id="mesh_wrap.png" tooltip-id="" accel-id="" toggle-id="" execute-action=""/>
<popup-item item-id="6016" pos-id="" label-id="Skew" icon-id="mesh_skew.png" tooltip-id="" accel-id="" toggle-id="" execute-action=""/>
</submenu>
<endsubmenu />
<popup-item item-id="405" pos-id="" label-id="Move Node" icon-id="mesh_move_node.png" tooltip-id="" accel-id="" toggle-id="" execute-action=""/>
- <popup-item item-id="806" pos-id="" label-id="Orientation" icon-id="mesh_orientation.png" tooltip-id="" accel-id="" toggle-id="" execute-action=""/>
- <popup-item item-id="807" pos-id="" label-id="Diagonal Inversion" icon-id="mesh_diagonal.png" tooltip-id="" accel-id="" toggle-id="" execute-action=""/>
-</menu-item>
-
-<!-- ************************** Numbering (menubar) ************************************ -->
-<menu-item label-id="Numbering" item-id="80" pos-id="7">
- <popup-item item-id="9010" pos-id="" label-id="Display Nodes #" icon-id="" tooltip-id="" accel-id="" toggle-id="false" execute-action=""/>
- <popup-item item-id="9011" pos-id="" label-id="Display Elements #" icon-id="" tooltip-id="" accel-id="" toggle-id="false" execute-action=""/>
+ <popup-item item-id="406" pos-id="" label-id="Orientation" icon-id="mesh_orientation.png" tooltip-id="" accel-id="" toggle-id="" execute-action=""/>
+ <popup-item item-id="407" pos-id="" label-id="Diagonal Inversion" icon-id="mesh_diagonal.png" tooltip-id="" accel-id="" toggle-id="" execute-action=""/>
</menu-item>
<!-- ********************************* Settings (menubar) ********************************* -->
<menu-item label-id="Preferences" item-id="4" pos-id="">
<submenu label-id="Mesh" item-id="100" pos-id="-1">
<submenu label-id="Display Mode" item-id="1000" pos-id="">
- <popup-item item-id="10001" pos-id="" label-id="Wireframe" icon-id="" tooltip-id="" accel-id="" toggle-id="false" execute-action=""/>
- <popup-item item-id="10002" pos-id="" label-id="Shading" icon-id="" tooltip-id=""accel-id="" toggle-id="true" execute-action=""/>
- <popup-item item-id="10003" pos-id="" label-id="Shrink" icon-id="" tooltip-id="" accel-id="" toggle-id="false" execute-action=""/>
+ <popup-item item-id="10001" pos-id="" label-id="Wireframe" icon-id="mesh_wireframe.png" tooltip-id="" accel-id="" toggle-id="false" execute-action=""/>
+ <popup-item item-id="10002" pos-id="" label-id="Shading" icon-id="mesh_shading.png" tooltip-id=""accel-id="" toggle-id="true" execute-action=""/>
+ <popup-item item-id="10004" pos-id="" label-id="Nodes" icon-id="mesh_points.png" tooltip-id="" accel-id="" toggle-id="false" execute-action=""/>
+ <separator pos-id=""/>
+ <popup-item item-id="10003" pos-id="" label-id="Shrink" icon-id="mesh_shrink.png" tooltip-id="" accel-id="" toggle-id="false" execute-action=""/>
</submenu>
<endsubmenu />
<popup-item item-id="1001" pos-id="" label-id="Automatic Update" icon-id="" tooltip-id="" accel-id="" toggle-id="false" execute-action=""/>
<separator pos-id=""/>
- <popup-item item-id="1003" pos-id="" label-id="Colors - Size" icon-id="" tooltip-id="" accel-id="" toggle-id="" execute-action=""/>
+ <popup-item item-id="1003" pos-id="" label-id="Colors / Size" icon-id="" tooltip-id="" accel-id="" toggle-id="" execute-action=""/>
<separator pos-id=""/>
- <popup-item item-id="1005" pos-id="" label-id="Scalars Bar" icon-id="" tooltip-id="" accel-id="" toggle-id="" execute-action=""/>
+ <popup-item item-id="1005" pos-id="" label-id="Scalar Bar" icon-id="" tooltip-id="" accel-id="" toggle-id="" execute-action=""/>
+ <separator pos-id=""/>
+ <popup-item item-id="1006" pos-id="" label-id="Selection" icon-id="" tooltip-id="" accel-id="" toggle-id="" execute-action=""/>
</submenu>
<endsubmenu />
<separator pos-id="-1"/>
<!-- ********************************* View (menubar) ********************************* -->
<menu-item label-id="View" item-id="2" pos-id="">
- <submenu label-id="Display Mode" item-id="21" pos-id="">
- <popup-item item-id="211" pos-id="" label-id="Wireframe" icon-id="mesh_wireframe.png" tooltip-id="" accel-id="" toggle-id="" execute-action=""/>
- <popup-item item-id="212" pos-id="" label-id="Shading" icon-id="mesh_shading.png" tooltip-id=""accel-id="" toggle-id="" execute-action=""/>
- <popup-item item-id="213" pos-id="" label-id="Shrink" icon-id="mesh_shrink.png" tooltip-id="" accel-id="" toggle-id="" execute-action=""/>
- </submenu>
- <endsubmenu />
<separator pos-id=""/>
<popup-item item-id="214" pos-id="" label-id="Update" icon-id="mesh_update.png" tooltip-id="" accel-id="" toggle-id="" execute-action=""/>
</menu-item>
<!-- ################################# POPUP MENU ################################# -->
<popupmenu label-id="Popup for ObjectBrowser" context-id="" parent-id="ObjectBrowser" object-id="Mesh">
- <popup-item item-id="705" pos-id="" label-id="Edit Global Hyp." icon-id="" tooltip-id="" accel-id="" toggle-id="" execute-action=""/>
+ <popup-item item-id="705" pos-id="" label-id="Edit Global Hypothesis" icon-id="mesh_edit.png" tooltip-id="" accel-id="" toggle-id="" execute-action=""/>
+ <separator pos-id=""/>
+ <popup-item item-id="701" pos-id="" label-id="Compute" icon-id="mesh_compute.png" tooltip-id="" accel-id="" toggle-id="" execute-action=""/>
+ <popup-item item-id="214" pos-id="" label-id="Update" icon-id="mesh_update.png" tooltip-id="" accel-id="" toggle-id="" execute-action=""/>
+ <popup-item item-id="900" pos-id="" label-id="Show Info" icon-id="mesh_info.png" tooltip-id="" accel-id="" toggle-id="" execute-action=""/>
<separator pos-id=""/>
- <popup-item item-id="701" pos-id="" label-id="Compute" icon-id="" tooltip-id="" accel-id="" toggle-id="" execute-action=""/>
- <popup-item item-id="214" pos-id="" label-id="Update" icon-id="" tooltip-id="" accel-id="" toggle-id="" execute-action=""/>
+ <popup-item item-id="801" pos-id="" label-id="Create Group" icon-id="mesh_tree_group.png" tooltip-id="" accel-id="" toggle-id="" execute-action=""/>
<separator pos-id=""/>
<popup-item item-id="1101" pos-id="" label-id="Rename" icon-id="" tooltip-id="" accel-id="" toggle-id="" execute-action=""/>
+ <separator pos-id=""/>
+ <popup-item item-id="122" pos-id="" label-id="Export to MED" icon-id="" tooltip-id="" accel-id="" toggle-id="" execute-action=""/>
</popupmenu>
<popupmenu label-id="Popup for ObjectBrowser" context-id="" parent-id="ObjectBrowser" object-id="SubMesh">
- <popup-item item-id="706" pos-id="" label-id="Edit Local Hyp." icon-id="" tooltip-id="" accel-id="" toggle-id="" execute-action=""/>
+ <popup-item item-id="706" pos-id="" label-id="Edit Local Hypothesis" icon-id="mesh_edit.png" tooltip-id="" accel-id="" toggle-id="" execute-action=""/>
+ <separator pos-id=""/>
+ <popup-item item-id="214" pos-id="" label-id="Update" icon-id="mesh_update.png" tooltip-id="" accel-id="" toggle-id="" execute-action=""/>
+ <popup-item item-id="900" pos-id="" label-id="Show Info" icon-id="mesh_info.png" tooltip-id="" accel-id="" toggle-id="" execute-action=""/>
+ <separator pos-id=""/>
+ <popup-item item-id="802" pos-id="" label-id="Construct Group" icon-id="mesh_make_group.png" tooltip-id="" accel-id="" toggle-id="" execute-action=""/>
+ <separator pos-id=""/>
+ <popup-item item-id="33" pos-id="" label-id="Delete" icon-id="delete.png" tooltip-id="" accel-id="" toggle-id="" execute-action="" />
+</popupmenu>
+
+<popupmenu label-id="Popup for ObjectBrowser" context-id="" parent-id="ObjectBrowser" object-id="Group">
+ <popup-item item-id="803" pos-id="" label-id="Edit" icon-id="mesh_edit_group.png" tooltip-id="" accel-id="" toggle-id="" execute-action=""/>
+ <separator pos-id=""/>
+ <popup-item item-id="214" pos-id="" label-id="Update" icon-id="mesh_update.png" tooltip-id="" accel-id="" toggle-id="" execute-action=""/>
+ <popup-item item-id="900" pos-id="" label-id="Show Info" icon-id="mesh_info.png" tooltip-id="" accel-id="" toggle-id="" execute-action=""/>
+ <separator pos-id=""/>
+ <popup-item item-id="1101" pos-id="" label-id="Rename" icon-id="" tooltip-id="" accel-id="" toggle-id="" execute-action=""/>
+ <separator pos-id=""/>
+ <popup-item item-id="33" pos-id="" label-id="Delete" icon-id="delete.png" tooltip-id="" accel-id="" toggle-id="" execute-action="" />
</popupmenu>
<popupmenu label-id="Popup for ObjectBrowser" context-id="" parent-id="ObjectBrowser" object-id="Hypothesis">
<popup-item item-id="1100" pos-id="" label-id="Edit" icon-id="" tooltip-id="" accel-id="" toggle-id="" execute-action=""/>
- <popup-item item-id="1102" pos-id="" label-id="Unassign Hyp." icon-id="" tooltip-id="" accel-id="" toggle-id="" execute-action=""/>
+ <popup-item item-id="1102" pos-id="" label-id="Unassign Hypothesis" icon-id="" tooltip-id="" accel-id="" toggle-id="" execute-action=""/>
<popup-item item-id="1101" pos-id="" label-id="Rename" icon-id="" tooltip-id="" accel-id="" toggle-id="" execute-action=""/>
</popupmenu>
+
<popupmenu label-id="Popup for ObjectBrowser" context-id="" parent-id="ObjectBrowser" object-id="Algorithm">
- <popup-item item-id="1102" pos-id="" label-id="Unassign Algo." icon-id="" tooltip-id="" accel-id="" toggle-id="" execute-action=""/>
+ <popup-item item-id="1102" pos-id="" label-id="Unassign Algorithm" icon-id="" tooltip-id="" accel-id="" toggle-id="" execute-action=""/>
<popup-item item-id="1101" pos-id="" label-id="Rename" icon-id="" tooltip-id="" accel-id="" toggle-id="" execute-action=""/>
</popupmenu>
-
<popupmenu label-id="Popup for Viewer" context-id="" parent-id="Viewer" object-id="Mesh">
- <popup-item item-id="214" pos-id="" label-id="Update" icon-id="" tooltip-id="" accel-id="" toggle-id="" execute-action=""/>
+ <popup-item item-id="214" pos-id="" label-id="Update" icon-id="mesh_update.png" tooltip-id="" accel-id="" toggle-id="" execute-action=""/>
+ <popup-item item-id="900" pos-id="" label-id="Show Info" icon-id="mesh_info.png" tooltip-id="" accel-id="" toggle-id="" execute-action=""/>
+ <separator pos-id=""/>
+ <submenu label-id="Numbering" item-id="114" pos-id="">
+ <popup-item item-id="9010" pos-id="" label-id="Display Nodes #" icon-id="" tooltip-id="" accel-id="" toggle-id="" execute-action=""/>
+ <popup-item item-id="9011" pos-id="" label-id="Display Elements #" icon-id="" tooltip-id="" accel-id="" toggle-id="" execute-action=""/>
+ </submenu>
+ <endsubmenu />
+ <separator pos-id=""/>
+ <submenu label-id="Display Mode" item-id="1131" pos-id="">
+ <popup-item item-id="211" pos-id="" label-id="Wireframe" icon-id="mesh_wireframe.png" tooltip-id="" accel-id="" toggle-id="" execute-action=""/>
+ <popup-item item-id="212" pos-id="" label-id="Shading" icon-id="mesh_shading.png" tooltip-id=""accel-id="" toggle-id="" execute-action=""/>
+ <popup-item item-id="215" pos-id="" label-id="Nodes" icon-id="mesh_points.png" tooltip-id="" accel-id="" toggle-id="" execute-action=""/>
+ <separator pos-id=""/>
+ <popup-item item-id="213" pos-id="" label-id="Shrink" icon-id="mesh_shrink.png" tooltip-id="" accel-id="" toggle-id="" execute-action=""/>
+ </submenu>
+ <endsubmenu />
+ <popup-item item-id="1132" pos-id="" label-id="Colors / Size" icon-id="" tooltip-id="" accel-id="" toggle-id="" execute-action=""/>
+ <popup-item item-id="1133" pos-id="" label-id="Transparency" icon-id="" tooltip-id="" accel-id="" toggle-id="" execute-action=""/>
+ <separator pos-id=""/>
+ <submenu label-id="Control" item-id="2000" pos-id="">
+ <popup-item item-id="6001" pos-id="" label-id="Length" icon-id="mesh_length.png" tooltip-id="" accel-id="" toggle-id="" execute-action=""/>
+ <popup-item item-id="6003" pos-id="" label-id="Free borders" icon-id="mesh_free_edges.png" tooltip-id="" accel-id="" toggle-id="" execute-action=""/>
+ <popup-item item-id="6004" pos-id="" label-id="Borders at multi-connection" icon-id="mesh_multi_edges.png" tooltip-id="" accel-id="" toggle-id="" execute-action=""/>
+ <!-- popup-item item-id="6002" pos-id="" label-id="Connectivity" icon-id="mesh_connectivity.png" tooltip-id="" accel-id="" toggle-id="" execute-action=""/ -->
+ <popup-item item-id="6011" pos-id="" label-id="Area" icon-id="mesh_area.png" tooltip-id="" accel-id="" toggle-id="" execute-action=""/>
+ <popup-item item-id="6012" pos-id="" label-id="Taper" icon-id="mesh_taper.png" tooltip-id="" accel-id="" toggle-id="" execute-action=""/>
+ <popup-item item-id="6013" pos-id="" label-id="Aspect Ratio" icon-id="mesh_aspect.png" tooltip-id="" accel-id="" toggle-id="" execute-action=""/>
+ <popup-item item-id="6014" pos-id="" label-id="Minimum angle" icon-id="mesh_angle.png" tooltip-id="" accel-id="" toggle-id="" execute-action=""/>
+ <popup-item item-id="6015" pos-id="" label-id="Warp" icon-id="mesh_wrap.png" tooltip-id="" accel-id="" toggle-id="" execute-action=""/>
+ <popup-item item-id="6016" pos-id="" label-id="Skew" icon-id="mesh_skew.png" tooltip-id="" accel-id="" toggle-id="" execute-action=""/>
+ <separator pos-id=""/>
+ <popup-item item-id="200" pos-id="" label-id="Reset" icon-id="" tooltip-id="" accel-id="" toggle-id="" execute-action=""/>
+ <separator pos-id=""/>
+ <popup-item item-id="201" pos-id="" label-id="Scalar Bar Properties" icon-id="" tooltip-id="" accel-id="" toggle-id="" execute-action=""/>
+ </submenu>
+ <endsubmenu />
+ <separator pos-id=""/>
+</popupmenu>
+
+<popupmenu label-id="Popup for Viewer" context-id="" parent-id="Viewer" object-id="SubMesh">
+ <popup-item item-id="214" pos-id="" label-id="Update" icon-id="mesh_update.png" tooltip-id="" accel-id="" toggle-id="" execute-action=""/>
+ <popup-item item-id="900" pos-id="" label-id="Show Info" icon-id="mesh_info.png" tooltip-id="" accel-id="" toggle-id="" execute-action=""/>
<separator pos-id=""/>
- <submenu label-id="Properties" item-id="113" pos-id="">
- <submenu label-id="Display Mode" item-id="1131" pos-id="">
- <popup-item item-id="211" pos-id="" label-id="Wireframe" icon-id="" tooltip-id="" accel-id="" toggle-id="" execute-action=""/>
- <popup-item item-id="212" pos-id="" label-id="Shading" icon-id="" tooltip-id=""accel-id="" toggle-id="" execute-action=""/>
- <popup-item item-id="213" pos-id="" label-id="Shrink" icon-id="" tooltip-id="" accel-id="" toggle-id="" execute-action=""/>
- </submenu>
- <endsubmenu />
+ <submenu label-id="Numbering" item-id="114" pos-id="">
+ <popup-item item-id="9010" pos-id="" label-id="Display Nodes #" icon-id="" tooltip-id="" accel-id="" toggle-id="" execute-action=""/>
+ <popup-item item-id="9011" pos-id="" label-id="Display Elements #" icon-id="" tooltip-id="" accel-id="" toggle-id="" execute-action=""/>
+ </submenu>
+ <endsubmenu />
+ <separator pos-id=""/>
+ <submenu label-id="Display Mode" item-id="1131" pos-id="">
+ <popup-item item-id="211" pos-id="" label-id="Wireframe" icon-id="mesh_wireframe.png" tooltip-id="" accel-id="" toggle-id="" execute-action=""/>
+ <popup-item item-id="212" pos-id="" label-id="Shading" icon-id="mesh_shading.png" tooltip-id=""accel-id="" toggle-id="" execute-action=""/>
+ <popup-item item-id="215" pos-id="" label-id="Nodes" icon-id="mesh_points.png" tooltip-id="" accel-id="" toggle-id="" execute-action=""/>
+ <separator pos-id=""/>
+ <popup-item item-id="213" pos-id="" label-id="Shrink" icon-id="mesh_shrink.png" tooltip-id="" accel-id="" toggle-id="" execute-action=""/>
+ </submenu>
+ <endsubmenu />
+ <popup-item item-id="1132" pos-id="" label-id="Colors / Size" icon-id="" tooltip-id="" accel-id="" toggle-id="" execute-action=""/>
+ <popup-item item-id="1133" pos-id="" label-id="Transparency" icon-id="" tooltip-id="" accel-id="" toggle-id="" execute-action=""/>
+ <separator pos-id=""/>
+ <submenu label-id="Control" item-id="2000" pos-id="">
+ <popup-item item-id="6001" pos-id="" label-id="Length" icon-id="mesh_length.png" tooltip-id="" accel-id="" toggle-id="" execute-action=""/>
+ <popup-item item-id="6003" pos-id="" label-id="Free borders" icon-id="mesh_free_edges.png" tooltip-id="" accel-id="" toggle-id="" execute-action=""/>
+ <popup-item item-id="6004" pos-id="" label-id="Borders at multi-connection" icon-id="mesh_multi_edges.png" tooltip-id="" accel-id="" toggle-id="" execute-action=""/>
+ <!-- popup-item item-id="6002" pos-id="" label-id="Connectivity" icon-id="mesh_connectivity.png" tooltip-id="" accel-id="" toggle-id="" execute-action=""/ -->
+ <popup-item item-id="6011" pos-id="" label-id="Area" icon-id="mesh_area.png" tooltip-id="" accel-id="" toggle-id="" execute-action=""/>
+ <popup-item item-id="6012" pos-id="" label-id="Taper" icon-id="mesh_taper.png" tooltip-id="" accel-id="" toggle-id="" execute-action=""/>
+ <popup-item item-id="6013" pos-id="" label-id="Aspect Ratio" icon-id="mesh_aspect.png" tooltip-id="" accel-id="" toggle-id="" execute-action=""/>
+ <popup-item item-id="6014" pos-id="" label-id="Minimum angle" icon-id="mesh_angle.png" tooltip-id="" accel-id="" toggle-id="" execute-action=""/>
+ <popup-item item-id="6015" pos-id="" label-id="Warp" icon-id="mesh_wrap.png" tooltip-id="" accel-id="" toggle-id="" execute-action=""/>
+ <popup-item item-id="6016" pos-id="" label-id="Skew" icon-id="mesh_skew.png" tooltip-id="" accel-id="" toggle-id="" execute-action=""/>
<separator pos-id=""/>
- <popup-item item-id="1132" pos-id="" label-id="Colors - Size" icon-id="" tooltip-id="" accel-id="" toggle-id="" execute-action=""/>
- <popup-item item-id="1133" pos-id="" label-id="Transparency" icon-id="" tooltip-id="" accel-id="" toggle-id="" execute-action=""/>
+ <popup-item item-id="200" pos-id="" label-id="Reset" icon-id="" tooltip-id="" accel-id="" toggle-id="" execute-action=""/>
+ <separator pos-id=""/>
+ <popup-item item-id="201" pos-id="" label-id="Scalar Bar Properties" icon-id="" tooltip-id="" accel-id="" toggle-id="" execute-action=""/>
</submenu>
<endsubmenu />
+ <separator pos-id=""/>
</popupmenu>
-<popupmenu label-id="ScalarBar" context-id="" parent-id="Viewer" object-id="ScalarBar">
- <popup-item item-id="200" pos-id="" label-id="Erase" icon-id="" tooltip-id="" accel-id="" toggle-id="" execute-action=""/>
- <popup-item item-id="201" pos-id="" label-id="Edit" icon-id="" tooltip-id="" accel-id="" toggle-id="" execute-action=""/>
- <popup-item item-id="202" pos-id="" label-id="Update View" icon-id="" tooltip-id="" accel-id="" toggle-id="" execute-action=""/>
+<popupmenu label-id="Popup for Viewer" context-id="" parent-id="Viewer" object-id="Group">
+ <popup-item item-id="803" pos-id="" label-id="Edit" icon-id="mesh_edit_group.png" tooltip-id="" accel-id="" toggle-id="" execute-action=""/>
+ <separator pos-id=""/>
+ <popup-item item-id="214" pos-id="" label-id="Update" icon-id="mesh_update.png" tooltip-id="" accel-id="" toggle-id="" execute-action=""/>
+ <popup-item item-id="900" pos-id="" label-id="Show Info" icon-id="mesh_info.png" tooltip-id="" accel-id="" toggle-id="" execute-action=""/>
+ <separator pos-id=""/>
+ <submenu label-id="Numbering" item-id="114" pos-id="">
+ <popup-item item-id="9010" pos-id="" label-id="Display Nodes #" icon-id="" tooltip-id="" accel-id="" toggle-id="" execute-action=""/>
+ <popup-item item-id="9011" pos-id="" label-id="Display Elements #" icon-id="" tooltip-id="" accel-id="" toggle-id="" execute-action=""/>
+ </submenu>
+ <endsubmenu />
+ <separator pos-id=""/>
+ <submenu label-id="Display Mode" item-id="1131" pos-id="">
+ <popup-item item-id="211" pos-id="" label-id="Wireframe" icon-id="mesh_wireframe.png" tooltip-id="" accel-id="" toggle-id="" execute-action=""/>
+ <popup-item item-id="212" pos-id="" label-id="Shading" icon-id="mesh_shading.png" tooltip-id=""accel-id="" toggle-id="" execute-action=""/>
+ <popup-item item-id="215" pos-id="" label-id="Nodes" icon-id="mesh_points.png" tooltip-id="" accel-id="" toggle-id="" execute-action=""/>
+ <separator pos-id=""/>
+ <popup-item item-id="213" pos-id="" label-id="Shrink" icon-id="mesh_shrink.png" tooltip-id="" accel-id="" toggle-id="" execute-action=""/>
+ </submenu>
+ <endsubmenu />
+ <popup-item item-id="1132" pos-id="" label-id="Colors / Size" icon-id="" tooltip-id="" accel-id="" toggle-id="" execute-action=""/>
+ <popup-item item-id="1133" pos-id="" label-id="Transparency" icon-id="" tooltip-id="" accel-id="" toggle-id="" execute-action=""/>
+ <separator pos-id=""/>
+ <submenu label-id="Control" item-id="2000" pos-id="">
+ <popup-item item-id="6001" pos-id="" label-id="Length" icon-id="mesh_length.png" tooltip-id="" accel-id="" toggle-id="" execute-action=""/>
+ <popup-item item-id="6003" pos-id="" label-id="Free borders" icon-id="mesh_free_edges.png" tooltip-id="" accel-id="" toggle-id="" execute-action=""/>
+ <popup-item item-id="6004" pos-id="" label-id="Borders at multi-connection" icon-id="mesh_multi_edges.png" tooltip-id="" accel-id="" toggle-id="" execute-action=""/>
+ <!-- popup-item item-id="6002" pos-id="" label-id="Connectivity" icon-id="mesh_connectivity.png" tooltip-id="" accel-id="" toggle-id="" execute-action=""/ -->
+ <popup-item item-id="6011" pos-id="" label-id="Area" icon-id="mesh_area.png" tooltip-id="" accel-id="" toggle-id="" execute-action=""/>
+ <popup-item item-id="6012" pos-id="" label-id="Taper" icon-id="mesh_taper.png" tooltip-id="" accel-id="" toggle-id="" execute-action=""/>
+ <popup-item item-id="6013" pos-id="" label-id="Aspect Ratio" icon-id="mesh_aspect.png" tooltip-id="" accel-id="" toggle-id="" execute-action=""/>
+ <popup-item item-id="6014" pos-id="" label-id="Minimum angle" icon-id="mesh_angle.png" tooltip-id="" accel-id="" toggle-id="" execute-action=""/>
+ <popup-item item-id="6015" pos-id="" label-id="Warp" icon-id="mesh_wrap.png" tooltip-id="" accel-id="" toggle-id="" execute-action=""/>
+ <popup-item item-id="6016" pos-id="" label-id="Skew" icon-id="mesh_skew.png" tooltip-id="" accel-id="" toggle-id="" execute-action=""/>
+ <separator pos-id=""/>
+ <popup-item item-id="200" pos-id="" label-id="Reset" icon-id="" tooltip-id="" accel-id="" toggle-id="" execute-action=""/>
+ <separator pos-id=""/>
+ <popup-item item-id="201" pos-id="" label-id="Scalar Bar Properties" icon-id="" tooltip-id="" accel-id="" toggle-id="" execute-action=""/>
+ </submenu>
+ <endsubmenu />
+ <separator pos-id=""/>
+</popupmenu>
+
+<popupmenu label-id="Elements" context-id="" parent-id="Viewer" object-id="Elements">
+ <popup-item item-id="804" pos-id="" label-id="Add" icon-id="" tooltip-id="" accel-id="" toggle-id="" execute-action=""/>
+ <popup-item item-id="805" pos-id="" label-id="Remove" icon-id="" tooltip-id="" accel-id="" toggle-id="" execute-action=""/>
</popupmenu>
</menubar>
<!-- ///////////////////////////////////// TOOLBARS ////////////////////////////////////// -->
<toolbar label-id="Mesh Toolbar">
- <toolbutton-item item-id="703" pos-id="" label-id="Init" icon-id="mesh_init.png" tooltip-id="Global Hyp." accel-id="" toggle-id="" execute-action=""/>
- <toolbutton-item item-id="702" pos-id="" label-id="Add SubMesh" icon-id="mesh_add_sub.png" tooltip-id="Local Hyp." accel-id="" toggle-id="" execute-action=""/>
- <toolbutton-item item-id="704" pos-id="" label-id="Edit" icon-id="mesh_edit.png" tooltip-id="Edit Hyp." accel-id="" toggle-id="" execute-action=""/>
+ <toolbutton-item item-id="703" pos-id="" label-id="Init" icon-id="mesh_init.png" tooltip-id="Global Hypothesis" accel-id="" toggle-id="" execute-action=""/>
+ <toolbutton-item item-id="702" pos-id="" label-id="Add SubMesh" icon-id="mesh_add_sub.png" tooltip-id="Local Hypothesis" accel-id="" toggle-id="" execute-action=""/>
+ <toolbutton-item item-id="704" pos-id="" label-id="Edit" icon-id="mesh_edit.png" tooltip-id="Edit Hypothesis" accel-id="" toggle-id="" execute-action=""/>
<separatorTB/>
<toolbutton-item item-id="701" pos-id="" label-id="Compute" icon-id="mesh_compute.png" tooltip-id="Compute" accel-id="" toggle-id="" execute-action=""/>
<separatorTB/>
+ <toolbutton-item item-id="801" pos-id="" label-id="Create Group" icon-id="mesh_tree_group.png" tooltip-id="Create Group" accel-id="" toggle-id="" execute-action=""/>
+ <toolbutton-item item-id="802" pos-id="" label-id="Construct Group" icon-id="mesh_make_group.png" tooltip-id="Construct Group" accel-id="" toggle-id="" execute-action=""/>
+ <toolbutton-item item-id="803" pos-id="" label-id="Edit Group" icon-id="mesh_edit_group.png" tooltip-id="Edit Group" accel-id="" toggle-id="" execute-action=""/>
+ <separatorTB/>
<toolbutton-item item-id="900" pos-id="" label-id="Mesh Infos" icon-id="mesh_info.png" tooltip-id="Mesh Infos" accel-id="" toggle-id="" execute-action=""/>
</toolbar>
<toolbar label-id="Hypotheses Toolbar">
- <toolbutton-item item-id="5030" label-id="Average length" icon-id="mesh_hypo_length.png" tooltip-id="Avreage length Hypothesis" accel-id="" toggle-id="" execute-action=""/>
- <toolbutton-item item-id="5031" label-id="Segments" icon-id="mesh_hypo_segment.png" tooltip-id="Nb. Segments Hypothesis" accel-id="" toggle-id="" execute-action=""/>
- <toolbutton-item item-id="5032" label-id="Max. Triangle Area" icon-id="mesh_hypo_area.png" tooltip-id="Max. Triangle Area Hypothesis" accel-id="" toggle-id="" execute-action=""/>
- <toolbutton-item item-id="5033" label-id="Max. Hexahedron or Tetrahedron Volume" icon-id="mesh_hypo_volume.png" tooltip-id="Max. Hexahedron or Tetrahedron Volume Hypothesis" accel-id="" toggle-id="" execute-action=""/>
- <toolbutton-item item-id="5034" label-id="Length From Edges (2D Hyp. for Triangulator)" icon-id="mesh_hypo_length.png" tooltip-id="Length From Edges Hypothesis" accel-id="" toggle-id="" execute-action=""/>
- <separatorTB/>
- <toolbutton-item item-id="5000" label-id="Wire Discretisation" icon-id="mesh_algo_regular.png" tooltip-id="Wire Discratisation Algorithm" accel-id="" toggle-id="" execute-action=""/>
- <toolbutton-item item-id="5010" label-id="Triangle (Mefisto)" icon-id="mesh_algo_mefisto.png" tooltip-id="Triangle (Mefisto) Algorithm" accel-id="" toggle-id="" execute-action=""/>
- <toolbutton-item item-id="5011" label-id="Quadrangle (Mapping)" icon-id="mesh_algo_quad.png" tooltip-id="Quadrangle (Mapping) Algorithm" accel-id="" toggle-id="" execute-action=""/>
- <toolbutton-item item-id="5020" label-id="Hexahedron (i,j,k)" icon-id="mesh_algo_hexa.png" tooltip-id="Hexahedron (i,j,k) Algorithm" accel-id="" toggle-id="" execute-action=""/>
- <toolbutton-item item-id="5021" label-id="Tetrahedron (Netgen)" icon-id="mesh_algo_hexa.png" tooltip-id="Tetrahedron (Netgen) Delaunay Algorithm" accel-id="" toggle-id="" execute-action=""/>
+ <toolbutton-item item-id="5000" label-id="Create Hypotheses" icon-id="mesh_hypo_length.png" tooltip-id="Create Hypotheses" accel-id="" toggle-id="" execute-action=""/>
+ <toolbutton-item item-id="5010" label-id="Create Algorithms" icon-id="mesh_algo_mefisto.png" tooltip-id="Create Algorithms" accel-id="" toggle-id="" execute-action=""/>
</toolbar>
<toolbar label-id="Controls toolbar">
<toolbutton-item item-id="6001" label-id="Length" icon-id="mesh_length.png" tooltip-id="Length" accel-id="" toggle-id="" execute-action=""/>
- <toolbutton-item item-id="6002" label-id="Connectivity" icon-id="mesh_connectivity.png" tooltip-id="Connectivity" accel-id="" toggle-id="" execute-action=""/>
+ <toolbutton-item item-id="6003" label-id="Free borders" icon-id="mesh_free_edges.png" tooltip-id="Free borders" accel-id="" toggle-id="" execute-action=""/>
+ <toolbutton-item item-id="6004" label-id="Borders at multi-connection" icon-id="mesh_multi_edges.png" tooltip-id="Borders at multi-connection" accel-id="" toggle-id="" execute-action=""/>
+<!--<toolbutton-item item-id="6002" label-id="Connectivity" icon-id="mesh_connectivity.png" tooltip-id="Connectivity" accel-id="" toggle-id="" execute-action=""/>-->
<toolbutton-item item-id="6011" label-id="Area" icon-id="mesh_area.png" tooltip-id="Area" accel-id="" toggle-id="" execute-action=""/>
<toolbutton-item item-id="6012" label-id="Taper" icon-id="mesh_taper.png" tooltip-id="Taper" accel-id="" toggle-id="" execute-action=""/>
<toolbutton-item item-id="6013" label-id="Aspect Ratio" icon-id="mesh_aspect.png" tooltip-id="Aspect Ratio" accel-id="" toggle-id="" execute-action=""/>
<toolbar label-id="Modification toolbar">
<toolbutton-item item-id="405" label-id="Move Node" icon-id="mesh_move_node.png" tooltip-id="Move Node" accel-id="" toggle-id="" execute-action=""/>
- <toolbutton-item item-id="806" label-id="Orientation" icon-id="mesh_orientation.png" tooltip-id="Orientation" accel-id="" toggle-id="" execute-action=""/>
- <toolbutton-item item-id="807" label-id="Diagonal Inversion" icon-id="mesh_diagonal.png" tooltip-id="Diagonal Inversion" accel-id="" toggle-id="" execute-action=""/>
+ <toolbutton-item item-id="406" label-id="Orientation" icon-id="mesh_orientation.png" tooltip-id="Orientation" accel-id="" toggle-id="" execute-action=""/>
+ <toolbutton-item item-id="407" label-id="Diagonal Inversion" icon-id="mesh_diagonal.png" tooltip-id="Diagonal Inversion" accel-id="" toggle-id="" execute-action=""/>
</toolbar>
<toolbar label-id="Display Mode Toolbar">
<toolbutton-item item-id="214" pos-id="" label-id="Update" icon-id="mesh_update.png" tooltip-id="Update View" accel-id="" toggle-id="" execute-action=""/>
- <separatorTB/>
- <toolbutton-item item-id="211" pos-id="" label-id="Wireframe" icon-id="mesh_wireframe.png" tooltip-id="Wireframe" accel-id="" toggle-id="" execute-action=""/>
- <toolbutton-item item-id="212" pos-id="" label-id="Shading" icon-id="mesh_shading.png" tooltip-id="shading" accel-id="" toggle-id="" execute-action=""/>
- <toolbutton-item item-id="213" pos-id="" label-id="Shrink" icon-id="mesh_shrink.png" tooltip-id="shrink" accel-id="" toggle-id="" execute-action=""/>
</toolbar>
</desktop>
<submenu label-id="Import" item-id="11" pos-id="8">
<popup-item item-id="111" pos-id="" label-id="DAT file" icon-id="" tooltip-id="" accel-id="Ctrl+B" toggle-id="" execute-action=""/>
<popup-item item-id="112" pos-id="" label-id="UNV File" icon-id="" tooltip-id="" accel-id="Ctrl+I" toggle-id="" execute-action=""/>
- <popup-item item-id="113" pos-id="" label-id="MED File" icon-id="" tooltip-id="" accel-id="" toggle-id="" execute-action=""/>
+ <popup-item item-id="113" pos-id="" label-id="MED File" icon-id="" tooltip-id="" accel-id="Ctrl+M" toggle-id="" execute-action=""/>
</submenu>
<endsubmenu />
<submenu label-id="Export" item-id="12" pos-id="9">
<!-- ************************** Hypothesis (menubar) ************************************ -->
<menu-item label-id="Hypotheses" item-id="50" pos-id="3">
- <popup-item item-id="5030" pos-id="" label-id="Average length" icon-id="mesh_hypo_length.png" tooltip-id="" accel-id="" toggle-id="" execute-action=""/>
- <popup-item item-id="5031" pos-id="" label-id="Nb. Segments" icon-id="mesh_hypo_segment.png" tooltip-id="" accel-id="" toggle-id="" execute-action=""/>
- <popup-item item-id="5032" pos-id="" label-id="Max. Triangle Area" icon-id="mesh_hypo_area.png" tooltip-id="" accel-id="" toggle-id="" execute-action=""/>
- <popup-item item-id="5033" pos-id="" label-id="Max. Hexahedron or Tetrahedron Volume" icon-id="mesh_hypo_volume.png" tooltip-id="" accel-id="" toggle-id="" execute-action=""/>
- <popup-item item-id="5034" pos-id="" label-id="Length From Edges (2D Hyp. for Triangulator)" icon-id="mesh_hypo_length.png" tooltip-id="" accel-id="" toggle-id="" execute-action=""/>
- <separator pos-id=""/>
- <popup-item item-id="5000" pos-id="" label-id="Wire discretisation" icon-id="mesh_algo_regular.png" tooltip-id="" accel-id="" toggle-id="" execute-action=""/>
- <popup-item item-id="5010" pos-id="" label-id="Triangle (Mefisto)" icon-id="mesh_algo_mefisto.png" tooltip-id="" accel-id="" toggle-id="" execute-action=""/>
- <popup-item item-id="5011" pos-id="" label-id="Quadrangle (Mapping)" icon-id="mesh_algo_quad.png" tooltip-id="" accel-id="" toggle-id="" execute-action=""/>
- <popup-item item-id="5020" pos-id="" label-id="Hexahedron (i,j,k)" icon-id="mesh_algo_hexa.png" tooltip-id="" accel-id="" toggle-id="" execute-action=""/>
- <popup-item item-id="5021" pos-id="" label-id="Tetrahedron (Netgen)" icon-id="mesh_algo_tetra.png" tooltip-id="" accel-id="" toggle-id="" execute-action=""/>
+ <popup-item item-id="5000" pos-id="" label-id="Create Hypothesis" icon-id="mesh_hypo_length.png" tooltip-id="" accel-id="" toggle-id="" execute-action=""/>
+ <popup-item item-id="5010" pos-id="" label-id="Create Algorithm" icon-id="mesh_algo_mefisto.png" tooltip-id="" accel-id="" toggle-id="" execute-action=""/>
</menu-item>
<!-- ************************** Mesh (menubar) ************************************ -->
<separator pos-id=""/>
<popup-item item-id="701" pos-id="" label-id="Compute" icon-id="mesh_compute.png" tooltip-id="" accel-id="" toggle-id="" execute-action=""/>
<separator pos-id=""/>
+ <popup-item item-id="801" pos-id="" label-id="Create Group" icon-id="" tooltip-id="" accel-id="" toggle-id="" execute-action=""/>
+ <separator pos-id=""/>
<popup-item item-id="900" pos-id="" label-id="Mesh Infos" icon-id="mesh_info.png" tooltip-id="" accel-id="" toggle-id="" execute-action=""/>
</menu-item>
</submenu>
<endsubmenu />
<popup-item item-id="405" pos-id="" label-id="Move Node" icon-id="mesh_move_node.png" tooltip-id="" accel-id="" toggle-id="" execute-action=""/>
- <popup-item item-id="806" pos-id="" label-id="Orientation" icon-id="mesh_orientation.png" tooltip-id="" accel-id="" toggle-id="" execute-action=""/>
- <popup-item item-id="807" pos-id="" label-id="Diagonal Inversion" icon-id="mesh_diagonal.png" tooltip-id="" accel-id="" toggle-id="" execute-action=""/>
+ <popup-item item-id="406" pos-id="" label-id="Orientation" icon-id="mesh_orientation.png" tooltip-id="" accel-id="" toggle-id="" execute-action=""/>
+ <popup-item item-id="407" pos-id="" label-id="Diagonal Inversion" icon-id="mesh_diagonal.png" tooltip-id="" accel-id="" toggle-id="" execute-action=""/>
</menu-item>
<!-- ************************** Numbering (menubar) ************************************ -->
<endsubmenu />
<popup-item item-id="1001" pos-id="" label-id="Automatic Update" icon-id="" tooltip-id="" accel-id="" toggle-id="false" execute-action=""/>
<separator pos-id=""/>
- <popup-item item-id="1003" pos-id="" label-id="Colors - Size" icon-id="" tooltip-id="" accel-id="" toggle-id="" execute-action=""/>
+ <popup-item item-id="1003" pos-id="" label-id="Colors - Size" icon-id="" tooltip-id="" accel-id="" toggle-id="" execute-action=""/>
<separator pos-id=""/>
<popup-item item-id="1005" pos-id="" label-id="Scalars Bar" icon-id="" tooltip-id="" accel-id="" toggle-id="" execute-action=""/>
</submenu>
<popup-item item-id="701" pos-id="" label-id="Compute" icon-id="" tooltip-id="" accel-id="" toggle-id="" execute-action=""/>
<popup-item item-id="214" pos-id="" label-id="Update" icon-id="" tooltip-id="" accel-id="" toggle-id="" execute-action=""/>
<separator pos-id=""/>
+ <popup-item item-id="801" pos-id="" label-id="Create Group" icon-id="" tooltip-id="" accel-id="" toggle-id="" execute-action=""/>
+ <separator pos-id=""/>
<popup-item item-id="1101" pos-id="" label-id="Rename" icon-id="" tooltip-id="" accel-id="" toggle-id="" execute-action=""/>
</popupmenu>
<popupmenu label-id="Popup for ObjectBrowser" context-id="" parent-id="ObjectBrowser" object-id="SubMesh">
<popup-item item-id="706" pos-id="" label-id="Edit Local Hyp." icon-id="" tooltip-id="" accel-id="" toggle-id="" execute-action=""/>
+ <separator pos-id=""/>
+ <popup-item item-id="802" pos-id="" label-id="Construct Group" icon-id="" tooltip-id="" accel-id="" toggle-id="" execute-action=""/>
</popupmenu>
<popupmenu label-id="Popup for ObjectBrowser" context-id="" parent-id="ObjectBrowser" object-id="Hypothesis">
<popup-item item-id="1102" pos-id="" label-id="Unassign Hyp." icon-id="" tooltip-id="" accel-id="" toggle-id="" execute-action=""/>
<popup-item item-id="1101" pos-id="" label-id="Rename" icon-id="" tooltip-id="" accel-id="" toggle-id="" execute-action=""/>
</popupmenu>
+
<popupmenu label-id="Popup for ObjectBrowser" context-id="" parent-id="ObjectBrowser" object-id="Algorithm">
<popup-item item-id="1102" pos-id="" label-id="Unassign Algo." icon-id="" tooltip-id="" accel-id="" toggle-id="" execute-action=""/>
<popup-item item-id="1101" pos-id="" label-id="Rename" icon-id="" tooltip-id="" accel-id="" toggle-id="" execute-action=""/>
</popupmenu>
-
<popupmenu label-id="Popup for Viewer" context-id="" parent-id="Viewer" object-id="Mesh">
<popup-item item-id="214" pos-id="" label-id="Update" icon-id="" tooltip-id="" accel-id="" toggle-id="" execute-action=""/>
<separator pos-id=""/>
</toolbar>
<toolbar label-id="Hypotheses Toolbar">
- <toolbutton-item item-id="5030" label-id="Average length" icon-id="mesh_hypo_length.png" tooltip-id="Avreage length Hypothesis" accel-id="" toggle-id="" execute-action=""/>
- <toolbutton-item item-id="5031" label-id="Segments" icon-id="mesh_hypo_segment.png" tooltip-id="Nb. Segments Hypothesis" accel-id="" toggle-id="" execute-action=""/>
- <toolbutton-item item-id="5032" label-id="Max. Triangle Area" icon-id="mesh_hypo_area.png" tooltip-id="Max. Triangle Area Hypothesis" accel-id="" toggle-id="" execute-action=""/>
- <toolbutton-item item-id="5033" label-id="Max. Hexahedron or Tetrahedron Volume" icon-id="mesh_hypo_volume.png" tooltip-id="Max. Hexahedron or Tetrahedron Volume Hypothesis" accel-id="" toggle-id="" execute-action=""/>
- <toolbutton-item item-id="5034" label-id="Length From Edges (2D Hyp. for Triangulator)" icon-id="mesh_hypo_length.png" tooltip-id="Length From Edges Hypothesis" accel-id="" toggle-id="" execute-action=""/>
- <separatorTB/>
- <toolbutton-item item-id="5000" label-id="Wire Discretisation" icon-id="mesh_algo_regular.png" tooltip-id="Wire Discratisation Algorithm" accel-id="" toggle-id="" execute-action=""/>
- <toolbutton-item item-id="5010" label-id="Triangle (Mefisto)" icon-id="mesh_algo_mefisto.png" tooltip-id="Triangle (Mefisto) Algorithm" accel-id="" toggle-id="" execute-action=""/>
- <toolbutton-item item-id="5011" label-id="Quadrangle (Mapping)" icon-id="mesh_algo_quad.png" tooltip-id="Quadrangle (Mapping) Algorithm" accel-id="" toggle-id="" execute-action=""/>
- <toolbutton-item item-id="5020" label-id="Hexahedron (i,j,k)" icon-id="mesh_algo_hexa.png" tooltip-id="Hexahedron (i,j,k) Algorithm" accel-id="" toggle-id="" execute-action=""/>
- <toolbutton-item item-id="5021" label-id="Tetrahedron (Netgen)" icon-id="mesh_algo_hexa.png" tooltip-id="Tetrahedron (Netgen) Delaunay Algorithm" accel-id="" toggle-id="" execute-action=""/>
+ <toolbutton-item item-id="5000" label-id="Create Hypothesis" icon-id="mesh_hypo_length.png" tooltip-id="Create Hypothesis" accel-id="" toggle-id="" execute-action=""/>
+ <toolbutton-item item-id="5010" label-id="Create Algorithm" icon-id="mesh_algo_mefisto.png" tooltip-id="Create Algorithm" accel-id="" toggle-id="" execute-action=""/>
</toolbar>
<toolbar label-id="Controls toolbar">
<toolbar label-id="Modification toolbar">
<toolbutton-item item-id="405" label-id="Move Node" icon-id="mesh_move_node.png" tooltip-id="Move Node" accel-id="" toggle-id="" execute-action=""/>
- <toolbutton-item item-id="806" label-id="Orientation" icon-id="mesh_orientation.png" tooltip-id="Orientation" accel-id="" toggle-id="" execute-action=""/>
- <toolbutton-item item-id="807" label-id="Diagonal Inversion" icon-id="mesh_diagonal.png" tooltip-id="Diagonal Inversion" accel-id="" toggle-id="" execute-action=""/>
+ <toolbutton-item item-id="406" label-id="Orientation" icon-id="mesh_orientation.png" tooltip-id="Orientation" accel-id="" toggle-id="" execute-action=""/>
+ <toolbutton-item item-id="407" label-id="Diagonal Inversion" icon-id="mesh_diagonal.png" tooltip-id="Diagonal Inversion" accel-id="" toggle-id="" execute-action=""/>
</toolbar>
<toolbar label-id="Display Mode Toolbar">
--- /dev/null
+<?xml version='1.0' encoding='us-ascii'?>
+<!DOCTYPE meshers PUBLIC "" "desktop.dtd">
+
+<!-- GUI customization for MESH component -->
+
+<meshers>
+
+<meshers-group name="Standard Meshers"
+ resources="StdMeshers"
+ server-lib="libStdMeshersEngine.so"
+ gui-lib="libStdMeshersGUI.so">
+ <hypotheses>
+
+ <hypothesis type="LocalLength"
+ label-id="Average length"
+ icon-id="mesh_hypo_length.png"/>
+
+ <hypothesis type="LengthFromEdges"
+ label-id="Length From Edges (2D Hyp. for Triangulator)"
+ icon-id="mesh_hypo_length.png"/>
+
+ <hypothesis type="NumberOfSegments"
+ label-id="Nb. Segments"
+ icon-id="mesh_hypo_segment.png"/>
+
+ <hypothesis type="MaxElementArea"
+ label-id="Max. Triangle Area"
+ icon-id="mesh_hypo_area.png"/>
+
+ <hypothesis type="MaxElementVolume"
+ label-id="Max. Hexahedron or Tetrahedron Volume"
+ icon-id="mesh_hypo_volume.png"/>
+
+ <hypothesis type="NotConformAllowed"
+ label-id="Not Conform Mesh Allowed"
+ icon-id="mesh_hypo_length.png"/>
+ </hypotheses>
+
+ <algorithms>
+
+ <algorithm type="Regular_1D"
+ label-id="Wire discretisation"
+ icon-id="mesh_algo_regular.png"/>
+
+ <algorithm type="MEFISTO_2D"
+ label-id="Triangle (Mefisto)"
+ icon-id="mesh_algo_mefisto.png"/>
+
+ <algorithm type="Quadrangle_2D"
+ label-id="Quadrangle (Mapping)"
+ icon-id="mesh_algo_quad.png"/>
+
+ <algorithm type="Hexa_3D"
+ label-id="Hexahedron (i,j,k)"
+ icon-id="mesh_algo_hexa.png"/>
+ </algorithms>
+</meshers-group>
+
+<meshers-group name="Your Meshers Group"
+ resources=""
+ server-lib=""
+ gui-lib="">
+ <hypotheses>
+
+ <hypothesis type=""
+ label-id=""
+ icon-id=""/>
+ </hypotheses>
+
+ <algorithms>
+
+ <algorithm type=""
+ label-id=""
+ icon-id=""/>
+ </algorithms>
+</meshers-group>
+
+</meshers>
--- /dev/null
+# SMESH OBJECT : interactive object for SMESH visualization
+#
+# Copyright (C) 2003 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
+# CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
+#
+# This library 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.
+#
+# This library 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 this library; if not, write to the Free Software
+# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+#
+# See http://www.opencascade.org/SALOME/ or email : webmaster.salome@opencascade.org
+#
+#
+#
+# File : Makefile.in
+# Module : SMESH
+
+top_srcdir=@top_srcdir@
+top_builddir=../..
+srcdir=@srcdir@
+VPATH=.:@srcdir@:@top_srcdir@/idl:$(top_builddir)/idl
+
+@COMMENCE@
+
+EXPORT_HEADERS = SMESH_Controls.hxx
+
+
+# Libraries targets
+
+LIB = libSMESHControls.la
+LIB_SRC = SMESH_Controls.cxx
+
+# Executables targets
+BIN = SMESHControls
+BIN_SRC =
+
+CPPFLAGS+=$(OCC_INCLUDES) $(BOOST_CPPFLAGS)
+
+LDFLAGS+=$(OCC_KERNEL_LIBS) -L${KERNEL_ROOT_DIR}/lib/salome -lOpUtil -lSMDS
+
+@CONCLUDE@
--- /dev/null
+// Copyright (C) 2003 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
+// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
+//
+// This library 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.
+//
+// This library 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 this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+//
+// See http://www.opencascade.org/SALOME/ or email : webmaster.salome@opencascade.org
+
+#include "SMESH_Controls.hxx"
+
+int main(int argc, char** argv)
+{
+ using namespace SMESH::Controls;
+ new MinimumAngle();
+ new AspectRatio();
+ new Warping();
+ new Taper();
+ new Skew();
+ new Area();
+ new Length();
+ new MultiConnection();
+ new FreeBorders();
+ new LessThan();
+ new MoreThan();
+ new EqualTo();
+ new LogicalNOT();
+ new LogicalAND();
+ new LogicalOR();
+
+ return 1;
+}
--- /dev/null
+// Copyright (C) 2003 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
+// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
+//
+// This library 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.
+//
+// This library 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 this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+//
+// See http://www.opencascade.org/SALOME/ or email : webmaster.salome@opencascade.org
+
+#include <set>
+
+#include <gp_Pnt.hxx>
+#include <gp_Vec.hxx>
+#include <gp_XYZ.hxx>
+#include <Precision.hxx>
+#include <TColgp_SequenceOfXYZ.hxx>
+#include <TColStd_MapOfInteger.hxx>
+
+#include "SMDS_Mesh.hxx"
+#include "SMDS_Iterator.hxx"
+#include "SMDS_MeshElement.hxx"
+#include "SMDS_MeshNode.hxx"
+
+#include "SMESH_Controls.hxx"
+
+/*
+ AUXILIARY METHODS
+*/
+
+static inline double getAngle( const gp_XYZ& P1, const gp_XYZ& P2, const gp_XYZ& P3 )
+{
+ return gp_Vec( P1 - P2 ).Angle( gp_Vec( P3 - P2 ) );
+}
+
+static inline double getArea( const gp_XYZ& P1, const gp_XYZ& P2, const gp_XYZ& P3 )
+{
+ gp_Vec aVec1( P2 - P1 );
+ gp_Vec aVec2( P3 - P1 );
+ return ( aVec1 ^ aVec2 ).Magnitude() * 0.5;
+}
+
+static inline double getArea( const gp_Pnt& P1, const gp_Pnt& P2, const gp_Pnt& P3 )
+{
+ return getArea( P1.XYZ(), P2.XYZ(), P3.XYZ() );
+}
+
+static inline double getDistance( const gp_XYZ& P1, const gp_XYZ& P2 )
+{
+ double aDist = gp_Pnt( P1 ).Distance( gp_Pnt( P2 ) );
+ return aDist;
+}
+
+static int getNbMultiConnection( SMDS_Mesh* theMesh, const int theId )
+{
+ if ( theMesh == 0 )
+ return 0;
+
+ const SMDS_MeshElement* anEdge = theMesh->FindElement( theId );
+ if ( anEdge == 0 || anEdge->GetType() != SMDSAbs_Edge || anEdge->NbNodes() != 2 )
+ return 0;
+
+ TColStd_MapOfInteger aMap;
+
+ int aResult = 0;
+ SMDS_ElemIteratorPtr anIter = anEdge->nodesIterator();
+ if ( anIter != 0 )
+ {
+ while( anIter->more() )
+ {
+ const SMDS_MeshNode* aNode = (SMDS_MeshNode*)anIter->next();
+ if ( aNode == 0 )
+ return 0;
+ SMDS_ElemIteratorPtr anElemIter = aNode->GetInverseElementIterator();
+ while( anElemIter->more() )
+ {
+ const SMDS_MeshElement* anElem = anElemIter->next();
+ if ( anElem != 0 && anElem->GetType() != SMDSAbs_Edge )
+ {
+ int anId = anElem->GetID();
+
+ if ( anIter->more() ) // i.e. first node
+ aMap.Add( anId );
+ else if ( aMap.Contains( anId ) )
+ aResult++;
+ }
+ }
+ }
+ }
+
+ return aResult;
+}
+
+
+using namespace SMESH::Controls;
+
+/*
+ FUNCTORS
+*/
+
+/*
+ Class : NumericalFunctor
+ Description : Base class for numerical functors
+*/
+NumericalFunctor::NumericalFunctor():
+ myMesh(NULL)
+{}
+
+void NumericalFunctor::SetMesh( SMDS_Mesh* theMesh )
+{
+ myMesh = theMesh;
+}
+
+bool NumericalFunctor::getPoints( const int theId,
+ TColgp_SequenceOfXYZ& theRes ) const
+{
+ theRes.Clear();
+
+ if ( myMesh == 0 )
+ return false;
+
+ // Get nodes of the face
+ const SMDS_MeshElement* anElem = myMesh->FindElement( theId );
+ if ( anElem == 0 || anElem->GetType() != GetType() )
+ return false;
+
+ int nbNodes = anElem->NbNodes();
+
+ SMDS_ElemIteratorPtr anIter = anElem->nodesIterator();
+ if ( anIter != 0 )
+ {
+ while( anIter->more() )
+ {
+ const SMDS_MeshNode* aNode = (SMDS_MeshNode*)anIter->next();
+ if ( aNode != 0 )
+ theRes.Append( gp_XYZ( aNode->X(), aNode->Y(), aNode->Z() ) );
+ }
+ }
+
+ return true;
+}
+
+
+/*
+ Class : MinimumAngle
+ Description : Functor for calculation of minimum angle
+*/
+double MinimumAngle::GetValue( long theId )
+{
+ TColgp_SequenceOfXYZ P;
+ if ( !getPoints( theId, P ) || P.Length() != 3 && P.Length() != 4 )
+ return 0;
+
+ double aMin;
+
+ if ( P.Length() == 3 )
+ {
+ double A0 = getAngle( P( 3 ), P( 1 ), P( 2 ) );
+ double A1 = getAngle( P( 1 ), P( 2 ), P( 3 ) );
+ double A2 = getAngle( P( 2 ), P( 3 ), P( 1 ) );
+
+ aMin = Min( A0, Min( A1, A2 ) );
+ }
+ else
+ {
+ double A0 = getAngle( P( 4 ), P( 1 ), P( 2 ) );
+ double A1 = getAngle( P( 1 ), P( 2 ), P( 3 ) );
+ double A2 = getAngle( P( 2 ), P( 3 ), P( 4 ) );
+ double A3 = getAngle( P( 3 ), P( 4 ), P( 1 ) );
+
+ aMin = Min( Min( A0, A1 ), Min( A2, A3 ) );
+ }
+
+ return aMin * 180 / PI;
+}
+
+SMDSAbs_ElementType MinimumAngle::GetType() const
+{
+ return SMDSAbs_Face;
+}
+
+
+/*
+ Class : AspectRatio
+ Description : Functor for calculating aspect ratio
+*/
+double AspectRatio::GetValue( long theId )
+{
+ TColgp_SequenceOfXYZ P;
+ if ( !getPoints( theId, P ) || P.Length() != 3 && P.Length() != 4 )
+ return 0;
+
+ int nbNodes = P.Length();
+
+ // Compute lengths of the sides
+
+ double aLen[ nbNodes ];
+ for ( int i = 0; i < nbNodes - 1; i++ )
+ aLen[ i ] = getDistance( P( i + 1 ), P( i + 2 ) );
+ aLen[ nbNodes - 1 ] = getDistance( P( 1 ), P( nbNodes ) );
+
+ // Compute aspect ratio
+
+ if ( nbNodes == 3 )
+ {
+ double aMaxLen = Max( aLen[ 0 ], Max( aLen[ 1 ], aLen[ 2 ] ) );
+ double anArea = getArea( P( 1 ), P( 2 ), P( 3 ) );
+ static double aCoef = sqrt( 3. ) / 4;
+
+ return anArea != 0 ? aCoef * aMaxLen * aMaxLen / anArea : 0;
+ }
+ else
+ {
+ double aMaxLen = Max( Max( aLen[ 0 ], aLen[ 1 ] ), Max( aLen[ 2 ], aLen[ 3 ] ) );
+ double aMinLen = Min( Min( aLen[ 0 ], aLen[ 1 ] ), Min( aLen[ 2 ], aLen[ 3 ] ) );
+
+ return aMinLen != 0 ? aMaxLen / aMinLen : 0;
+ }
+}
+
+SMDSAbs_ElementType AspectRatio::GetType() const
+{
+ return SMDSAbs_Face;
+}
+
+
+/*
+ Class : Warping
+ Description : Functor for calculating warping
+*/
+double Warping::GetValue( long theId )
+{
+ TColgp_SequenceOfXYZ P;
+ if ( !getPoints( theId, P ) || P.Length() != 4 )
+ return 0;
+
+ gp_XYZ G = ( P( 1 ) + P( 2 ) + P( 3 ) + P( 4 ) ) / 4;
+
+ double A1 = ComputeA( P( 1 ), P( 2 ), P( 3 ), G );
+ double A2 = ComputeA( P( 2 ), P( 3 ), P( 4 ), G );
+ double A3 = ComputeA( P( 3 ), P( 4 ), P( 1 ), G );
+ double A4 = ComputeA( P( 4 ), P( 1 ), P( 2 ), G );
+
+ return Max( Max( A1, A2 ), Max( A3, A4 ) );
+}
+
+double Warping::ComputeA( const gp_XYZ& thePnt1,
+ const gp_XYZ& thePnt2,
+ const gp_XYZ& thePnt3,
+ const gp_XYZ& theG ) const
+{
+ double aLen1 = gp_Pnt( thePnt1 ).Distance( gp_Pnt( thePnt2 ) );
+ double aLen2 = gp_Pnt( thePnt2 ).Distance( gp_Pnt( thePnt3 ) );
+ double L = Min( aLen1, aLen2 ) * 0.5;
+
+ gp_XYZ GI = ( thePnt2 - thePnt1 ) / 2. - theG;
+ gp_XYZ GJ = ( thePnt3 - thePnt2 ) / 2. - theG;
+ gp_XYZ N = GI.Crossed( GJ );
+ N.Normalize();
+
+ double H = gp_Vec( thePnt2 - theG ).Dot( gp_Vec( N ) );
+ return asin( fabs( H / L ) ) * 180 / PI;
+}
+
+SMDSAbs_ElementType Warping::GetType() const
+{
+ return SMDSAbs_Face;
+}
+
+
+/*
+ Class : Taper
+ Description : Functor for calculating taper
+*/
+double Taper::GetValue( long theId )
+{
+ TColgp_SequenceOfXYZ P;
+ if ( !getPoints( theId, P ) || P.Length() != 4 )
+ return 0;
+
+ // Compute taper
+ double J1 = getArea( P( 4 ), P( 1 ), P( 2 ) ) / 2;
+ double J2 = getArea( P( 3 ), P( 1 ), P( 2 ) ) / 2;
+ double J3 = getArea( P( 2 ), P( 3 ), P( 4 ) ) / 2;
+ double J4 = getArea( P( 3 ), P( 4 ), P( 1 ) ) / 2;
+
+ double JA = 0.25 * ( J1 + J2 + J3 + J4 );
+
+ double T1 = fabs( ( J1 - JA ) / JA );
+ double T2 = fabs( ( J2 - JA ) / JA );
+ double T3 = fabs( ( J3 - JA ) / JA );
+ double T4 = fabs( ( J4 - JA ) / JA );
+
+ return Max( Max( T1, T2 ), Max( T3, T4 ) );
+}
+
+SMDSAbs_ElementType Taper::GetType() const
+{
+ return SMDSAbs_Face;
+}
+
+
+/*
+ Class : Skew
+ Description : Functor for calculating skew in degrees
+*/
+static inline double skewAngle( const gp_XYZ& p1, const gp_XYZ& p2, const gp_XYZ& p3 )
+{
+ gp_XYZ p12 = ( p2 + p1 ) / 2;
+ gp_XYZ p23 = ( p3 + p2 ) / 2;
+ gp_XYZ p31 = ( p3 + p1 ) / 2;
+
+ return gp_Vec( p31 - p2 ).Angle( p12 - p23 );
+}
+
+double Skew::GetValue( long theId )
+{
+ TColgp_SequenceOfXYZ P;
+ if ( !getPoints( theId, P ) || P.Length() != 3 && P.Length() != 4 )
+ return 0;
+
+ // Compute skew
+ static double PI2 = PI / 2;
+ if ( P.Length() == 3 )
+ {
+ double A0 = fabs( PI2 - skewAngle( P( 3 ), P( 1 ), P( 2 ) ) );
+ double A1 = fabs( PI2 - skewAngle( P( 1 ), P( 2 ), P( 3 ) ) );
+ double A2 = fabs( PI2 - skewAngle( P( 2 ), P( 3 ), P( 1 ) ) );
+
+ return Max( A0, Max( A1, A2 ) ) * 180 / PI;
+ }
+ else
+ {
+ gp_XYZ p12 = ( P( 1 ) + P( 2 ) ) / 2;
+ gp_XYZ p23 = ( P( 2 ) + P( 3 ) ) / 2;
+ gp_XYZ p34 = ( P( 3 ) + P( 4 ) ) / 2;
+ gp_XYZ p41 = ( P( 4 ) + P( 1 ) ) / 2;
+
+ double A = fabs( PI2 - gp_Vec( p34 - p12 ).Angle( p23 - p41 ) );
+
+ return A * 180 / PI;
+ }
+}
+
+SMDSAbs_ElementType Skew::GetType() const
+{
+ return SMDSAbs_Face;
+}
+
+
+/*
+ Class : Area
+ Description : Functor for calculating area
+*/
+double Area::GetValue( long theId )
+{
+ TColgp_SequenceOfXYZ P;
+ if ( !getPoints( theId, P ) || P.Length() != 3 && P.Length() != 4 )
+ return 0;
+
+ if ( P.Length() == 3 )
+ return getArea( P( 1 ), P( 2 ), P( 3 ) );
+ else
+ return getArea( P( 1 ), P( 2 ), P( 3 ) ) + getArea( P( 1 ), P( 3 ), P( 4 ) );
+}
+
+SMDSAbs_ElementType Area::GetType() const
+{
+ return SMDSAbs_Face;
+}
+
+
+/*
+ Class : Length
+ Description : Functor for calculating length off edge
+*/
+double Length::GetValue( long theId )
+{
+ TColgp_SequenceOfXYZ P;
+ return getPoints( theId, P ) && P.Length() == 2 ? getDistance( P( 1 ), P( 2 ) ) : 0;
+}
+
+SMDSAbs_ElementType Length::GetType() const
+{
+ return SMDSAbs_Edge;
+}
+
+
+/*
+ Class : MultiConnection
+ Description : Functor for calculating number of faces conneted to the edge
+*/
+double MultiConnection::GetValue( long theId )
+{
+ return getNbMultiConnection( myMesh, theId );
+}
+
+SMDSAbs_ElementType MultiConnection::GetType() const
+{
+ return SMDSAbs_Edge;
+}
+
+
+/*
+ PREDICATES
+*/
+
+/*
+ Class : FreeBorders
+ Description : Predicate for free borders
+*/
+
+FreeBorders::FreeBorders()
+{
+ myMesh = 0;
+}
+
+void FreeBorders::SetMesh( SMDS_Mesh* theMesh )
+{
+ myMesh = theMesh;
+}
+
+bool FreeBorders::IsSatisfy( long theId )
+{
+ return getNbMultiConnection( myMesh, theId ) == 1;
+}
+
+SMDSAbs_ElementType FreeBorders::GetType() const
+{
+ return SMDSAbs_Edge;
+}
+
+
+/*
+ Class : FreeEdges
+ Description : Predicate for free Edges
+*/
+FreeEdges::FreeEdges()
+{
+ myMesh = 0;
+}
+
+void FreeEdges::SetMesh( SMDS_Mesh* theMesh )
+{
+ myMesh = theMesh;
+}
+
+bool FreeEdges::IsSatisfy( long theId )
+{
+ return getNbMultiConnection( myMesh, theId ) == 1;
+}
+
+SMDSAbs_ElementType FreeEdges::GetType() const
+{
+ return SMDSAbs_Face;
+}
+
+FreeEdges::Border::Border(long thePntId1, long thePntId2){
+ PntId[0] = thePntId1; PntId[1] = thePntId2;
+ if(thePntId1 > thePntId2){
+ PntId[1] = thePntId1; PntId[0] = thePntId2;
+ }
+}
+
+//bool operator<(const FreeEdges::Border& x, const FreeEdges::Border& y){
+// if(x.PntId[0] < y.PntId[0]) return true;
+// if(x.PntId[0] == y.PntId[0])
+// if(x.PntId[1] < y.PntId[1]) return true;
+// return false;
+//}
+
+namespace SMESH{
+ namespace Controls{
+ struct EdgeBorder: public FreeEdges::Border{
+ long ElemId;
+ EdgeBorder(long theElemId, long thePntId1, long thePntId2):
+ FreeEdges::Border(thePntId1,thePntId2),
+ ElemId(theElemId)
+ {}
+ };
+
+ bool operator<(const FreeEdges::Border& x, const FreeEdges::Border& y){
+ if(x.PntId[0] < y.PntId[0]) return true;
+ if(x.PntId[0] == y.PntId[0])
+ if(x.PntId[1] < y.PntId[1]) return true;
+ return false;
+ }
+
+ typedef std::set<EdgeBorder> EdgeBorderS;
+
+ inline void UpdateBorders(const EdgeBorder& theBorder,
+ EdgeBorderS& theRegistry,
+ EdgeBorderS& theContainer)
+ {
+ if(theRegistry.find(theBorder) == theRegistry.end()){
+ theRegistry.insert(theBorder);
+ theContainer.insert(theBorder);
+ }else{
+ theContainer.erase(theBorder);
+ }
+ }
+
+ }
+}
+
+void FreeEdges::GetBoreders(Borders& theBorders)
+{
+ EdgeBorderS aRegistry;
+ EdgeBorderS aContainer;
+ SMDS_FaceIteratorPtr anIter = myMesh->facesIterator();
+ for(; anIter->more(); ){
+ const SMDS_MeshFace* anElem = anIter->next();
+ long anElemId = anElem->GetID();
+ SMDS_ElemIteratorPtr aNodesIter = anElem->nodesIterator();
+ long aNodeId[2];
+ const SMDS_MeshElement* aNode;
+ if(aNodesIter->more()){
+ aNode = aNodesIter->next();
+ aNodeId[0] = aNodeId[1] = aNode->GetID();
+ }
+ for(; aNodesIter->more(); ){
+ aNode = aNodesIter->next();
+ EdgeBorder aBorder(anElemId,aNodeId[1],aNode->GetID());
+ aNodeId[1] = aNode->GetID();
+ //std::cout<<aBorder.PntId[0]<<"; "<<aBorder.PntId[1]<<"; "<<aBorder.ElemId<<"\n";
+ UpdateBorders(aBorder,aRegistry,aContainer);
+ }
+ EdgeBorder aBorder(anElemId,aNodeId[0],aNodeId[1]);
+ UpdateBorders(aBorder,aRegistry,aContainer);
+ }
+ //std::cout<<"aContainer.size() = "<<aContainer.size()<<"\n";
+ if(aContainer.size()){
+ EdgeBorderS::const_iterator anIter = aContainer.begin();
+ for(; anIter != aContainer.end(); anIter++){
+ const EdgeBorder& aBorder = *anIter;
+ //std::cout<<aBorder.PntId[0]<<"; "<<aBorder.PntId[1]<<"; "<<aBorder.ElemId<<"\n";
+ theBorders.insert(Borders::value_type(aBorder.ElemId,aBorder));
+ }
+ }
+}
+
+
+/*
+ Class : Comparator
+ Description : Base class for comparators
+*/
+Comparator::Comparator():
+ myMargin(0)
+{}
+
+Comparator::~Comparator()
+{}
+
+void Comparator::SetMesh( SMDS_Mesh* theMesh )
+{
+ if ( myFunctor )
+ myFunctor->SetMesh( theMesh );
+}
+
+void Comparator::SetMargin( double theValue )
+{
+ myMargin = theValue;
+}
+
+void Comparator::SetNumFunctor( NumericalFunctorPtr theFunct )
+{
+ myFunctor = theFunct;
+}
+
+SMDSAbs_ElementType Comparator::GetType() const
+{
+ return myFunctor ? myFunctor->GetType() : SMDSAbs_All;
+}
+
+
+/*
+ Class : LessThan
+ Description : Comparator "<"
+*/
+bool LessThan::IsSatisfy( long theId )
+{
+ return myFunctor && myFunctor->GetValue( theId ) < myMargin;
+}
+
+
+/*
+ Class : MoreThan
+ Description : Comparator ">"
+*/
+bool MoreThan::IsSatisfy( long theId )
+{
+ return myFunctor && myFunctor->GetValue( theId ) > myMargin;
+}
+
+
+/*
+ Class : EqualTo
+ Description : Comparator "="
+*/
+EqualTo::EqualTo():
+ myToler(Precision::Confusion())
+{}
+
+bool EqualTo::IsSatisfy( long theId )
+{
+ return myFunctor && fabs( myFunctor->GetValue( theId ) - myMargin ) < myToler;
+}
+
+void EqualTo::SetTolerance( double theToler )
+{
+ myToler = theToler;
+}
+
+
+/*
+ Class : LogicalNOT
+ Description : Logical NOT predicate
+*/
+LogicalNOT::LogicalNOT()
+{}
+
+LogicalNOT::~LogicalNOT()
+{}
+
+bool LogicalNOT::IsSatisfy( long theId )
+{
+ return myPredicate && !myPredicate->IsSatisfy( theId );
+}
+
+void LogicalNOT::SetMesh( SMDS_Mesh* theMesh )
+{
+ if ( myPredicate )
+ myPredicate->SetMesh( theMesh );
+}
+
+void LogicalNOT::SetPredicate( PredicatePtr thePred )
+{
+ myPredicate = thePred;
+}
+
+SMDSAbs_ElementType LogicalNOT::GetType() const
+{
+ return myPredicate ? myPredicate->GetType() : SMDSAbs_All;
+}
+
+
+/*
+ Class : LogicalBinary
+ Description : Base class for binary logical predicate
+*/
+LogicalBinary::LogicalBinary()
+{}
+
+LogicalBinary::~LogicalBinary()
+{}
+
+void LogicalBinary::SetMesh( SMDS_Mesh* theMesh )
+{
+ if ( myPredicate1 )
+ myPredicate1->SetMesh( theMesh );
+
+ if ( myPredicate2 )
+ myPredicate2->SetMesh( theMesh );
+}
+
+void LogicalBinary::SetPredicate1( PredicatePtr thePredicate )
+{
+ myPredicate1 = thePredicate;
+}
+
+void LogicalBinary::SetPredicate2( PredicatePtr thePredicate )
+{
+ myPredicate2 = thePredicate;
+}
+
+SMDSAbs_ElementType LogicalBinary::GetType() const
+{
+ if ( !myPredicate1 || !myPredicate2 )
+ return SMDSAbs_All;
+
+ SMDSAbs_ElementType aType1 = myPredicate1->GetType();
+ SMDSAbs_ElementType aType2 = myPredicate2->GetType();
+
+ return aType1 == aType2 ? aType1 : SMDSAbs_All;
+}
+
+
+/*
+ Class : LogicalAND
+ Description : Logical AND
+*/
+bool LogicalAND::IsSatisfy( long theId )
+{
+ return
+ myPredicate1 &&
+ myPredicate2 &&
+ myPredicate1->IsSatisfy( theId ) &&
+ myPredicate2->IsSatisfy( theId );
+}
+
+
+/*
+ Class : LogicalOR
+ Description : Logical OR
+*/
+bool LogicalOR::IsSatisfy( long theId )
+{
+ return
+ myPredicate1 &&
+ myPredicate2 &&
+ myPredicate1->IsSatisfy( theId ) ||
+ myPredicate2->IsSatisfy( theId );
+}
+
+
+/*
+ FILTER
+*/
+
+Filter::Filter()
+{}
+
+Filter::~Filter()
+{}
+
+void Filter::SetPredicate( PredicatePtr thePredicate )
+{
+ myPredicate = thePredicate;
+}
+
+Filter::TIdSequence
+Filter::GetElementsId( SMDS_Mesh* theMesh )
+{
+ TIdSequence aSequence;
+ if ( !theMesh || !myPredicate ) return aSequence;
+
+ myPredicate->SetMesh( theMesh );
+
+ SMDSAbs_ElementType aType = myPredicate->GetType();
+ switch(aType){
+ case SMDSAbs_Edge:{
+ SMDS_EdgeIteratorPtr anIter = theMesh->edgesIterator();
+ if ( anIter != 0 ) {
+ while( anIter->more() ) {
+ const SMDS_MeshElement* anElem = anIter->next();
+ long anId = anElem->GetID();
+ if ( myPredicate->IsSatisfy( anId ) )
+ aSequence.push_back( anId );
+ }
+ }
+ }
+ case SMDSAbs_Face:{
+ SMDS_FaceIteratorPtr anIter = theMesh->facesIterator();
+ if ( anIter != 0 ) {
+ while( anIter->more() ) {
+ const SMDS_MeshElement* anElem = anIter->next();
+ long anId = anElem->GetID();
+ if ( myPredicate->IsSatisfy( anId ) )
+ aSequence.push_back( anId );
+ }
+ }
+ }
+ }
+ return aSequence;
+}
--- /dev/null
+// Copyright (C) 2003 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
+// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
+//
+// This library 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.
+//
+// This library 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 this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+//
+// See http://www.opencascade.org/SALOME/ or email : webmaster.salome@opencascade.org
+
+#ifndef _SMESH_CONTROLS_HXX_
+#define _SMESH_CONTROLS_HXX_
+
+#include <map>
+#include <vector>
+#include <boost/shared_ptr.hpp>
+#include "SMDSAbs_ElementType.hxx"
+
+class SMDS_Mesh;
+class gp_Pnt;
+class gp_XYZ;
+class TColgp_SequenceOfXYZ;
+
+namespace SMESH{
+ namespace Controls{
+ class Functor{
+ public:
+ ~Functor(){}
+ virtual void SetMesh( SMDS_Mesh* theMesh ) = 0;
+ };
+ typedef boost::shared_ptr<Functor> FunctorPtr;
+
+ class NumericalFunctor: public virtual Functor{
+ public:
+ NumericalFunctor();
+ virtual void SetMesh( SMDS_Mesh* theMesh );
+ virtual double GetValue( long theElementId ) = 0;
+ virtual SMDSAbs_ElementType GetType() const = 0;
+
+ protected:
+ bool getPoints( const int theId,
+ TColgp_SequenceOfXYZ& theRes ) const;
+ protected:
+ SMDS_Mesh* myMesh;
+ };
+ typedef boost::shared_ptr<NumericalFunctor> NumericalFunctorPtr;
+
+
+ /*
+ Class : SMESH_MinimumAngle
+ Description : Functor for calculation of minimum angle
+ */
+ class MinimumAngle: public virtual NumericalFunctor{
+ public:
+ virtual double GetValue( long theElementId );
+ virtual SMDSAbs_ElementType GetType() const;
+ };
+
+
+ /*
+ Class : AspectRatio
+ Description : Functor for calculating aspect ratio
+ */
+ class AspectRatio: public virtual NumericalFunctor{
+ public:
+ virtual double GetValue( long theElementId );
+ virtual SMDSAbs_ElementType GetType() const;
+ };
+
+
+ /*
+ Class : Warping
+ Description : Functor for calculating warping
+ */
+ class Warping: public virtual NumericalFunctor{
+ public:
+ virtual double GetValue( long theElementId );
+ virtual SMDSAbs_ElementType GetType() const;
+
+ private:
+ double ComputeA( const gp_XYZ&, const gp_XYZ&,
+ const gp_XYZ&, const gp_XYZ& ) const;
+ };
+
+
+ /*
+ Class : Taper
+ Description : Functor for calculating taper
+ */
+ class Taper: public virtual NumericalFunctor{
+ public:
+ virtual double GetValue( long theElementId );
+ virtual SMDSAbs_ElementType GetType() const;
+ };
+
+
+ /*
+ Class : Skew
+ Description : Functor for calculating skew in degrees
+ */
+ class Skew: public virtual NumericalFunctor{
+ public:
+ virtual double GetValue( long theElementId );
+ virtual SMDSAbs_ElementType GetType() const;
+ };
+
+
+ /*
+ Class : Area
+ Description : Functor for calculating area
+ */
+ class Area: public virtual NumericalFunctor{
+ public:
+ virtual double GetValue( long theElementId );
+ virtual SMDSAbs_ElementType GetType() const;
+ };
+
+
+ /*
+ Class : Length
+ Description : Functor for calculating length of edge
+ */
+ class Length: public virtual NumericalFunctor{
+ public:
+ virtual double GetValue( long theElementId );
+ virtual SMDSAbs_ElementType GetType() const;
+ };
+
+
+ /*
+ Class : MultiConnection
+ Description : Functor for calculating number of faces conneted to the edge
+ */
+ class MultiConnection: public virtual NumericalFunctor{
+ public:
+ virtual double GetValue( long theElementId );
+ virtual SMDSAbs_ElementType GetType() const;
+ };
+
+
+ /*
+ PREDICATES
+ */
+ /*
+ Class : Predicate
+ Description : Base class for all predicates
+ */
+ class Predicate: public virtual Functor{
+ public:
+ virtual bool IsSatisfy( long theElementId ) = 0;
+ virtual SMDSAbs_ElementType GetType() const = 0;
+ };
+ typedef boost::shared_ptr<Predicate> PredicatePtr;
+
+
+
+ /*
+ Class : FreeBorders
+ Description : Predicate for free borders
+ */
+ class FreeBorders: public virtual Predicate{
+ public:
+ FreeBorders();
+ virtual void SetMesh( SMDS_Mesh* theMesh );
+ virtual bool IsSatisfy( long theElementId );
+ virtual SMDSAbs_ElementType GetType() const;
+
+ protected:
+ SMDS_Mesh* myMesh;
+ };
+
+
+ /*
+ Class : FreeEdges
+ Description : Predicate for free Edges
+ */
+ class FreeEdges: public virtual Predicate{
+ public:
+ FreeEdges();
+ virtual void SetMesh( SMDS_Mesh* theMesh );
+ virtual bool IsSatisfy( long theElementId );
+ virtual SMDSAbs_ElementType GetType() const;
+ struct Border{
+ long PntId[2];
+ Border(long thePntId1, long thePntId2);
+ };
+ typedef long TElemId;
+ typedef std::map<TElemId,Border> Borders;
+ void GetBoreders(Borders& theBorders);
+
+ protected:
+ SMDS_Mesh* myMesh;
+ };
+ typedef boost::shared_ptr<FreeEdges> FreeEdgesPtr;
+
+
+ /*
+ Class : Comparator
+ Description : Base class for comparators
+ */
+ class Comparator: public virtual Predicate{
+ public:
+ Comparator();
+ virtual ~Comparator();
+ virtual void SetMesh( SMDS_Mesh* theMesh );
+ virtual void SetMargin(double theValue);
+ virtual void SetNumFunctor(NumericalFunctorPtr theFunct);
+ virtual bool IsSatisfy( long theElementId ) = 0;
+ virtual SMDSAbs_ElementType GetType() const;
+
+ protected:
+ double myMargin;
+ NumericalFunctorPtr myFunctor;
+ };
+ typedef boost::shared_ptr<Comparator> ComparatorPtr;
+
+
+ /*
+ Class : LessThan
+ Description : Comparator "<"
+ */
+ class LessThan: public virtual Comparator{
+ public:
+ virtual bool IsSatisfy( long theElementId );
+ };
+
+
+ /*
+ Class : MoreThan
+ Description : Comparator ">"
+ */
+ class MoreThan: public virtual Comparator{
+ public:
+ virtual bool IsSatisfy( long theElementId );
+ };
+
+
+ /*
+ Class : EqualTo
+ Description : Comparator "="
+ */
+ class EqualTo: public virtual Comparator{
+ public:
+ EqualTo();
+ virtual bool IsSatisfy( long theElementId );
+ virtual void SetTolerance( double theTol );
+
+ private:
+ double myToler;
+ };
+ typedef boost::shared_ptr<EqualTo> EqualToPtr;
+
+
+ /*
+ Class : LogicalNOT
+ Description : Logical NOT predicate
+ */
+ class LogicalNOT: public virtual Predicate{
+ public:
+ LogicalNOT();
+ virtual ~LogicalNOT();
+ virtual bool IsSatisfy( long theElementId );
+ virtual void SetMesh( SMDS_Mesh* theMesh );
+ virtual void SetPredicate(PredicatePtr thePred);
+ virtual SMDSAbs_ElementType GetType() const;
+
+ private:
+ PredicatePtr myPredicate;
+ };
+ typedef boost::shared_ptr<LogicalNOT> LogicalNOTPtr;
+
+
+ /*
+ Class : LogicalBinary
+ Description : Base class for binary logical predicate
+ */
+ class LogicalBinary: public virtual Predicate{
+ public:
+ LogicalBinary();
+ virtual ~LogicalBinary();
+ virtual void SetMesh( SMDS_Mesh* theMesh );
+ virtual void SetPredicate1(PredicatePtr thePred);
+ virtual void SetPredicate2(PredicatePtr thePred);
+ virtual SMDSAbs_ElementType GetType() const;
+
+ protected:
+ PredicatePtr myPredicate1;
+ PredicatePtr myPredicate2;
+ };
+ typedef boost::shared_ptr<LogicalBinary> LogicalBinaryPtr;
+
+
+ /*
+ Class : LogicalAND
+ Description : Logical AND
+ */
+ class LogicalAND: public virtual LogicalBinary{
+ public:
+ virtual bool IsSatisfy( long theElementId );
+ };
+
+
+ /*
+ Class : LogicalOR
+ Description : Logical OR
+ */
+ class LogicalOR: public virtual LogicalBinary{
+ public:
+ virtual bool IsSatisfy( long theElementId );
+ };
+
+
+ /*
+ FILTER
+ */
+ class Filter{
+ public:
+ Filter();
+ virtual ~Filter();
+ virtual void SetPredicate(PredicatePtr thePred);
+ typedef std::vector<long> TIdSequence;
+ virtual TIdSequence GetElementsId( SMDS_Mesh* theMesh );
+
+ protected:
+ PredicatePtr myPredicate;
+ };
+ };
+};
+
+
+#endif
{
myDocument = aDoc;
}
-
-void Document_Reader::Read()
-{
- int myMeshId = myDocument->NewMesh();
- SMDS_Mesh * myMesh = myDocument->GetMesh(myMeshId);
- myReader->SetMesh(myMesh);
- myReader->SetFile(myFile);
- myReader->Read();
-}
-
-Document_Reader::Document_Reader(Mesh_Reader* reader): myReader(reader)
-{
-}
#define _INCLUDE_DOCUMENT_READER
#include "SMESHDS_Document.hxx"
-#include "Mesh_Reader.h"
#include <string>
class Document_Reader
{
public:
- virtual void Read();
+ virtual void Read() = 0;
void SetFile(string);
void SetDocument(SMESHDS_Document *);
- Document_Reader(Mesh_Reader*);
protected:
- SMESHDS_Document * myDocument;
+ SMESHDS_Document * myDocument;
string myFile;
-
- private:
- Mesh_Reader* myReader;
};
#endif
// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
//
// See http://www.opencascade.org/SALOME/ or email : webmaster.salome@opencascade.org
+//
+//
+//
+// File : Document_Writer.cxx
+// Module : SMESH
+using namespace std;
#include "Document_Writer.h"
-#include "utilities.h"
void Document_Writer::SetFile(string aFile)
{
{
myDocument = aDoc;
}
-
-void Document_Writer::Write()
-{
- SCRUTE(myFile);
- SMESHDS_Mesh * myMesh;
- int nb_of_meshes = myDocument->NbMeshes(); //voir avec Yves
- SCRUTE(nb_of_meshes);
-
- int numero = 0;
-
- myDocument->InitMeshesIterator();
- while(myDocument->MoreMesh())
- {
- numero++;
- myMesh = myDocument->NextMesh();
- myWriter->SetMesh(myMesh);
- myWriter->SetFile(myFile);
- myWriter->SetMeshId(numero);
- myWriter->Add();
- }
-}
-
-Document_Writer::Document_Writer(Mesh_Writer* writer): myWriter(writer)
-{
-}
#define _INCLUDE_DOCUMENT_WRITER
#include "SMESHDS_Document.hxx"
-#include "Mesh_Writer.h"
#include <string>
class Document_Writer
{
- public:virtual void Write();
+ public:virtual void Write() = 0;
void SetFile(string);
void SetDocument(SMESHDS_Document *);
- Document_Writer(Mesh_Writer* );
- protected:
- SMESHDS_Document * myDocument;
+ protected: SMESHDS_Document * myDocument;
string myFile;
- Mesh_Writer * myWriter;
};
#endif
--- /dev/null
+// Copyright (C) 2003 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
+// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
+//
+// This library 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.
+//
+// This library 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 this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+//
+// See http://www.opencascade.org/SALOME/ or email : webmaster.salome@opencascade.org
+
+#include "Driver_Document.h"
+
+Driver_Document::Driver_Document():
+ myDocument(NULL)
+{}
+
+
+void Driver_Document::SetFile(const std::string& theFileName)
+{
+ myFile = theFileName;
+}
+
+
+void Driver_Document::SetDocument(SMESHDS_Document * theDocument)
+{
+ myDocument = theDocument;
+}
--- /dev/null
+// Copyright (C) 2003 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
+// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
+//
+// This library 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.
+//
+// This library 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 this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+//
+// See http://www.opencascade.org/SALOME/ or email : webmaster.salome@opencascade.org
+
+#ifndef _INCLUDE_DRIVER_DOCUMENT
+#define _INCLUDE_DRIVER_DOCUMENT
+
+#include <string>
+
+class SMESHDS_Document;
+
+class Driver_Document
+{
+ public:
+ Driver_Document();
+ virtual ~Driver_Document(){}
+
+ virtual void Perform() = 0;
+ void SetFile(const std::string& theFileName);
+ void SetDocument(SMESHDS_Document *theDocument);
+
+ protected:
+ SMESHDS_Document * myDocument;
+ std::string myFile;
+
+};
+
+
+#endif
--- /dev/null
+// SMESH Driver : implementaion of driver for reading and writing
+//
+// Copyright (C) 2003 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
+// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
+//
+// This library 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.
+//
+// This library 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 this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+//
+// See http://www.opencascade.org/SALOME/ or email : webmaster.salome@opencascade.org
+//
+//
+//
+// File : Mesh_Reader.cxx
+// Module : SMESH
+
+#include "Driver_Mesh.h"
+
+using namespace std;
+
+Driver_Mesh::Driver_Mesh():
+ myFile(""),
+ myMeshId(-1)
+{}
+
+
+void Driver_Mesh::SetMeshId(int theMeshId)
+{
+ myMeshId = theMeshId;
+}
+
+
+void Driver_Mesh::SetFile(const std::string& theFileName)
+{
+ myFile = theFileName;
+}
--- /dev/null
+// SMESH Driver : implementaion of driver for reading and writing
+//
+// Copyright (C) 2003 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
+// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
+//
+// This library 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.
+//
+// This library 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 this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+//
+// See http://www.opencascade.org/SALOME/ or email : webmaster.salome@opencascade.org
+//
+//
+//
+// File : Mesh_Reader.h
+// Module : SMESH
+
+#ifndef _INCLUDE_DRIVER_MESH
+#define _INCLUDE_DRIVER_MESH
+
+#include <string>
+
+class Driver_Mesh
+{
+ public:
+ Driver_Mesh();
+ virtual ~Driver_Mesh(){}
+
+ enum Status {
+ DRS_OK,
+ DRS_EMPTY, // a file contains no mesh with the given name
+ DRS_WARN_RENUMBER, // a file has overlapped ranges of element numbers,
+ // so the numbers from the file are ignored
+ DRS_WARN_SKIP_ELEM, // some elements were skipped due to incorrect file data
+ DRS_FAIL // general failure (exception etc.)
+ };
+
+ virtual Status Perform() = 0;
+ void SetMeshId(int theMeshId);
+ void SetFile(const std::string& theFileName);
+
+ protected:
+ std::string myFile;
+ int myMeshId;
+
+};
+
+#endif
--- /dev/null
+// Copyright (C) 2003 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
+// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
+//
+// This library 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.
+//
+// This library 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 this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+//
+// See http://www.opencascade.org/SALOME/ or email : webmaster.salome@opencascade.org
+
+#include "Driver_SMDS_Mesh.h"
+
+using namespace std;
+
+Driver_SMDS_Mesh::Driver_SMDS_Mesh():
+ myMesh(NULL)
+{}
+
+void Driver_SMDS_Mesh::SetMesh(SMDS_Mesh *theMesh)
+{
+ myMesh = theMesh;
+}
--- /dev/null
+// Copyright (C) 2003 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
+// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
+//
+// This library 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.
+//
+// This library 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 this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+//
+// See http://www.opencascade.org/SALOME/ or email : webmaster.salome@opencascade.org
+
+#ifndef _INCLUDE_DRIVER_SMDS_MESH
+#define _INCLUDE_DRIVER_SMDS_MESH
+
+#include "Driver_Mesh.h"
+
+class SMDS_Mesh;
+
+class Driver_SMDS_Mesh: public Driver_Mesh
+{
+ public:
+ Driver_SMDS_Mesh();
+ void SetMesh(SMDS_Mesh *theMesh);
+
+ protected:
+ SMDS_Mesh *myMesh;
+
+};
+
+#endif
--- /dev/null
+// Copyright (C) 2003 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
+// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
+//
+// This library 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.
+//
+// This library 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 this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+//
+// See http://www.opencascade.org/SALOME/ or email : webmaster.salome@opencascade.org
+
+#include "Driver_SMESHDS_Mesh.h"
+
+using namespace std;
+
+Driver_SMESHDS_Mesh::Driver_SMESHDS_Mesh():
+ myMesh(NULL)
+{}
+
+void Driver_SMESHDS_Mesh::SetMesh(SMESHDS_Mesh *theMesh)
+{
+ myMesh = theMesh;
+}
--- /dev/null
+// Copyright (C) 2003 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
+// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
+//
+// This library 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.
+//
+// This library 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 this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+//
+// See http://www.opencascade.org/SALOME/ or email : webmaster.salome@opencascade.org
+
+#ifndef _INCLUDE_DRIVER_SMESHDS_MESH
+#define _INCLUDE_DRIVER_SMESHDS_MESH
+
+#include "Driver_Mesh.h"
+
+class SMESHDS_Mesh;
+
+class Driver_SMESHDS_Mesh: public Driver_Mesh
+{
+ public:
+ Driver_SMESHDS_Mesh();
+ void SetMesh(SMESHDS_Mesh *theMesh);
+
+ protected:
+ SMESHDS_Mesh *myMesh;
+
+};
+
+#endif
@COMMENCE@
# header files
-EXPORT_HEADERS = \
- SMESHDriver.h \
- Document_Reader.h \
- Document_Writer.h \
- Mesh_Reader.h \
- Mesh_Writer.h
+EXPORT_HEADERS= Document_Reader.h Document_Writer.h Mesh_Reader.h Mesh_Writer.h
# Libraries targets
LIB = libMeshDriver.la
-LIB_SRC = \
- SMESHDriver.cxx \
- Document_Reader.cxx \
- Document_Writer.cxx
-# Mesh_Reader.cxx \
-# Mesh_Writer.cxx \
+LIB_SRC = Document_Reader.cxx Document_Writer.cxx Mesh_Reader.cxx Mesh_Writer.cxx
LIB_CLIENT_IDL =
LIB_SERVER_IDL =
# additionnal information to compil and link file
-CPPFLAGS += $(OCC_INCLUDES) -I${KERNEL_ROOT_DIR}/include/salome
+CPPFLAGS += $(OCC_INCLUDES) -I${KERNEL_ROOT_DIR}/include/salome $(BOOST_CPPFLAGS)
CXXFLAGS += $(OCC_CXXFLAGS) $(MED2_INCLUDES) -rdynamic -ldl -I${KERNEL_ROOT_DIR}/include/salome
LDFLAGS += $(MED2_LIBS) -lSMESHDS -lSMDS
-// SMESH Driver : implementation of driver for reading and writing
+// SMESH Driver : implementaion of driver for reading and writing
//
// Copyright (C) 2003 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
//
// See http://www.opencascade.org/SALOME/ or email : webmaster.salome@opencascade.org
+//
+//
+//
+// File : SMESHDriver.cxx
+// Module : SMESH
+using namespace std;
#include "SMESHDriver.h"
#include <dlfcn.h>
#include <utilities.h>
-Document_Reader* SMESHDriver::GetDocumentReader(string Extension)
-{
- // if there is not document reader in the driver create a default
- // one with the mesh reader.
- Document_Reader * docReader=
- (Document_Reader*)getMeshDocumentDriver(Extension);
-
- if(docReader==NULL)
- {
- Mesh_Reader * reader=GetMeshReader(Extension);
- if(reader==NULL)
- {
- MESSAGE("No driver known for this extension");
- return NULL;
- }
- return new Document_Reader(reader);
- }
- else return docReader;
-}
+//A enlever
+#include "DriverMED_R_SMESHDS_Document.h"
+#include "DriverMED_R_SMESHDS_Mesh.h"
+#include "DriverMED_R_SMDS_Mesh.h"
+#include "DriverMED_W_SMESHDS_Document.h"
+#include "DriverMED_W_SMESHDS_Mesh.h"
+#include "DriverMED_W_SMDS_Mesh.h"
+
+#include "DriverDAT_R_SMESHDS_Document.h"
+#include "DriverDAT_R_SMESHDS_Mesh.h"
+#include "DriverDAT_R_SMDS_Mesh.h"
+#include "DriverDAT_W_SMESHDS_Document.h"
+#include "DriverDAT_W_SMESHDS_Mesh.h"
+#include "DriverDAT_W_SMDS_Mesh.h"
+//
+
+Document_Reader* SMESHDriver::GetDocumentReader(string Extension, string Class) {
+ if (Extension==string("MED")) {
+ DriverMED_R_SMESHDS_Document* myDriver = new DriverMED_R_SMESHDS_Document();
+ return (myDriver);
+ }
+ else if (Extension==string("DAT")) {
+ DriverDAT_R_SMESHDS_Document* myDriver = new DriverDAT_R_SMESHDS_Document();
+ return (myDriver);
+ }
+ else {
+ MESSAGE("No driver known for this extension");
+ return (Document_Reader*)NULL;
+ }
-Document_Writer* SMESHDriver::GetDocumentWriter(string Extension)
-{
- Mesh_Writer * writer=GetMeshWriter(Extension);
- if(writer==NULL)
- {
- MESSAGE("No driver known for this extension");
- return NULL;
- }
- return new Document_Writer(writer);
-}
-Mesh_Reader* SMESHDriver::GetMeshReader(string extension)
-{
- void * driver = getMeshDriver(extension, string("Reader"));
- return (Mesh_Reader*)driver;
}
-Mesh_Writer* SMESHDriver::GetMeshWriter(string extension)
-{
- void * driver = getMeshDriver(extension, string("Writer"));
- return (Mesh_Writer*)driver;
+Document_Writer* SMESHDriver::GetDocumentWriter(string Extension, string Class) {
+ if (Extension==string("MED")) {
+ DriverMED_W_SMESHDS_Document* myDriver = new DriverMED_W_SMESHDS_Document();
+ return (myDriver);
+ }
+ else if (Extension==string("DAT")) {
+ DriverDAT_W_SMESHDS_Document* myDriver = new DriverDAT_W_SMESHDS_Document();
+ return (myDriver);
+ }
+ else {
+ MESSAGE("No driver known for this extension");
+ return (Document_Writer*)NULL;
+ }
+
+
}
-void * SMESHDriver::getMeshDriver(string extension, string type)
-{
- string libName = string("libMeshDriver")+extension+string(".so");
- void * handle = dlopen(libName.c_str(), RTLD_LAZY);
- if(!handle)
- {
- cerr << dlerror() << endl;
- return NULL;
- }
- else
- {
- void * (*factory)();
- string symbol = string("SMESH_create")+extension+string("Mesh")+type;
- factory = (void * (*)()) dlsym(handle, symbol.c_str());
- if(factory==NULL)
- {
- cerr << dlerror() << endl;
- return NULL;
- }
- else return factory();
- }
+Mesh_Reader* SMESHDriver::GetMeshReader(string Extension, string Class) {
+ if (Extension==string("MED")) {
+
+ if (strcmp(Class.c_str(),"SMESHDS_Mesh")==0) {
+ DriverMED_R_SMESHDS_Mesh* myDriver = new DriverMED_R_SMESHDS_Mesh();
+ return (myDriver);
+ }
+ else if (strcmp(Class.c_str(),"SMDS_Mesh")==0) {
+ DriverMED_R_SMDS_Mesh* myDriver = new DriverMED_R_SMDS_Mesh();
+ return (myDriver);
+ }
+
+ }
+ else if (Extension==string("DAT")) {
+
+ if (strcmp(Class.c_str(),"SMESHDS_Mesh")==0) {
+ DriverDAT_R_SMESHDS_Mesh* myDriver = new DriverDAT_R_SMESHDS_Mesh();
+ return (myDriver);
+ }
+ else if (strcmp(Class.c_str(),"SMDS_Mesh")==0) {
+ DriverDAT_R_SMDS_Mesh* myDriver = new DriverDAT_R_SMDS_Mesh();
+ return (myDriver);
+ }
+
+ }
+
+
}
-void * SMESHDriver::getMeshDocumentDriver(string extension)
-{
- string libName = string("libMeshDriver")+extension+string(".so");
- void * handle = dlopen(libName.c_str(), RTLD_LAZY);
- if(!handle)
- {
- cerr << dlerror() << endl;
- return NULL;
- }
- else
- {
- void * (*factory)();
- string symbol = string("SMESH_create")+extension+string("DocumentReader");
- factory = (void * (*)()) dlsym(handle, symbol.c_str());
- if(factory==NULL)
- {
- cerr << dlerror() << endl;
- return NULL;
- }
- else return factory();
- }
+Mesh_Writer* SMESHDriver::GetMeshWriter(string Extension, string Class) {
+ if (Extension==string("MED")) {
+
+ if (strcmp(Class.c_str(),"SMESHDS_Mesh")==0) {
+ DriverMED_W_SMESHDS_Mesh* myDriver = new DriverMED_W_SMESHDS_Mesh();
+ return (myDriver);
+ }
+ else if (strcmp(Class.c_str(),"SMDS_Mesh")==0) {
+ DriverMED_W_SMDS_Mesh* myDriver = new DriverMED_W_SMDS_Mesh();
+ return (myDriver);
+ }
+
+ }
+ else if (Extension==string("DAT")) {
+
+ if (strcmp(Class.c_str(),"SMESHDS_Mesh")==0) {
+ DriverDAT_W_SMESHDS_Mesh* myDriver = new DriverDAT_W_SMESHDS_Mesh();
+ return (myDriver);
+ }
+ else if (strcmp(Class.c_str(),"SMDS_Mesh")==0) {
+ DriverDAT_W_SMDS_Mesh* myDriver = new DriverDAT_W_SMDS_Mesh();
+ return (myDriver);
+ }
+
+ }
+
}
+
#include "Mesh_Reader.h"
#include "Mesh_Writer.h"
-class SMESHDriver
-{
+class SMESHDriver {
+
public :
- static Document_Reader* GetDocumentReader(string Extension);
- static Document_Writer* GetDocumentWriter(string Extension);
+ static Document_Reader* GetDocumentReader(string Extension, string Class);
+ static Document_Writer* GetDocumentWriter(string Extension, string Class);
- static Mesh_Reader* GetMeshReader(string Extension);
- static Mesh_Writer* GetMeshWriter(string Extension);
+ static Mesh_Reader* GetMeshReader(string Extension, string Class);
+ static Mesh_Writer* GetMeshWriter(string Extension, string Class);
- private:
- static void * getMeshDriver(string Extension, string type);
- static void * getMeshDocumentDriver(string Extension);
};
#endif
--- /dev/null
+// Copyright (C) 2003 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
+// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
+//
+// This library 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.
+//
+// This library 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 this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+//
+// See http://www.opencascade.org/SALOME/ or email : webmaster.salome@opencascade.org
+
+#include "DriverDAT_R_SMDS_Mesh.h"
+#include "DriverDAT_W_SMDS_Mesh.h"
+
+int main(int argc, char** argv)
+{
+ DriverDAT_R_SMDS_Mesh aR;
+ DriverDAT_W_SMDS_Mesh aW;
+ return 1;
+}
// File : DriverDAT_R_SMDS_Mesh.cxx
// Module : SMESH
+using namespace std;
#include "DriverDAT_R_SMDS_Mesh.h"
-#include "utilities.h"
-
-extern "C"
-{
-/**
- * Factory function which will be called by SMESHDriver
- */
-void * SMESH_createDATMeshReader()
-{
- return new DriverDAT_R_SMDS_Mesh();
-}
-}
+#include "utilities.h"
DriverDAT_R_SMDS_Mesh::DriverDAT_R_SMDS_Mesh()
{
// File : DriverDAT_W_SMDS_Mesh.cxx
// Module : SMESH
+using namespace std;
#include "DriverDAT_W_SMDS_Mesh.h"
+
#include "SMDS_MeshElement.hxx"
#include "SMDS_MeshNode.hxx"
-#include "utilities.h"
-extern "C"
-{
-
-/**
- * Factory function which will be called by SMESHDriver
- */
-void * SMESH_createDATMeshWriter()
-{
- return new DriverDAT_W_SMDS_Mesh();
-}
-}
+#include "utilities.h"
DriverDAT_W_SMDS_Mesh::DriverDAT_W_SMDS_Mesh()
{
+ ;
}
DriverDAT_W_SMDS_Mesh::~DriverDAT_W_SMDS_Mesh()
void DriverDAT_W_SMDS_Mesh::Add()
{
- MESSAGE("Adding a mesh to a DAT document. As DAT do not support more than one mesh in a file, the previous mesh is deleted");
- Write();
+ ;
}
void DriverDAT_W_SMDS_Mesh::Write()
{
+
int nbNodes, nbCells;
int i;
fprintf(stderr, ">> ERREUR : ouverture du fichier %s \n", file2Read);
exit(EXIT_FAILURE);
}
-
+ SCRUTE(myMesh);
/****************************************************************************
* NOMBRES D'OBJETS *
****************************************************************************/
nb_of_faces = myMesh->NbFaces();
nb_of_volumes = myMesh->NbVolumes();
nbCells = nb_of_edges + nb_of_faces + nb_of_volumes;
+ SCRUTE(nb_of_edges);
+ SCRUTE(nb_of_faces);
+ SCRUTE(nb_of_volumes);
fprintf(stdout, "%d %d\n", nbNodes, nbCells);
fprintf(myFileId, "%d %d\n", nbNodes, nbCells);
fprintf(stdout, "(* NOEUDS DU MAILLAGE : *)\n");
fprintf(stdout, "(************************)\n");
- SMDS_Iterator<const SMDS_MeshNode *> * itNodes=myMesh->nodesIterator();
+ SMDS_NodeIteratorPtr itNodes=myMesh->nodesIterator();
while(itNodes->more())
{
const SMDS_MeshNode * node = itNodes->next();
fprintf(myFileId, "%d %e %e %e\n", node->GetID(), node->X(),
node->Y(), node->Z());
}
- delete itNodes;
-
+
/****************************************************************************
* ECRITURE DES ELEMENTS *
****************************************************************************/
fprintf(stdout, "(**************************)");
/* Ecriture des connectivites, noms, numeros des mailles */
- SMDS_Iterator<const SMDS_MeshEdge*> * itEdges=myMesh->edgesIterator();
+ SMDS_EdgeIteratorPtr itEdges=myMesh->edgesIterator();
while(itEdges->more())
{
- const SMDS_MeshEdge * elem = itEdges->next();
+ const SMDS_MeshElement * elem = itEdges->next();
switch (elem->NbNodes())
{
}
}
- SMDS_Iterator<const SMDS_MeshElement *> * itNodes=elem->nodesIterator();
- while(itNodes->more())
- fprintf(myFileId, "%d ", itNodes->next()->GetID());
-
+ SMDS_ElemIteratorPtr it=elem->nodesIterator();
+ while(it->more()) fprintf(myFileId, "%d ", it->next()->GetID());
+
fprintf(myFileId, "\n");
}
- delete itEdges;
- SMDS_Iterator<const SMDS_MeshFace *> * itFaces=myMesh->facesIterator();
+ SMDS_FaceIteratorPtr itFaces=myMesh->facesIterator();
while(itFaces->more())
{
const SMDS_MeshElement * elem = itFaces->next();
}
}
- SMDS_Iterator<const SMDS_MeshElement *> * itNodes=elem->nodesIterator();
- while(itNodes->more())
- fprintf(myFileId, "%d ", itNodes->next()->GetID());
- delete itNodes;
-
+ SMDS_ElemIteratorPtr it=elem->nodesIterator();
+ while(it->more()) fprintf(myFileId, "%d ", it->next()->GetID());
+
fprintf(myFileId, "\n");
}
- delete itFaces;
- SMDS_Iterator<const SMDS_MeshVolume*> * itVolumes=myMesh->volumesIterator();
+ SMDS_VolumeIteratorPtr itVolumes=myMesh->volumesIterator();
while(itVolumes->more())
{
const SMDS_MeshElement * elem = itVolumes->next();
}
}
- SMDS_Iterator<const SMDS_MeshElement *> * itNodes=elem->nodesIterator();
- while(itNodes->more())
- fprintf(myFileId, "%d ", itNodes->next()->GetID());
- delete itNodes;
+ SMDS_ElemIteratorPtr it=elem->nodesIterator();
+ while(it->more()) fprintf(myFileId, "%d ", it->next()->GetID());
fprintf(myFileId, "\n");
}
- delete itVolumes;
fclose(myFileId);
}
fprintf(stdout, "(* NOEUDS DU MAILLAGE : *)\n");
fprintf(stdout, "(************************)\n");
- SMDS_Iterator<const SMDS_MeshNode *> * itNodes=myMesh->nodesIterator();
+ SMDS_NodeIteratorPtr itNodes=myMesh->nodesIterator();
while(itNodes->more())
{
const SMDS_MeshNode * node = itNodes->next();
fprintf(myFileId, "%d %e %e %e\n", node->GetID(), node->X(),
node->Y(), node->Z());
}
- delete itNodes;
/****************************************************************************
* ECRITURE DES ELEMENTS *
fprintf(stdout, "(**************************)");
/* Ecriture des connectivites, noms, numeros des mailles */
- SMDS_Iterator<const SMDS_MeshEdge*> * itEdges=myMesh->edgesIterator();
+ SMDS_EdgeIteratorPtr itEdges=myMesh->edgesIterator();
while(itEdges->more())
{
const SMDS_MeshEdge * elem = itEdges->next();
}
}
- SMDS_Iterator<const SMDS_MeshElement *> * itNodes=elem->nodesIterator();
+ SMDS_ElemIteratorPtr itNodes=elem->nodesIterator();
while(itNodes->more())
fprintf(myFileId, "%d ", itNodes->next()->GetID());
fprintf(myFileId, "\n");
}
- delete itEdges;
- SMDS_Iterator<const SMDS_MeshFace *> * itFaces=myMesh->facesIterator();
+ SMDS_FaceIteratorPtr itFaces=myMesh->facesIterator();
while(itFaces->more())
{
const SMDS_MeshElement * elem = itFaces->next();
}
}
- SMDS_Iterator<const SMDS_MeshElement *> * itNodes=elem->nodesIterator();
+ SMDS_ElemIteratorPtr itNodes=elem->nodesIterator();
while(itNodes->more())
fprintf(myFileId, "%d ", itNodes->next()->GetID());
- delete itNodes;
fprintf(myFileId, "\n");
}
- delete itFaces;
- SMDS_Iterator<const SMDS_MeshVolume*> * itVolumes=myMesh->volumesIterator();
+ SMDS_VolumeIteratorPtr itVolumes=myMesh->volumesIterator();
while(itVolumes->more())
{
const SMDS_MeshElement * elem = itVolumes->next();
}
}
- SMDS_Iterator<const SMDS_MeshElement *> * itNodes=elem->nodesIterator();
+ SMDS_ElemIteratorPtr itNodes=elem->nodesIterator();
while(itNodes->more())
fprintf(myFileId, "%d ", itNodes->next()->GetID());
- delete itNodes;
fprintf(myFileId, "\n");
}
- delete itVolumes;
fclose(myFileId);
}
@COMMENCE@
# header files
-EXPORT_HEADERS = \
- DriverDAT_R_SMDS_Mesh.h \
- DriverDAT_R_SMESHDS_Mesh.h \
- DriverDAT_W_SMDS_Mesh.h \
- DriverDAT_W_SMESHDS_Mesh.h
-# DriverDAT_W_SMESHDS_Document.h \
-# DriverDAT_R_SMESHDS_Document.h \
+EXPORT_HEADERS= DriverDAT_R_SMDS_Mesh.h DriverDAT_R_SMESHDS_Mesh.h DriverDAT_R_SMESHDS_Document.h DriverDAT_W_SMDS_Mesh.h DriverDAT_W_SMESHDS_Mesh.h DriverDAT_W_SMESHDS_Document.h
# Libraries targets
LIB = libMeshDriverDAT.la
-LIB_SRC = \
- DriverDAT_R_SMDS_Mesh.cxx \
- DriverDAT_R_SMESHDS_Mesh.cxx \
- DriverDAT_W_SMDS_Mesh.cxx \
- DriverDAT_W_SMESHDS_Mesh.cxx
- #DriverDAT_W_SMESHDS_Document.cxx \
- #DriverDAT_R_SMESHDS_Document.cxx \
+LIB_SRC = DriverDAT_R_SMDS_Mesh.cxx DriverDAT_R_SMESHDS_Mesh.cxx DriverDAT_R_SMESHDS_Document.cxx DriverDAT_W_SMDS_Mesh.cxx DriverDAT_W_SMESHDS_Mesh.cxx DriverDAT_W_SMESHDS_Document.cxx
LIB_CLIENT_IDL =
LIB_SERVER_IDL =
# additionnal information to compil and link file
-CPPFLAGS += $(OCC_INCLUDES) -I${KERNEL_ROOT_DIR}/include/salome
+CPPFLAGS += $(OCC_INCLUDES) -I${KERNEL_ROOT_DIR}/include/salome $(BOOST_CPPFLAGS)
CXXFLAGS += $(OCC_CXXFLAGS) $(MED2_INCLUDES) -I${KERNEL_ROOT_DIR}/include/salome
LDFLAGS += $(MED2_LIBS) -lMeshDriver
--- /dev/null
+// SMESH DriverMED : tool to split groups on families
+//
+// Copyright (C) 2003 CEA
+//
+// This library 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.
+//
+// This library 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 this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+//
+// See http://www.salome-platform.org or email : webmaster.salome@opencascade.org
+//
+//
+//
+// File : DriverMED_Family.cxx
+// Author : Julia DOROVSKIKH
+// Module : SMESH
+// $Header$
+
+#include "DriverMED_Family.h"
+#include <sstream>
+
+//=============================================================================
+/*!
+ * Split each group from list <aGroups> on some parts (families)
+ * on the basis of the elements membership in other groups from this list.
+ * Resulting families have no common elements.
+ */
+//=============================================================================
+list<DriverMED_FamilyPtr> DriverMED_Family::MakeFamilies
+ (const map <int, SMESHDS_SubMesh*>& theSubMeshes,
+ const list<SMESHDS_Group*>& theGroups,
+ const bool doGroupOfNodes,
+ const bool doGroupOfEdges,
+ const bool doGroupOfFaces,
+ const bool doGroupOfVolumes)
+{
+ list<DriverMED_FamilyPtr> aFamilies;
+
+ string anAllNodesGroupName = "Group_Of_All_Nodes";
+ string anAllEdgesGroupName = "Group_Of_All_Edges";
+ string anAllFacesGroupName = "Group_Of_All_Faces";
+ string anAllVolumesGroupName = "Group_Of_All_Volumes";
+
+ // Reserve four ids for families of free elements
+ // (1 - nodes, -1 - edges, -2 - faces, -3 - volumes).
+ // 'Free' means here not belonging to any group.
+ int aNodeFamId = FIRST_NODE_FAMILY;
+ int aElemFamId = FIRST_ELEM_FAMILY;
+
+ // Process sub-meshes
+ map<int, SMESHDS_SubMesh*>::const_iterator aSMIter = theSubMeshes.begin();
+ for (; aSMIter != theSubMeshes.end(); aSMIter++)
+ {
+ list<DriverMED_FamilyPtr> aSMFams = SplitByType((*aSMIter).second, (*aSMIter).first);
+ list<DriverMED_FamilyPtr>::iterator aSMFamsIter = aSMFams.begin();
+ for (; aSMFamsIter != aSMFams.end(); aSMFamsIter++)
+ {
+ DriverMED_FamilyPtr aFam2 = (*aSMFamsIter);
+
+ list<DriverMED_FamilyPtr>::iterator aFamsIter = aFamilies.begin();
+ while (aFamsIter != aFamilies.end())
+ {
+ DriverMED_FamilyPtr aFam1 = *aFamsIter;
+ list<DriverMED_FamilyPtr>::iterator aCurrIter = aFamsIter++;
+ if (aFam1->myType == aFam2->myType)
+ {
+ DriverMED_FamilyPtr aCommon (new DriverMED_Family);
+ aFam1->Split(aFam2, aCommon);
+ if (!aCommon->IsEmpty())
+ {
+ aFamilies.push_back(aCommon);
+ }
+ if (aFam1->IsEmpty())
+ {
+ aFamilies.erase(aCurrIter);
+ }
+ if (aFam2->IsEmpty()) break;
+ }
+ }
+ // The rest elements of family
+ if (!aFam2->IsEmpty())
+ {
+ aFamilies.push_back(aFam2);
+ }
+ }
+ }
+
+ // Process groups
+ list<SMESHDS_Group*>::const_iterator aGroupsIter = theGroups.begin();
+ for (; aGroupsIter != theGroups.end(); aGroupsIter++)
+ {
+ DriverMED_FamilyPtr aFam2 (new DriverMED_Family);
+ aFam2->Init(*aGroupsIter);
+
+ list<DriverMED_FamilyPtr>::iterator aFamsIter = aFamilies.begin();
+ while (aFamsIter != aFamilies.end())
+ {
+ DriverMED_FamilyPtr aFam1 = *aFamsIter;
+ list<DriverMED_FamilyPtr>::iterator aCurrIter = aFamsIter++;
+ if (aFam1->myType == aFam2->myType)
+ {
+ DriverMED_FamilyPtr aCommon (new DriverMED_Family);
+ aFam1->Split(aFam2, aCommon);
+ if (!aCommon->IsEmpty())
+ {
+ aFamilies.push_back(aCommon);
+ }
+ if (aFam1->IsEmpty())
+ {
+ aFamilies.erase(aCurrIter);
+ }
+ if (aFam2->IsEmpty()) break;
+ }
+ }
+ // The rest elements of group
+ if (!aFam2->IsEmpty())
+ {
+ aFamilies.push_back(aFam2);
+ }
+ }
+
+ list<DriverMED_FamilyPtr>::iterator aFamsIter = aFamilies.begin();
+ for (; aFamsIter != aFamilies.end(); aFamsIter++)
+ {
+ DriverMED_FamilyPtr aFam = *aFamsIter;
+ if (aFam->myType == SMDSAbs_Node) {
+ aFam->SetId(aNodeFamId++);
+ if (doGroupOfNodes) aFam->myGroupNames.insert(anAllNodesGroupName);
+ }
+ else {
+ aFam->SetId(aElemFamId--);
+ if (aFam->myType == SMDSAbs_Edge) {
+ if (doGroupOfEdges) aFam->myGroupNames.insert(anAllEdgesGroupName);
+ }
+ else if (aFam->myType == SMDSAbs_Face) {
+ if (doGroupOfFaces) aFam->myGroupNames.insert(anAllFacesGroupName);
+ }
+ else if (aFam->myType == SMDSAbs_Volume) {
+ if (doGroupOfVolumes) aFam->myGroupNames.insert(anAllVolumesGroupName);
+ }
+ }
+ }
+
+ // Create families for elements, not belonging to any group
+ if (doGroupOfNodes)
+ {
+ DriverMED_FamilyPtr aFreeNodesFam (new DriverMED_Family);
+ aFreeNodesFam->SetId(REST_NODES_FAMILY);
+ aFreeNodesFam->myType = SMDSAbs_Node;
+ aFreeNodesFam->myGroupNames.insert(anAllNodesGroupName);
+ aFamilies.push_back(aFreeNodesFam);
+ }
+
+ if (doGroupOfEdges)
+ {
+ DriverMED_FamilyPtr aFreeEdgesFam (new DriverMED_Family);
+ aFreeEdgesFam->SetId(REST_EDGES_FAMILY);
+ aFreeEdgesFam->myType = SMDSAbs_Edge;
+ aFreeEdgesFam->myGroupNames.insert(anAllEdgesGroupName);
+ aFamilies.push_back(aFreeEdgesFam);
+ }
+
+ if (doGroupOfFaces)
+ {
+ DriverMED_FamilyPtr aFreeFacesFam (new DriverMED_Family);
+ aFreeFacesFam->SetId(REST_FACES_FAMILY);
+ aFreeFacesFam->myType = SMDSAbs_Face;
+ aFreeFacesFam->myGroupNames.insert(anAllFacesGroupName);
+ aFamilies.push_back(aFreeFacesFam);
+ }
+
+ if (doGroupOfVolumes)
+ {
+ DriverMED_FamilyPtr aFreeVolumesFam (new DriverMED_Family);
+ aFreeVolumesFam->SetId(REST_VOLUMES_FAMILY);
+ aFreeVolumesFam->myType = SMDSAbs_Volume;
+ aFreeVolumesFam->myGroupNames.insert(anAllVolumesGroupName);
+ aFamilies.push_back(aFreeVolumesFam);
+ }
+
+ DriverMED_FamilyPtr aNullFam (new DriverMED_Family);
+ aNullFam->SetId(0);
+ aNullFam->myType = SMDSAbs_All;
+ aFamilies.push_back(aNullFam);
+
+ return aFamilies;
+}
+
+//=============================================================================
+/*!
+ * Create TFamilyInfo for this family
+ */
+//=============================================================================
+MEDA::PFamilyInfo DriverMED_Family::GetFamilyInfo
+ (const MEDA::PMeshInfo& theMeshInfo) const
+{
+ string aValue;
+ ostringstream aStr;
+ aStr << myId;
+ aValue = aStr.str();
+ MED::TStringVector anAttrDescs (1, ""); // 1 attribute with empty description,
+ MED::TIntVector anAttrIds (1, myId); // Id=0,
+ MED::TIntVector anAttrVals (1, myId); // Value=0
+
+ MEDA::PFamilyInfo anInfo = MEDA::TWrapper::CrFamilyInfo(theMeshInfo,
+ aValue,
+ myId,
+ myGroupNames,
+ anAttrDescs,anAttrIds,anAttrVals);
+
+// cout << endl;
+// cout << "Groups: ";
+// set<string>::iterator aGrIter = myGroupNames.begin();
+// for (; aGrIter != myGroupNames.end(); aGrIter++)
+// {
+// cout << " " << *aGrIter;
+// }
+// cout << endl;
+//
+// cout << "Elements: ";
+// set<const SMDS_MeshElement *>::iterator anIter = myElements.begin();
+// for (; anIter != myElements.end(); anIter++)
+// {
+// cout << " " << (*anIter)->GetID();
+// }
+// cout << endl;
+
+ return anInfo;
+}
+
+//=============================================================================
+/*!
+ * Initialize the tool by SMESHDS_Group
+ */
+//=============================================================================
+void DriverMED_Family::Init (SMESHDS_Group* group)
+{
+ // Elements
+ myElements.clear();
+ group->InitIterator();
+ while (group->More())
+ {
+ myElements.insert(group->Next());
+ }
+
+ // Type
+ myType = group->GetType();
+
+ // Groups list
+ myGroupNames.clear();
+ myGroupNames.insert(string(group->GetStoreName()));
+}
+
+//=============================================================================
+/*!
+ * Split <theSubMesh> on some parts (families)
+ * on the basis of the elements type.
+ */
+//=============================================================================
+list<DriverMED_FamilyPtr> DriverMED_Family::SplitByType (SMESHDS_SubMesh* theSubMesh,
+ const int theId)
+{
+ list<DriverMED_FamilyPtr> aFamilies;
+ DriverMED_FamilyPtr aNodesFamily (new DriverMED_Family);
+ DriverMED_FamilyPtr anEdgesFamily (new DriverMED_Family);
+ DriverMED_FamilyPtr aFacesFamily (new DriverMED_Family);
+ DriverMED_FamilyPtr aVolumesFamily (new DriverMED_Family);
+
+ char submeshGrpName[ 30 ];
+ sprintf( submeshGrpName, "SubMesh %d", theId );
+
+ SMDS_NodeIteratorPtr aNodesIter = theSubMesh->GetNodes();
+ while (aNodesIter->more())
+ {
+ const SMDS_MeshNode* aNode = aNodesIter->next();
+ aNodesFamily->AddElement(aNode);
+ }
+
+ SMDS_ElemIteratorPtr anElemsIter = theSubMesh->GetElements();
+ while (anElemsIter->more())
+ {
+ const SMDS_MeshElement* anElem = anElemsIter->next();
+ switch (anElem->GetType())
+ {
+ case SMDSAbs_Edge:
+ anEdgesFamily->AddElement(anElem);
+ break;
+ case SMDSAbs_Face:
+ aFacesFamily->AddElement(anElem);
+ break;
+ case SMDSAbs_Volume:
+ aVolumesFamily->AddElement(anElem);
+ break;
+ default:
+ break;
+ }
+ }
+
+ if (!aNodesFamily->IsEmpty()) {
+ aNodesFamily->SetType(SMDSAbs_Node);
+ aNodesFamily->AddGroupName(submeshGrpName);
+ aFamilies.push_back(aNodesFamily);
+ }
+ if (!anEdgesFamily->IsEmpty()) {
+ anEdgesFamily->SetType(SMDSAbs_Edge);
+ anEdgesFamily->AddGroupName(submeshGrpName);
+ aFamilies.push_back(anEdgesFamily);
+ }
+ if (!aFacesFamily->IsEmpty()) {
+ aFacesFamily->SetType(SMDSAbs_Face);
+ aFacesFamily->AddGroupName(submeshGrpName);
+ aFamilies.push_back(aFacesFamily);
+ }
+ if (!aVolumesFamily->IsEmpty()) {
+ aVolumesFamily->SetType(SMDSAbs_Volume);
+ aVolumesFamily->AddGroupName(submeshGrpName);
+ aFamilies.push_back(aVolumesFamily);
+ }
+
+ return aFamilies;
+}
+
+//=============================================================================
+/*!
+ * Remove from <myElements> elements, common with <by>,
+ * Remove from <by> elements, common with <myElements>,
+ * Create family <common> from common elements, with combined groups list.
+ */
+//=============================================================================
+void DriverMED_Family::Split (DriverMED_FamilyPtr by,
+ DriverMED_FamilyPtr common)
+{
+ // Elements
+ set<const SMDS_MeshElement *>::iterator anIter = by->myElements.begin();
+ for (; anIter != by->myElements.end(); anIter++)
+ {
+ if (myElements.find(*anIter) != myElements.end())
+ {
+ common->myElements.insert(*anIter);
+ myElements.erase(*anIter);
+ by->myElements.erase(*anIter);
+ }
+ }
+
+ if (!common->IsEmpty())
+ {
+ // Groups list
+ common->myGroupNames = myGroupNames;
+ set<string>::iterator aGrNamesIter = by->myGroupNames.begin();
+ for (; aGrNamesIter != by->myGroupNames.end(); aGrNamesIter++)
+ {
+ common->myGroupNames.insert(*aGrNamesIter);
+ }
+
+ // Type
+ common->myType = myType;
+ }
+}
--- /dev/null
+// SMESH DriverMED : tool to split groups on families
+//
+// Copyright (C) 2003 CEA
+//
+// This library 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.
+//
+// This library 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 this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+//
+// See http://www.salome-platform.org or email : webmaster.salome@opencascade.org
+//
+//
+//
+// File : DriverMED_Family.hxx
+// Author : Julia DOROVSKIKH
+// Module : SMESH
+// $Header$
+
+#ifndef _INCLUDE_DRIVERMED_FAMILY
+#define _INCLUDE_DRIVERMED_FAMILY
+
+#include "SMDS_Mesh.hxx"
+#include "SMESHDS_Group.hxx"
+#include "SMESHDS_SubMesh.hxx"
+#include "MEDA_Wrapper.hxx"
+
+#include <boost/shared_ptr.hpp>
+#include <set>
+
+using namespace std;
+
+#define REST_NODES_FAMILY 1
+#define REST_EDGES_FAMILY -1
+#define REST_FACES_FAMILY -2
+#define REST_VOLUMES_FAMILY -3
+#define FIRST_NODE_FAMILY 2
+#define FIRST_ELEM_FAMILY -4
+
+class DriverMED_Family;
+typedef boost::shared_ptr<DriverMED_Family> DriverMED_FamilyPtr;
+
+class DriverMED_Family
+{
+ public:
+
+ // Methods for groups storing to MED
+
+ static list<DriverMED_FamilyPtr> MakeFamilies (const map <int, SMESHDS_SubMesh*>& theSubMeshes,
+ const list<SMESHDS_Group*>& theGroups,
+ const bool doGroupOfNodes,
+ const bool doGroupOfEdges,
+ const bool doGroupOfFaces,
+ const bool doGroupOfVolumes);
+ // Split each group from list <theGroups> and each sub-mesh from list <theSubMeshes>
+ // on some parts (families) on the basis of the elements membership in other groups
+ // from <theGroups> and other sub-meshes from <theSubMeshes>.
+ // Resulting families have no common elements.
+
+ MEDA::PFamilyInfo GetFamilyInfo (const MEDA::PMeshInfo& theMeshInfo) const;
+ // Create TFamilyInfo for this family
+
+ const set<const SMDS_MeshElement *>& GetElements () const { return myElements; }
+ // Returns elements of this family
+
+ int GetId () const { return myId; }
+ // Returns a family ID
+
+ public:
+
+ // Methods for groups reading from MED
+
+ void AddElement (const SMDS_MeshElement* theElement) { myElements.insert(theElement); }
+
+ void AddGroupName (string theGroupName) { myGroupNames.insert(theGroupName); }
+
+ void SetType (const SMDSAbs_ElementType theType) { myType = theType; }
+ SMDSAbs_ElementType GetType () { return myType; }
+
+ bool MemberOf (string theGroupName) const
+ { return (myGroupNames.find(theGroupName) != myGroupNames.end()); }
+
+ const MED::TStringSet& GetGroupNames () const { return myGroupNames; }
+
+ private:
+ void Init (SMESHDS_Group* group);
+ // Initialize the tool by SMESHDS_Group
+
+ static list<DriverMED_FamilyPtr> SplitByType (SMESHDS_SubMesh* theSubMesh,
+ const int theId);
+ // Split <theSubMesh> on some parts (families)
+ // on the basis of the elements type.
+
+ void Split (DriverMED_FamilyPtr by,
+ DriverMED_FamilyPtr common);
+ // Remove from <Elements> elements, common with <by>,
+ // Remove from <by> elements, common with <Elements>,
+ // Create family <common> from common elements, with combined groups list.
+
+ void SetId (const int theId) { myId = theId; }
+ // Sets a family ID
+
+ bool IsEmpty () const { return myElements.empty(); }
+ // Check, if this family has empty list of elements
+
+ private:
+ int myId;
+ SMDSAbs_ElementType myType;
+ set<const SMDS_MeshElement *> myElements;
+ MED::TStringSet myGroupNames;
+};
+
+#endif
extern "C"
{
- void * SMESH_createMEDDocumentReader()
+ Document_Reader *maker()
{
return new DriverMED_R_SMESHDS_Document;
}
}
DriverMED_R_SMESHDS_Document::DriverMED_R_SMESHDS_Document()
- :Document_Reader(new DriverMED_R_SMESHDS_Mesh())
{
;
}
int myMeshId;
+ //string myFile = string("/home/home_users/cai/projects/salome_prev04/SALOME_ROOT/data/fra1.med");
+
/****************************************************************************
* OUVERTURE DU FICHIER EN LECTURE *
****************************************************************************/
// File : DriverMED_R_SMESHDS_Mesh.cxx
// Module : SMESH
-using namespace std;
#include "DriverMED_R_SMESHDS_Mesh.h"
#include "DriverMED_R_SMDS_Mesh.h"
#include "utilities.h"
-#include <stdlib.h>
+#include "DriverMED_Family.h"
-extern "C"
-{
-/**
- * Factory function which will be called by SMESHDriver
- */
-void * SMESH_createMEDMeshReader()
-{
- return new DriverMED_R_SMESHDS_Mesh();
-}
+#include "SMESHDS_Group.hxx"
-}
+#include "MEDA_Wrapper.hxx"
+#include "MED_Utilities.hxx"
+
+#include <stdlib.h>
DriverMED_R_SMESHDS_Mesh::DriverMED_R_SMESHDS_Mesh()
+ :
+ myMesh (NULL),
+ myFile (""),
+ myFileId (-1),
+ myMeshId (-1)
{
- myFileId = -1;
}
DriverMED_R_SMESHDS_Mesh::~DriverMED_R_SMESHDS_Mesh()
{
- ;
+// map<int, DriverMED_FamilyPtr>::iterator aFamsIter = myFamilies.begin();
+// for (; aFamsIter != myFamilies.end(); aFamsIter++)
+// {
+// delete (*aFamsIter).second;
+// }
}
void DriverMED_R_SMESHDS_Mesh::SetMesh(SMDS_Mesh * aMesh)
{
- //myMesh = SMESHDS_Mesh *::DownCast(aMesh);
- myMesh = aMesh;
+ myMesh = aMesh;
}
void DriverMED_R_SMESHDS_Mesh::SetFile(string aFile)
{
- myFile = aFile;
+ myFile = aFile;
}
void DriverMED_R_SMESHDS_Mesh::SetFileId(med_idt aFileId)
{
- myFileId = aFileId;
+ myFileId = aFileId;
}
void DriverMED_R_SMESHDS_Mesh::SetMeshId(int aMeshId)
{
- myMeshId = aMeshId;
+ myMeshId = aMeshId;
}
-void DriverMED_R_SMESHDS_Mesh::Read()
+void DriverMED_R_SMESHDS_Mesh::SetMeshName(string theMeshName)
{
+ myMeshName = theMeshName;
+}
- string myClass = string("SMDS_Mesh");
- string myExtension = string("MED");
+void DriverMED_R_SMESHDS_Mesh::Read()
+{
- DriverMED_R_SMDS_Mesh *myReader = new DriverMED_R_SMDS_Mesh;
+ string myClass = string("SMDS_Mesh");
+ string myExtension = string("MED");
- myReader->SetMesh(myMesh);
- myReader->SetMeshId(myMeshId);
- myReader->SetFile(myFile);
- myReader->SetFileId(-1);
+ DriverMED_R_SMDS_Mesh *myReader = new DriverMED_R_SMDS_Mesh;
- myReader->Read();
+ myReader->SetMesh(myMesh);
+ myReader->SetMeshId(myMeshId);
+ myReader->SetFile(myFile);
+ myReader->SetFileId(-1);
+ myReader->Read();
}
void DriverMED_R_SMESHDS_Mesh::Add()
{
+ string myClass = string("SMDS_Mesh");
+ string myExtension = string("MED");
- string myClass = string("SMDS_Mesh");
- string myExtension = string("MED");
-
- DriverMED_R_SMDS_Mesh *myReader = new DriverMED_R_SMDS_Mesh;
+ DriverMED_R_SMDS_Mesh *myReader = new DriverMED_R_SMDS_Mesh;
- myReader->SetMesh(myMesh);
- myReader->SetMeshId(myMeshId);
+ myReader->SetMesh(myMesh);
+ myReader->SetMeshId(myMeshId);
- SCRUTE(myFileId);
- myReader->SetFileId(myFileId);
-
- myReader->Read();
+ SCRUTE(myFileId);
+ myReader->SetFileId(myFileId);
+ myReader->Read();
}
-void DriverMED_R_SMESHDS_Mesh::ReadMySelf()
-{
- med_err ret = 0;
- int i, j, k, l;
- int numero;
- char message[200];
- bool ok;
- /* nombre d'objets MED */
- char nom_universel[MED_TAILLE_LNOM + 1];
- med_int long_fichier_en_tete;
- char *fichier_en_tete;
- char version_hdf[10];
- char version_med[10];
- med_int nmaa, mdim, nnoe;
- med_int nmai[MED_NBR_GEOMETRIE_MAILLE], nfac[MED_NBR_GEOMETRIE_FACE];
- med_int nare[MED_NBR_GEOMETRIE_ARETE];
- /* nom du maillage */
- char nommaa[MED_TAILLE_NOM + 1];
- /* noeuds */
- med_float *coo;
- char nomcoo[3 * MED_TAILLE_PNOM + 1];
- char unicoo[3 * MED_TAILLE_PNOM + 1];
- char *nomnoe;
- med_int *numnoe;
- med_int *nufano;
- med_repere rep;
- med_booleen inonoe, inunoe;
- med_mode_switch mode_coo;
- char str[MED_TAILLE_PNOM + 1];
- /* elements */
- med_int nsup;
- med_int edim;
- med_int taille;
- med_int elem_id;
- med_int cmpt = 0;
- med_int *connectivite;
- char *nomele;
- med_int *numele;
- med_int *nufael;
- med_booleen inoele, inuele;
- med_connectivite typ_con;
- med_geometrie_element typgeo;
- med_geometrie_element typmai[MED_NBR_GEOMETRIE_MAILLE] =
- { MED_POINT1, MED_SEG2,
- MED_SEG3, MED_TRIA3,
- MED_TRIA6, MED_QUAD4,
- MED_QUAD8, MED_TETRA4,
- MED_TETRA10, MED_HEXA8,
- MED_HEXA20, MED_PENTA6,
- MED_PENTA15, MED_PYRA5,
- MED_PYRA13
- };
- med_int desmai[MED_NBR_GEOMETRIE_MAILLE] =
- { 0, 2, 3, 3, 3, 4, 4, 4, 4, 6, 6, 5, 5, 5, 5 };
- med_int nmailles[MED_NBR_GEOMETRIE_MAILLE];
- char nommai[MED_NBR_GEOMETRIE_MAILLE][MED_TAILLE_NOM + 1] = { "MED_POINT1",
- "MED_SEG2",
- "MED_SEG3",
- "MED_TRIA3",
- "MED_TRIA6",
- "MED_QUAD4",
- "MED_QUAD8",
- "MED_TETRA4",
- "MED_TETRA10",
- "MED_HEXA8",
- "MED_HEXA20",
- "MED_PENTA6",
- "MED_PENTA15",
- "MED_PYRA5",
- "MED_PYRA13"
- };
- med_geometrie_element typfac[MED_NBR_GEOMETRIE_FACE] =
- { MED_TRIA3, MED_TRIA6,
- MED_QUAD4, MED_QUAD8
- };
- med_int desfac[MED_NBR_GEOMETRIE_FACE] = { 3, 3, 4, 4 };
- med_int nfaces[MED_NBR_GEOMETRIE_FACE];
- char nomfac[MED_NBR_GEOMETRIE_FACE][MED_TAILLE_NOM + 1] =
- { "MED_TRIA3", "MED_TRIA6",
- "MED_QUAD4", "MED_QUAD8"
- };
- med_geometrie_element typare[MED_NBR_GEOMETRIE_ARETE] =
- { MED_SEG2, MED_SEG3 };
- med_int desare[MED_NBR_GEOMETRIE_ARETE] = { 2, 3 };
- med_int naretes[MED_NBR_GEOMETRIE_ARETE];
- char nomare[MED_NBR_GEOMETRIE_ARETE][MED_TAILLE_NOM + 1] =
- { "MED_SEG2", "MED_SEG3" };
- /* familles */
- med_int nfam;
- med_int natt, ngro;
- char *attdes, *gro;
- med_int *attval, *attide;
- char nomfam[MED_TAILLE_NOM + 1];
- med_int numfam;
- char str1[MED_TAILLE_DESC + 1];
- char str2[MED_TAILLE_LNOM + 1];
- string fam;
- string fam_type;
- string fam_id;
-
- char *file2Read;
- bool locally_managed;
-
- if (myFileId == -1)
- locally_managed = true;
- else
- locally_managed = false;
-
- if (locally_managed)
- {
- file2Read = (char *)myFile.c_str();
- myFileId = MEDouvrir(file2Read, MED_LECT);
- if (myFileId < 0)
- {
- fprintf(stderr, ">> ERREUR : ouverture du fichier %s \n",
- file2Read);
- exit(EXIT_FAILURE);
- }
- numero = 1;
- }
- else
- numero = myMeshId;
- sprintf(nommaa, "Mesh %d", myMeshId); //pour load
- SCRUTE(nommaa);
-
- typ_con = MED_NOD;
- mode_coo = MED_FULL_INTERLACE;
- mdim = 3;
-
- SMESHDS_Mesh * mySMESHDSMesh = dynamic_cast<SMESHDS_Mesh *>(myMesh);
-
- //TopoDS_Shape myShape = mySMESHDSMesh->ShapeToMesh();
-
- /****************************************************************************
- * NOMBRES D'OBJETS MED *
- ****************************************************************************/
- fprintf(stdout, "\n(****************************)\n");
- fprintf(stdout, "(* INFORMATIONS GENERALES : *)\n");
- fprintf(stdout, "(****************************)\n");
-
- /* lecture du nom et de la dimension du maillage */
- /*! fprintf(stdout,"%d %d\n",myFileId,numero);
- * ret = MEDmaaInfo(myFileId,numero,nommaa,&mdim);
- * fprintf(stdout,"%d\n",ret);
- * if (ret < 0)
- * {
- * fprintf(stderr,">> ERREUR : lecture du nom du maillage \n");
- * exit(EXIT_FAILURE);
- * }
- * fprintf(stdout,"- Nom du maillage : <<%s>>\n",nommaa);
- * fprintf(stdout,"- Dimension du maillage : %d\n",mdim);
- */
- /* Combien de noeuds ? */
- nnoe =
- MEDnEntMaa(myFileId, nommaa, MED_COOR, MED_NOEUD, MED_POINT1, typ_con);
- if (nnoe < 0)
- {
- fprintf(stderr, ">> ERREUR : lecture du nombre de noeuds \n");
- exit(EXIT_FAILURE);
- }
- fprintf(stdout, "- Nombre de noeuds : %d \n", nnoe);
-
- /* Combien de mailles, faces ou aretes ? */
- for (i = 0; i < MED_NBR_GEOMETRIE_MAILLE; i++)
- {
- nmailles[i] =
- MEDnEntMaa(myFileId, nommaa, MED_CONN, MED_MAILLE, typmai[i],
- typ_con);
- if (nmailles[i] < 0)
- {
- fprintf(stderr, ">> ERREUR : lecture du nombre de mailles \n");
- exit(EXIT_FAILURE);
- }
- fprintf(stdout, "- Nombre de mailles de type %s : %d \n", nommai[i],
- nmailles[i]);
- }
+static const SMDS_MeshNode*
+FindNode(const SMDS_Mesh* theMesh, med_int theId){
+ const SMDS_MeshNode* aNode = theMesh->FindNode(theId);
+ if(aNode) return aNode;
+ EXCEPTION(runtime_error,"SMDS_Mesh::FindNode - cannot find a SMDS_MeshNode for ID = "<<theId);
+}
- for (i = 0; i < MED_NBR_GEOMETRIE_FACE; i++)
- {
- nfaces[i] = MEDnEntMaa(myFileId, nommaa, MED_CONN, MED_FACE, typfac[i],
- typ_con);
- if (nfaces[i] < 0)
- {
- fprintf(stderr, ">> ERREUR : lecture du nombre de faces \n");
- exit(EXIT_FAILURE);
- }
- fprintf(stdout, "- Nombre de faces de type %s : %d \n", nomfac[i],
- nfaces[i]);
- }
- for (i = 0; i < MED_NBR_GEOMETRIE_ARETE; i++)
- {
- naretes[i] =
- MEDnEntMaa(myFileId, nommaa, MED_CONN, MED_ARETE, typare[i],
- typ_con);
- if (naretes[i] < 0)
- {
- fprintf(stderr, ">> ERREUR : lecture du nombre d'aretes \n");
- exit(EXIT_FAILURE);
+DriverMED_R_SMESHDS_Mesh::ReadStatus DriverMED_R_SMESHDS_Mesh::ReadMySelf()
+{
+ ReadStatus result = DRS_FAIL;
+ try{
+ using namespace MEDA;
+
+ myFamilies.clear();
+ MESSAGE("ReadMySelf - myFile : "<<myFile);
+ TWrapper aMed(myFile);
+
+ result = DRS_EMPTY;
+ if(med_int aNbMeshes = aMed.GetNbMeshes()){
+ for(int iMesh = 0; iMesh < aNbMeshes; iMesh++){
+ // Reading the MED mesh
+ //---------------------
+ PMeshInfo aMeshInfo = aMed.GetMeshInfo(iMesh);
+ string aMeshName;
+ if (myMeshId != -1) {
+ ostringstream aMeshNameStr;
+ aMeshNameStr<<myMeshId;
+ aMeshName = aMeshNameStr.str();
+ } else {
+ aMeshName = myMeshName;
+ }
+ MESSAGE("ReadMySelf - aMeshName : "<<aMeshName<<"; "<<aMeshInfo->GetName());
+ if(aMeshName != aMeshInfo->GetName()) continue;
+ result = DRS_OK;
+ med_int aMeshDim = aMeshInfo->GetDim();
+
+ // Reading MED families to the temporary structure
+ //------------------------------------------------
+ med_int aNbFams = aMed.GetNbFamilies(aMeshInfo);
+ MESSAGE("Read " << aNbFams << " families");
+ for (med_int iFam = 0; iFam < aNbFams; iFam++) {
+ PFamilyInfo aFamilyInfo = aMed.GetFamilyInfo(aMeshInfo, iFam);
+ med_int aFamId = aFamilyInfo->GetId();
+ MESSAGE("Family " << aFamId << " :");
+
+//if (aFamId >= FIRST_VALID_FAMILY) {
+ DriverMED_FamilyPtr aFamily (new DriverMED_Family);
+
+ med_int aNbGrp = aFamilyInfo->GetNbGroup();
+ MESSAGE("belong to " << aNbGrp << " groups");
+ for (med_int iGr = 0; iGr < aNbGrp; iGr++) {
+ string aGroupName = aFamilyInfo->GetGroupName(iGr);
+ MESSAGE(aGroupName);
+ aFamily->AddGroupName(aGroupName);
+ }
+// aFamily->SetId(aFamId);
+ myFamilies[aFamId] = aFamily;
+// }
+ }
+
+ // Reading MED nodes to the corresponding SMDS structure
+ //------------------------------------------------------
+ PNodeInfo aNodeInfo = aMed.GetNodeInfo(aMeshInfo);
+ med_booleen anIsNodeNum = aNodeInfo->IsElemNum();
+ med_int aNbElems = aNodeInfo->GetNbElem();
+ MESSAGE("ReadMySelf - aNodeInfo->GetNbElem() = "<<aNbElems<<"; anIsNodeNum = "<<anIsNodeNum);
+ for(med_int iElem = 0; iElem < aNbElems; iElem++){
+ double aCoords[3] = {0.0, 0.0, 0.0};
+ for(med_int iDim = 0; iDim < aMeshDim; iDim++)
+ aCoords[iDim] = aNodeInfo->GetNodeCoord(iElem,iDim);
+ const SMDS_MeshNode* aNode;
+ if(anIsNodeNum) {
+ aNode = myMesh->AddNodeWithID
+ (aCoords[0],aCoords[1],aCoords[2],aNodeInfo->GetElemNum(iElem));
+ } else {
+ aNode = myMesh->AddNode
+ (aCoords[0],aCoords[1],aCoords[2]);
+ }
+ //cout<<aNode->GetID()<<": "<<aNode->X()<<", "<<aNode->Y()<<", "<<aNode->Z()<<endl;
+
+ // Save reference to this node from its family
+ med_int aFamNum = aNodeInfo->GetFamNum(iElem);
+ if (myFamilies.find(aFamNum) != myFamilies.end())
+ {
+ myFamilies[aFamNum]->AddElement(aNode);
+ myFamilies[aFamNum]->SetType(SMDSAbs_Node);
+ }
+ }
+
+ // Reading pre information about all MED cells
+ //--------------------------------------------
+ bool takeNumbers = true; // initially we trust the numbers from file
+ MED::TEntityInfo aEntityInfo = aMed.GetEntityInfo(aMeshInfo);
+ MED::TEntityInfo::iterator anEntityIter = aEntityInfo.begin();
+ for(; anEntityIter != aEntityInfo.end(); anEntityIter++){
+ const med_entite_maillage& anEntity = anEntityIter->first;
+ if(anEntity == MED_NOEUD) continue;
+ // Reading MED cells to the corresponding SMDS structure
+ //------------------------------------------------------
+ const MED::TGeom& aTGeom = anEntityIter->second;
+ MED::TGeom::const_iterator anTGeomIter = aTGeom.begin();
+ for(; anTGeomIter != aTGeom.end(); anTGeomIter++){
+ const med_geometrie_element& aGeom = anTGeomIter->first;
+ if(aGeom == MED_POINT1) continue;
+ PCellInfo aCellInfo = aMed.GetCellInfo(aMeshInfo,anEntity,aGeom);
+ med_booleen anIsElemNum = takeNumbers ? aCellInfo->IsElemNum() : MED_FAUX;
+ med_int aNbElems = aCellInfo->GetNbElem();
+ MESSAGE("ReadMySelf - anEntity = "<<anEntity<<"; anIsElemNum = "<<anIsElemNum);
+ MESSAGE("ReadMySelf - aGeom = "<<aGeom<<"; aNbElems = "<<aNbElems);
+
+ for(int iElem = 0; iElem < aNbElems; iElem++){
+ med_int aNbNodes = -1;
+ switch(aGeom){
+ case MED_SEG2:
+ case MED_SEG3:
+ aNbNodes = 2;
+ break;
+ case MED_TRIA3:
+ case MED_TRIA6:
+ aNbNodes = 3;
+ break;
+ break;
+ case MED_QUAD4:
+ case MED_QUAD8:
+ aNbNodes = 4;
+ break;
+ case MED_TETRA4:
+ case MED_TETRA10:
+ aNbNodes = 4;
+ break;
+ case MED_PYRA5:
+ case MED_PYRA13:
+ aNbNodes = 5;
+ break;
+ case MED_PENTA6:
+ case MED_PENTA15:
+ aNbNodes = 6;
+ break;
+ case MED_HEXA8:
+ case MED_HEXA20:
+ aNbNodes = 8;
+ break;
+ }
+ vector<med_int> aNodeIds(aNbNodes);
+ if(anIsNodeNum) {
+ for(int i = 0; i < aNbNodes; i++){
+ aNodeIds.at(i) = aNodeInfo->GetElemNum(aCellInfo->GetConn(iElem,i)-1);
}
- fprintf(stdout, "- Nombre d'aretes de type %s : %d \n", nomare[i],
- naretes[i]);
- }
-
- /* nombre de familles */
- nfam = MEDnFam(myFileId, nommaa, 0, MED_FAMILLE);
- if (nfam < 0)
- {
- fprintf(stderr, ">> ERREUR : lecture du nombre de familles \n");
- exit(EXIT_FAILURE);
- }
- fprintf(stdout, "- Nombre de familles : %d \n", nfam);
-
- vector < int >family[nfam];
-
- /****************************************************************************
- * LECTURE DES NOEUDS *
- ****************************************************************************/
- fprintf(stdout, "\n(************************)\n");
- fprintf(stdout, "(* NOEUDS DU MAILLAGE : *)\n");
- fprintf(stdout, "(************************)\n");
-
- /* Allocations memoires */
- /* table des coordonnees
- * profil : (dimension * nombre de noeuds ) */
- coo = (med_float *) malloc(sizeof(med_float) * nnoe * mdim);
- /* table des numeros, des numeros de familles des noeuds
- * profil : (nombre de noeuds) */
- numnoe = (med_int *) malloc(sizeof(med_int) * nnoe);
- nufano = (med_int *) malloc(sizeof(med_int) * nnoe);
- /* table des noms des noeuds
- * profil : (nnoe*MED_TAILLE_PNOM+1) */
- nomnoe = (char *)malloc(MED_TAILLE_PNOM * nnoe + 1);
-
- /* lecture des noeuds :
- * - coordonnees
- * - noms (optionnel dans un fichier MED)
- * - numeros (optionnel dans un fichier MED)
- * - numeros des familles */
- ret = MEDnoeudsLire(myFileId, nommaa, mdim, coo, mode_coo, &rep,
- nomcoo, unicoo, nomnoe, &inonoe, numnoe, &inunoe, nufano, nnoe);
- if (ret < 0)
- strcpy(message, ">> ERREUR : lecture des noeuds \n");
-
- if (inunoe)
- {
- for (int i = 0; i < nnoe; i++)
- {
- ok = mySMESHDSMesh->AddNodeWithID(coo[i * 3], coo[i * 3 + 1],
- coo[i * 3 + 2], numnoe[i]);
- //fprintf(Out,"%d %f %f %f\n",numnoe[i],coo[i*3],coo[i*3+1],coo[i*3+2]);
+ }else{
+ for(int i = 0; i < aNbNodes; i++){
+ aNodeIds.at(i) = aCellInfo->GetConn(iElem,i);
}
- }
- else
- {
- for (int i = 0; i < nnoe; i++)
- {
- ok = mySMESHDSMesh->AddNodeWithID(coo[i * 3], coo[i * 3 + 1],
- coo[i * 3 + 2], i + 1);
- //fprintf(Out,"%d %f %f %f\n",numnoe[i],coo[i*3],coo[i*3+1],i);
- family[*(nufano + i)].push_back(numnoe[i]);
+ }
+ //if(anIsElemNum)
+ // cout<<aCellInfo->GetElemNum(iElem)<<": ";
+ //else
+ // cout<<iElem<<": ";
+ //for(int i = 0; i < aNbNodes; i++){
+ // cout<<aNodeIds.at(i)<<", ";
+ //}
+
+ bool isRenum = false;
+ SMDS_MeshElement* anElement = NULL;
+ med_int aFamNum = aCellInfo->GetFamNum(iElem);
+ try{
+ switch(aGeom){
+ case MED_SEG2:
+ case MED_SEG3:
+ if(anIsElemNum)
+ anElement = myMesh->AddEdgeWithID(aNodeIds.at(0),
+ aNodeIds.at(1),
+ aCellInfo->GetElemNum(iElem));
+ if (!anElement) {
+ anElement = myMesh->AddEdge(FindNode(myMesh,aNodeIds.at(0)),
+ FindNode(myMesh,aNodeIds.at(1)));
+ isRenum = anIsElemNum;
+ }
+ break;
+ case MED_TRIA3:
+ case MED_TRIA6:
+ aNbNodes = 3;
+ if(anIsElemNum)
+ anElement = myMesh->AddFaceWithID(aNodeIds.at(0),
+ aNodeIds.at(1),
+ aNodeIds.at(2),
+ aCellInfo->GetElemNum(iElem));
+ if (!anElement) {
+ anElement = myMesh->AddFace(FindNode(myMesh,aNodeIds.at(0)),
+ FindNode(myMesh,aNodeIds.at(1)),
+ FindNode(myMesh,aNodeIds.at(2)));
+ isRenum = anIsElemNum;
+ }
+ break;
+ case MED_QUAD4:
+ case MED_QUAD8:
+ aNbNodes = 4;
+ // There is some differnce between SMDS and MED
+ if(anIsElemNum)
+ anElement = myMesh->AddFaceWithID(aNodeIds.at(0),
+ aNodeIds.at(1),
+ aNodeIds.at(2),
+ aNodeIds.at(3),
+ aCellInfo->GetElemNum(iElem));
+ if (!anElement) {
+ anElement = myMesh->AddFace(FindNode(myMesh,aNodeIds.at(0)),
+ FindNode(myMesh,aNodeIds.at(1)),
+ FindNode(myMesh,aNodeIds.at(2)),
+ FindNode(myMesh,aNodeIds.at(3)));
+ isRenum = anIsElemNum;
+ }
+ break;
+ case MED_TETRA4:
+ case MED_TETRA10:
+ aNbNodes = 4;
+ if(anIsElemNum)
+ anElement = myMesh->AddVolumeWithID(aNodeIds.at(0),
+ aNodeIds.at(1),
+ aNodeIds.at(2),
+ aNodeIds.at(3),
+ aCellInfo->GetElemNum(iElem));
+ if (!anElement) {
+ anElement = myMesh->AddVolume(FindNode(myMesh,aNodeIds.at(0)),
+ FindNode(myMesh,aNodeIds.at(1)),
+ FindNode(myMesh,aNodeIds.at(2)),
+ FindNode(myMesh,aNodeIds.at(3)));
+ isRenum = anIsElemNum;
+ }
+ break;
+ case MED_PYRA5:
+ case MED_PYRA13:
+ aNbNodes = 5;
+ // There is some differnce between SMDS and MED
+ if(anIsElemNum)
+ anElement = myMesh->AddVolumeWithID(aNodeIds.at(0),
+ aNodeIds.at(1),
+ aNodeIds.at(2),
+ aNodeIds.at(3),
+ aNodeIds.at(4),
+ aCellInfo->GetElemNum(iElem));
+ if (!anElement) {
+ anElement = myMesh->AddVolume(FindNode(myMesh,aNodeIds.at(0)),
+ FindNode(myMesh,aNodeIds.at(1)),
+ FindNode(myMesh,aNodeIds.at(2)),
+ FindNode(myMesh,aNodeIds.at(3)),
+ FindNode(myMesh,aNodeIds.at(4)));
+ isRenum = anIsElemNum;
+ }
+ break;
+ case MED_PENTA6:
+ case MED_PENTA15:
+ aNbNodes = 6;
+ if(anIsElemNum)
+ anElement = myMesh->AddVolumeWithID(aNodeIds.at(0),
+ aNodeIds.at(1),
+ aNodeIds.at(2),
+ aNodeIds.at(3),
+ aNodeIds.at(4),
+ aNodeIds.at(5),
+ aCellInfo->GetElemNum(iElem));
+ if (!anElement) {
+ anElement = myMesh->AddVolume(FindNode(myMesh,aNodeIds.at(0)),
+ FindNode(myMesh,aNodeIds.at(1)),
+ FindNode(myMesh,aNodeIds.at(2)),
+ FindNode(myMesh,aNodeIds.at(3)),
+ FindNode(myMesh,aNodeIds.at(4)),
+ FindNode(myMesh,aNodeIds.at(5)));
+ isRenum = anIsElemNum;
+ }
+ break;
+ case MED_HEXA8:
+ case MED_HEXA20:
+ aNbNodes = 8;
+ if(anIsElemNum)
+ anElement = myMesh->AddVolumeWithID(aNodeIds.at(0),
+ aNodeIds.at(1),
+ aNodeIds.at(2),
+ aNodeIds.at(3),
+ aNodeIds.at(4),
+ aNodeIds.at(5),
+ aNodeIds.at(6),
+ aNodeIds.at(7),
+ aCellInfo->GetElemNum(iElem));
+ if (!anElement) {
+ anElement = myMesh->AddVolume(FindNode(myMesh,aNodeIds.at(0)),
+ FindNode(myMesh,aNodeIds.at(1)),
+ FindNode(myMesh,aNodeIds.at(2)),
+ FindNode(myMesh,aNodeIds.at(3)),
+ FindNode(myMesh,aNodeIds.at(4)),
+ FindNode(myMesh,aNodeIds.at(5)),
+ FindNode(myMesh,aNodeIds.at(6)),
+ FindNode(myMesh,aNodeIds.at(7)));
+ isRenum = anIsElemNum;
+ }
+ break;
}
+ }catch(const std::exception& exc){
+ //INFOS("Follow exception was cought:\n\t"<<exc.what());
+ result = DRS_FAIL;
+ }catch(...){
+ //INFOS("Unknown exception was cought !!!");
+ result = DRS_FAIL;
+ }
+
+ if (!anElement) {
+ result = DRS_WARN_SKIP_ELEM;
+ }
+ else {
+ if (isRenum) {
+ anIsElemNum = MED_FAUX;
+ takeNumbers = false;
+ if (result < DRS_WARN_RENUMBER)
+ result = DRS_WARN_RENUMBER;
+ }
+ if (myFamilies.find(aFamNum) != myFamilies.end()) {
+ // Save reference to this element from its family
+ myFamilies[aFamNum]->AddElement(anElement);
+ myFamilies[aFamNum]->SetType(anElement->GetType());
+ }
+ }
+ }
+ }
}
+ break;
+ }
+ }
+ }catch(const std::exception& exc){
+ INFOS("Follow exception was cought:\n\t"<<exc.what());
+ result = DRS_FAIL;
+ }catch(...){
+ INFOS("Unknown exception was cought !!!");
+ result = DRS_FAIL;
+ }
+ MESSAGE("ReadMySelf - result status = "<<result);
+ return result;
+}
- fprintf(stdout, "\n- Numeros des familles des noeuds : \n");
- for (i = 0; i < nnoe; i++)
- fprintf(stdout, " %d ", *(nufano + i));
- fprintf(stdout, "\n");
-
- /* liberation memoire */
- free(coo);
- free(nomnoe);
- free(numnoe);
- free(nufano);
-
- /****************************************************************************
- * LECTURE DES ELEMENTS *
- ****************************************************************************/
- fprintf(stdout, "\n(**************************)\n");
- fprintf(stdout, "(* ELEMENTS DU MAILLAGE : *)\n");
- fprintf(stdout, "(**************************)");
- //fprintf(Out,"CELLS\n");
- /* Lecture des connectivites, noms, numeros des mailles */
- //printf("%d %d %d %d\n",nmailles[3],nmailles[4],nmailles[5],nmailles[9]);
-
- if (ret == 0)
- for (i = 0; i < MED_NBR_GEOMETRIE_MAILLE; i++)
- {
- if (nmailles[i] > 0 && ret == 0)
- {
- /* dimension de la maille */
- edim = typmai[i] / 100;
- nsup = 0;
- if (mdim == 2 || mdim == 3)
- if (edim == 1)
- nsup = 1;
- if (mdim == 3)
- if (edim == 2)
- nsup = 1;
-
- taille = nsup + typmai[i] % 100;
- //taille = typmai[i]%100;
-
- /* allocation memoire */
- connectivite = (med_int *) malloc(sizeof(med_int) *
- taille * nmailles[i]);
- nomele = (char *)malloc(sizeof(char) * MED_TAILLE_PNOM *
- nmailles[i] + 1);
- numele = (med_int *) malloc(sizeof(med_int) * nmailles[i]);
- nufael = (med_int *) malloc(sizeof(med_int) * nmailles[i]);
-
- /* lecture des données */
- ret =
- MEDelementsLire(myFileId, nommaa, mdim, connectivite,
- mode_coo, nomele, &inoele, numele, &inuele, nufael,
- nmailles[i], MED_MAILLE, typmai[i], typ_con);
-
- switch (typmai[i])
- {
- case MED_TRIA3:
- {
- if (inuele)
- {
- for (j = 0; j < nmailles[i]; j++)
- {
- elem_id = *(numele + j);
- ok = mySMESHDSMesh->AddFaceWithID(*(connectivite +
- j * (taille - nsup)),
- *(connectivite + j * (taille - nsup) + 1),
- *(connectivite + j * (taille - nsup) + 2),
- elem_id);
- //fprintf(Out,"%d %d %d %d\n",elem_id,*(connectivite+j*(taille-nsup)),*(connectivite+j*(taille-nsup)+1),*(connectivite+j*(taille-nsup)+2));
- }
- }
- else
- {
- for (j = 0; j < nmailles[i]; j++)
- {
- cmpt++;
- ok = mySMESHDSMesh->AddFaceWithID(*(connectivite +
- j * (taille)),
- *(connectivite + j * (taille) + 1),
- *(connectivite + j * (taille) + 2), cmpt);
- //fprintf(Out,"%d %d %d %d\n",j,*(connectivite+j*(taille)),*(connectivite+j*(taille)+1),*(connectivite+j*(taille)+2));
- }
- }
-
- break;
- }
- case MED_QUAD4:
- {
- if (inuele)
- {
- for (j = 0; j < nmailles[i]; j++)
- {
- elem_id = *(numele + j);
- ok = mySMESHDSMesh->AddFaceWithID(*(connectivite +
- j * (taille - nsup)),
- *(connectivite + j * (taille - nsup) + 1),
- *(connectivite + j * (taille - nsup) + 2),
- *(connectivite + j * (taille - nsup) + 3),
- elem_id);
- //fprintf(Out,"%d %d %d %d\n",elem_id,*(connectivite+j*(taille-nsup)),*(connectivite+j*(taille-nsup)+1),*(connectivite+j*(taille-nsup)+2),*(connectivite+j*(taille-nsup)+3));
- }
- }
- else
- {
- for (j = 0; j < nmailles[i]; j++)
- {
- cmpt++;
- ok = myMesh->AddFaceWithID(*(connectivite +
- j * (taille)),
- *(connectivite + j * (taille) + 1),
- *(connectivite + j * (taille) + 2),
- *(connectivite + j * (taille) + 3), cmpt);
- //fprintf(Out,"%d %d %d %d\n",j,*(connectivite+j*(taille)),*(connectivite+j*(taille)+1),*(connectivite+j*(taille)+2),*(connectivite+j*(taille)+3));
- }
- }
- break;
- }
- case MED_TETRA4:
- {
- if (inuele)
- {
- for (j = 0; j < nmailles[i]; j++)
- {
- elem_id = *(numele + j);
- ok = mySMESHDSMesh->AddVolumeWithID(*(connectivite +
- j * (taille - nsup)),
- *(connectivite + j * (taille - nsup) + 1),
- *(connectivite + j * (taille - nsup) + 2),
- *(connectivite + j * (taille - nsup) + 3),
- elem_id);
- //fprintf(Out,"%d %d %d %d\n",elem_id,*(connectivite+j*(taille-nsup)),*(connectivite+j*(taille-nsup)+1),*(connectivite+j*(taille-nsup)+2),*(connectivite+j*(taille-nsup)+3));
- }
- }
- else
- {
- for (j = 0; j < nmailles[i]; j++)
- {
- cmpt++;
- ok = mySMESHDSMesh->AddVolumeWithID(*(connectivite +
- j * (taille)),
- *(connectivite + j * (taille) + 1),
- *(connectivite + j * (taille) + 2),
- *(connectivite + j * (taille) + 3), cmpt);
- //fprintf(Out,"%d %d %d %d\n",j,*(connectivite+j*(taille)),*(connectivite+j*(taille)+1),*(connectivite+j*(taille)+2),*(connectivite+j*(taille)+3));
- }
- }
- break;
- }
- case MED_HEXA8:
- {
- if (inuele)
- {
- for (j = 0; j < nmailles[i]; j++)
- {
- elem_id = *(numele + j);
- ok = mySMESHDSMesh->AddVolumeWithID(*(connectivite +
- j * (taille - nsup)),
- *(connectivite + j * (taille - nsup) + 1),
- *(connectivite + j * (taille - nsup) + 2),
- *(connectivite + j * (taille - nsup) + 3),
- *(connectivite + j * (taille - nsup) + 4),
- *(connectivite + j * (taille - nsup) + 5),
- *(connectivite + j * (taille - nsup) + 6),
- *(connectivite + j * (taille - nsup) + 7),
- elem_id);
- //fprintf(Out,"%d %d %d %d\n",elem_id,*(connectivite+j*(taille-nsup)),*(connectivite+j*(taille-nsup)+1),*(connectivite+j*(taille-nsup)+2),*(connectivite+j*(taille-nsup)+3),*(connectivite+j*(taille-nsup)+4),*(connectivite+j*(taille-nsup)+5),*(connectivite+j*(taille-nsup)+6),*(connectivite+j*(taille-nsup)+7));
- }
- }
- else
- {
- for (j = 0; j < nmailles[i]; j++)
- {
- cmpt++;
- ok = mySMESHDSMesh->AddVolumeWithID(*(connectivite +
- j * (taille)),
- *(connectivite + j * (taille) + 1),
- *(connectivite + j * (taille) + 2),
- *(connectivite + j * (taille) + 3),
- *(connectivite + j * (taille) + 4),
- *(connectivite + j * (taille) + 5),
- *(connectivite + j * (taille) + 6),
- *(connectivite + j * (taille) + 7), cmpt);
- //fprintf(Out,"%d %d %d %d\n",j,*(connectivite+j*(taille)),*(connectivite+j*(taille)+1),*(connectivite+j*(taille)+2),*(connectivite+j*(taille)+3),*(connectivite+j*(taille)+4),*(connectivite+j*(taille)+5),*(connectivite+j*(taille)+6),*(connectivite+j*(taille)+7));
- }
- }
- break;
- }
- default:
- {
- break;
- }
- }
-
- fprintf(stdout, "\n - Numéros de familles : \n");
- for (j = 0; j < nmailles[i]; j++)
- fprintf(stdout, " %d ", *(nufael + j));
-
- /* liberation memoire */
- free(connectivite);
- free(nomele);
- free(numele);
- free(nufael);
- }
- }
-
- /****************************************************************************
- * LECTURE DES FAMILLES *
- ****************************************************************************/
- printf("\n(*************************)\n");
- printf("(* FAMILLES DU MAILLAGE : *)\n");
- printf("(*************************)\n");
- if (ret == 0)
- for (i = 0; i < nfam; i++)
- {
-
- /* nombre de groupes */
- ngro = MEDnFam(myFileId, nommaa, i + 1, MED_GROUPE);
- if (ngro < 0)
- {
- ret = -1;
- strcpy(message,
- ">> ERREUR : lecture du nombre de groupes d'une famille \n");
- }
-
- /* nombre d'attributs */
- if (ret == 0)
- {
- natt = MEDnFam(myFileId, nommaa, i + 1, MED_ATTR);
- if (natt < 0)
- {
- ret = -1;
- strcpy(message,
- ">> ERREUR : lecture du nombre d'attributs d'une famille\n");
- }
- }
-
- if (ret == 0)
- fprintf(stdout, "- Famille %d a %d attributs et %d groupes \n",
- i + 1, natt, ngro);
-
- /* nom,numero,attributs,groupes */
- if (ret == 0)
- {
- attide = (med_int *) malloc(sizeof(med_int) * natt);
- attval = (med_int *) malloc(sizeof(med_int) * natt);
- attdes = (char *)malloc(MED_TAILLE_DESC * natt + 1);
- gro = (char *)malloc(MED_TAILLE_LNOM * ngro + 1);
- ret =
- MEDfamInfo(myFileId, nommaa, i + 1, nomfam, &numfam, attide,
- attval, attdes, &natt, gro, &ngro);
-
- fam = string(nomfam);
- fam_type = fam.substr(1, 1);
- fam_id = fam.substr(2, 1);
- if ((fam_type == string("V")) || (fam_type == string("A")) ||
- (fam_type == string("F")))
- LinkMeshToShape(fam_type, fam_id, family[i]);
-
- fprintf(stdout, " - Famille de nom %s et de numero %d : \n",
- nomfam, numfam);
- fprintf(stdout, " - Attributs : \n");
- for (j = 0; j < natt; j++)
- {
- strncpy(str1, attdes + j * MED_TAILLE_DESC,
- MED_TAILLE_DESC);
- str1[MED_TAILLE_DESC] = '\0';
- fprintf(stdout, " ide = %d - val = %d - des = %s\n",
- *(attide + j), *(attval + j), str1);
- }
- free(attide);
- free(attval);
- free(attdes);
- fprintf(stdout, " - Groupes :\n");
- for (j = 0; j < ngro; j++)
- {
- strncpy(str2, gro + j * MED_TAILLE_LNOM, MED_TAILLE_LNOM);
- str2[MED_TAILLE_LNOM] = '\0';
- fprintf(stdout, " gro = %s\n", str2);
- }
- free(gro);
- }
- }
-
- if (locally_managed)
- ret = MEDfermer(myFileId);
-
+list<string> DriverMED_R_SMESHDS_Mesh::GetMeshNames()
+{
+ list<string> aMeshNames;
+
+ try {
+ using namespace MEDA;
+
+ MESSAGE("GetMeshNames - myFile : " << myFile);
+ TWrapper aMed (myFile);
+
+ if (med_int aNbMeshes = aMed.GetNbMeshes()) {
+ for (int iMesh = 0; iMesh < aNbMeshes; iMesh++) {
+ // Reading the MED mesh
+ //---------------------
+ PMeshInfo aMeshInfo = aMed.GetMeshInfo(iMesh);
+ aMeshNames.push_back(aMeshInfo->GetName());
+ }
+ }
+ }catch(const std::exception& exc){
+ INFOS("Follow exception was cought:\n\t"<<exc.what());
+ }catch(...){
+ INFOS("Unknown exception was cought !!!");
+ }
+
+ return aMeshNames;
}
-void DriverMED_R_SMESHDS_Mesh::LinkMeshToShape(string fam_type, string fam_id,
- vector < int >myNodes)
+list<string> DriverMED_R_SMESHDS_Mesh::GetGroupNames()
{
+ list<string> aResult;
+ set<string> aResGroupNames;
+
+ map<int, DriverMED_FamilyPtr>::iterator aFamsIter = myFamilies.begin();
+ for (; aFamsIter != myFamilies.end(); aFamsIter++)
+ {
+ DriverMED_FamilyPtr aFamily = (*aFamsIter).second;
+ const MED::TStringSet& aGroupNames = aFamily->GetGroupNames();
+ set<string>::iterator aGrNamesIter = aGroupNames.begin();
+ for (; aGrNamesIter != aGroupNames.end(); aGrNamesIter++)
+ {
+ string aName = *aGrNamesIter;
+ // Check, if this is a Group or SubMesh name
+//if (aName.substr(0, 5) == string("Group")) {
+ if (aResGroupNames.find(aName) == aResGroupNames.end()) {
+ aResGroupNames.insert(aName);
+ aResult.push_back(aName);
+ }
+// }
+ }
+ }
+
+ return aResult;
+}
- SMESHDS_Mesh * mySMESHDSMesh = dynamic_cast<SMESHDS_Mesh *>(myMesh);
+void DriverMED_R_SMESHDS_Mesh::GetGroup(SMESHDS_Group* theGroup)
+{
+ string aGroupName (theGroup->GetStoreName());
+ MESSAGE("Get Group " << aGroupName);
+
+ map<int, DriverMED_FamilyPtr>::iterator aFamsIter = myFamilies.begin();
+ for (; aFamsIter != myFamilies.end(); aFamsIter++)
+ {
+ DriverMED_FamilyPtr aFamily = (*aFamsIter).second;
+ if (aFamily->MemberOf(aGroupName))
+ {
+ const set<const SMDS_MeshElement *>& anElements = aFamily->GetElements();
+ set<const SMDS_MeshElement *>::iterator anElemsIter = anElements.begin();
+ for (; anElemsIter != anElements.end(); anElemsIter++)
+ {
+ theGroup->SMDS_MeshGroup::Add(*anElemsIter);
+ }
+ }
+ }
+}
- int id = atoi(fam_id.c_str());
- if (fam_type == string("V"))
- { //Linked to a vertex
- for (int i = 0; i < myNodes.size(); i++)
- {
- const SMDS_MeshNode * node = mySMESHDSMesh->FindNode(myNodes[i]);
- //const TopoDS_Vertex& S;//le recuperer !!!
- //mySMESHDSMesh->SetNodeOnVertex (node,S);
- }
- }
- else if (fam_type == string("E"))
- { //Linked to an edge
- for (int i = 0; i < myNodes.size(); i++)
- {
- const SMDS_MeshNode * node = mySMESHDSMesh->FindNode(myNodes[i]);
- //const TopoDS_Edge& S;//le recuperer !!!
- //mySMESHDSMesh->SetNodeOnEdge (node,S);
- }
- }
- else if (fam_type == string("F"))
- { //Linked to a face
- for (int i = 0; i < myNodes.size(); i++)
- {
- const SMDS_MeshNode * node = mySMESHDSMesh->FindNode(myNodes[i]);
- //const TopoDS_Face& S;//le recuperer !!!
- //mySMESHDSMesh->SetNodeOnFace (node,S);
- }
- }
+void DriverMED_R_SMESHDS_Mesh::GetSubMesh (SMESHDS_SubMesh* theSubMesh,
+ const int theId)
+{
+ char submeshGrpName[ 30 ];
+ sprintf( submeshGrpName, "SubMesh %d", theId );
+ string aName (submeshGrpName);
+ map<int, DriverMED_FamilyPtr>::iterator aFamsIter = myFamilies.begin();
+ for (; aFamsIter != myFamilies.end(); aFamsIter++)
+ {
+ DriverMED_FamilyPtr aFamily = (*aFamsIter).second;
+ if (aFamily->MemberOf(aName))
+ {
+ const set<const SMDS_MeshElement *>& anElements = aFamily->GetElements();
+ set<const SMDS_MeshElement *>::iterator anElemsIter = anElements.begin();
+ if (aFamily->GetType() == SMDSAbs_Node)
+ {
+ for (; anElemsIter != anElements.end(); anElemsIter++)
+ {
+ const SMDS_MeshNode* node = static_cast<const SMDS_MeshNode*>(*anElemsIter);
+ theSubMesh->AddNode(node);
+ }
+ }
+ else
+ {
+ for (; anElemsIter != anElements.end(); anElemsIter++)
+ {
+ theSubMesh->AddElement(*anElemsIter);
+ }
+ }
+ }
+ }
+}
+void DriverMED_R_SMESHDS_Mesh::CreateAllSubMeshes ()
+{
+ SMESHDS_Mesh* aSMESHDSMesh = dynamic_cast<SMESHDS_Mesh*>(myMesh);
+ if (!aSMESHDSMesh) {
+ EXCEPTION(runtime_error,"Can not cast SMDS_Mesh to SMESHDS_Mesh");
+ }
+ map<int, DriverMED_FamilyPtr>::iterator aFamsIter = myFamilies.begin();
+ for (; aFamsIter != myFamilies.end(); aFamsIter++)
+ {
+ DriverMED_FamilyPtr aFamily = (*aFamsIter).second;
+ MED::TStringSet aGroupNames = aFamily->GetGroupNames();
+ set<string>::iterator aGrNamesIter = aGroupNames.begin();
+ for (; aGrNamesIter != aGroupNames.end(); aGrNamesIter++)
+ {
+ string aName = *aGrNamesIter;
+ // Check, if this is a Group or SubMesh name
+ if (aName.substr(0, 7) == string("SubMesh"))
+ {
+ int Id = atoi(string(aName).substr(7).c_str());
+ set<const SMDS_MeshElement *> anElements = aFamily->GetElements();
+ set<const SMDS_MeshElement *>::iterator anElemsIter = anElements.begin();
+ if (aFamily->GetType() == SMDSAbs_Node)
+ {
+ for (; anElemsIter != anElements.end(); anElemsIter++)
+ {
+ const SMDS_MeshNode* node = static_cast<const SMDS_MeshNode*>(*anElemsIter);
+ aSMESHDSMesh->SetNodeInVolume(node, Id);
+// aSMESHDSMesh->SetNodeOnFace(node, Id);
+// aSMESHDSMesh->SetNodeOnEdge(node, Id);
+// aSMESHDSMesh->SetNodeOnVertex(node, Id);
+ }
+ }
+ else
+ {
+ for (; anElemsIter != anElements.end(); anElemsIter++)
+ {
+ aSMESHDSMesh->SetMeshElementOnShape(*anElemsIter, Id);
+ }
+ }
+ }
+ }
+ }
}
#include "SMESHDS_Mesh.hxx"
#include "Mesh_Reader.h"
+#include "DriverMED_Family.h"
-#include <vector>
+#include <list>
extern "C"
{
#include <med.h>
}
+using namespace std;
+
+class SMESHDS_Group;
+class SMESHDS_SubMesh;
+
class DriverMED_R_SMESHDS_Mesh:public Mesh_Reader
{
+ public:
+
+ DriverMED_R_SMESHDS_Mesh();
+ ~DriverMED_R_SMESHDS_Mesh();
+
+ enum ReadStatus {
+ DRS_OK,
+ DRS_EMPTY, // a MED file contains no mesh with the given name
+ DRS_WARN_RENUMBER, // a MED file has overlapped ranges of element numbers,
+ // so the numbers from the file are ignored
+ DRS_WARN_SKIP_ELEM, // some elements were skipped due to incorrect file data
+ DRS_FAIL // general failure (exception etc.)
+ };
+
+ void Read();
+ ReadStatus ReadMySelf();
+ void Add();
- public:DriverMED_R_SMESHDS_Mesh();
- ~DriverMED_R_SMESHDS_Mesh();
+ list<string> GetGroupNames();
+ void GetGroup(SMESHDS_Group* theGroup);
+ void CreateAllSubMeshes();
+ void GetSubMesh(SMESHDS_SubMesh* theSubMesh, const int theId);
- void Read();
- void ReadMySelf();
- void Add();
+ list<string> GetMeshNames();
- void SetMesh(SMDS_Mesh * aMesh);
- void SetFile(string);
- void SetFileId(med_idt);
- void SetMeshId(int);
+ void SetMesh(SMDS_Mesh * aMesh);
+ void SetFile(string);
+ void SetFileId(med_idt);
+ void SetMeshId(int);
+ void SetMeshName(string theMeshName);
- void LinkMeshToShape(string, string, vector < int >);
+ private:
- private: SMDS_Mesh * myMesh;
- string myFile;
- med_idt myFileId;
- int myMeshId;
+ SMDS_Mesh * myMesh;
+ string myFile;
+ med_idt myFileId;
+ int myMeshId;
+ string myMeshName;
+ map<int, DriverMED_FamilyPtr> myFamilies;
};
#endif
for (i = 0; i < MED_NBR_GEOMETRIE_MAILLE; i++)
nmailles[i] = 0;
- SMDS_Iterator<const SMDS_MeshFace *> * itFaces=myMesh->facesIterator();
+ SMDS_FaceIteratorPtr itFaces=myMesh->facesIterator();
int nb_of_nodes, nb_of_faces;
nb_of_faces = myMesh->NbFaces();
//SCRUTE(nb_of_faces);
}
- SMDS_Iterator<const SMDS_MeshVolume*> * itVolumes=myMesh->volumesIterator();
+ SMDS_VolumeIteratorPtr itVolumes=myMesh->volumesIterator();
while(itVolumes->more())
{
const SMDS_MeshVolume * elem = itVolumes->next();
nomnoe = "";
i = 0;
- SMDS_Iterator<const SMDS_MeshNode *> * itNodes=myMesh->nodesIterator();
+ SMDS_NodeIteratorPtr itNodes=myMesh->nodesIterator();
while(itNodes->more())
{
const SMDS_MeshNode * node = itNodes->next();
//elem_id=*(numele+j);
//fprintf(stdout,"%d \n",myId);
- SMDS_Iterator<const SMDS_MeshElement *> * itNode=
- elem->nodesIterator();
+ SMDS_ElemIteratorPtr itNode= elem->nodesIterator();
while(itNode->more())
{
// File : DriverMED_W_SMESHDS_Mesh.cxx
// Module : SMESH
-using namespace std;
#include "DriverMED_W_SMESHDS_Mesh.h"
#include "DriverMED_W_SMDS_Mesh.h"
+#include "DriverMED_Family.h"
+
#include "SMDS_MeshElement.hxx"
#include "SMDS_MeshNode.hxx"
-#include <TopExp.hxx>
-#include <vector>
#include "utilities.h"
-extern "C"
-{
-/**
- * Factory function which will be called by SMESHDriver
- */
-void * SMESH_createMEDMeshWriter()
-{
- return new DriverMED_W_SMESHDS_Mesh();
-}
+#include "MEDA_Wrapper.hxx"
+#include <sstream>
-}
+#include "MED_Utilities.hxx"
DriverMED_W_SMESHDS_Mesh::DriverMED_W_SMESHDS_Mesh()
+ :
+ myMesh (NULL),
+ myFile (""),
+ myFileId (-1),
+ myMeshId (-1),
+ myAllSubMeshes (false),
+ myDoGroupOfNodes (false),
+ myDoGroupOfEdges (false),
+ myDoGroupOfFaces (false),
+ myDoGroupOfVolumes (false)
{
- ;
}
DriverMED_W_SMESHDS_Mesh::~DriverMED_W_SMESHDS_Mesh()
{
- ;
}
void DriverMED_W_SMESHDS_Mesh::SetMesh(SMDS_Mesh * aMesh)
{
- myMesh = aMesh;
+ myMesh = aMesh;
}
void DriverMED_W_SMESHDS_Mesh::SetFile(string aFile)
{
- myFile = aFile;
+ myFile = aFile;
}
void DriverMED_W_SMESHDS_Mesh::SetFileId(med_idt aFileId)
{
- myFileId = aFileId;
+ myFileId = aFileId;
}
void DriverMED_W_SMESHDS_Mesh::SetMeshId(int aMeshId)
{
- myMeshId = aMeshId;
+ myMeshId = aMeshId;
}
-void DriverMED_W_SMESHDS_Mesh::Write()
+void DriverMED_W_SMESHDS_Mesh::SetMeshName(string theMeshName)
{
- Add();
+ myMeshName = theMeshName;
}
-void DriverMED_W_SMESHDS_Mesh::Add()
+void DriverMED_W_SMESHDS_Mesh::AddGroup(SMESHDS_Group* theGroup)
{
+ myGroups.push_back(theGroup);
+}
- med_err ret = 0;
- int i, j, k, l;
- int numero;
- char message[200];
- bool ok;
- /* nombre d'objets MED */
- char nom_universel[MED_TAILLE_LNOM + 1];
- med_int long_fichier_en_tete;
- char *fichier_en_tete;
- char version_hdf[10];
- char version_med[10];
- med_int nmaa, mdim, nnoe;
- med_int nmai[MED_NBR_GEOMETRIE_MAILLE], nfac[MED_NBR_GEOMETRIE_FACE];
- med_int nare[MED_NBR_GEOMETRIE_ARETE];
- /* nom du maillage */
- char nommaa[MED_TAILLE_NOM + 1];
- /* noeuds */
- med_float *coo;
- // PN : Initilialisation de nomcoo et unicoo pour lisibilite du maillage
- char nomcoo[3 * MED_TAILLE_PNOM + 1] = "x y z ";
- char unicoo[3 * MED_TAILLE_PNOM + 1] = "m m m ";
- char *nomnoe;
- med_int *numnoe;
- med_int *nufano;
- med_repere rep;
- med_booleen inonoe, inunoe;
- med_mode_switch mode_coo;
- char str[MED_TAILLE_PNOM + 1];
- med_int nbNodes;
- /* elements */
- med_int nsup;
- med_int edim;
- med_int taille;
- med_int elem_id, myId;
- med_int *connectivite;
- char *nomele;
- med_int *numele;
- med_int *nufael;
- med_booleen inoele, inuele;
- med_connectivite typ_con;
- med_geometrie_element typgeo;
- med_geometrie_element typmai[MED_NBR_GEOMETRIE_MAILLE] =
- { MED_POINT1, MED_SEG2,
- MED_SEG3, MED_TRIA3,
- MED_TRIA6, MED_QUAD4,
- MED_QUAD8, MED_TETRA4,
- MED_TETRA10, MED_HEXA8,
- MED_HEXA20, MED_PENTA6,
- MED_PENTA15, MED_PYRA5,
- MED_PYRA13
- };
- med_int desmai[MED_NBR_GEOMETRIE_MAILLE] =
- { 0, 2, 3, 3, 3, 4, 4, 4, 4, 6, 6, 5, 5, 5, 5 };
- med_int nmailles[MED_NBR_GEOMETRIE_MAILLE];
- char nommai[MED_NBR_GEOMETRIE_MAILLE][MED_TAILLE_NOM + 1] = { "MED_POINT1",
- "MED_SEG2",
- "MED_SEG3",
- "MED_TRIA3",
- "MED_TRIA6",
- "MED_QUAD4",
- "MED_QUAD8",
- "MED_TETRA4",
- "MED_TETRA10",
- "MED_HEXA8",
- "MED_HEXA20",
- "MED_PENTA6",
- "MED_PENTA15",
- "MED_PYRA5",
- "MED_PYRA13"
- };
- med_geometrie_element typfac[MED_NBR_GEOMETRIE_FACE] =
- { MED_TRIA3, MED_TRIA6,
- MED_QUAD4, MED_QUAD8
- };
- med_int desfac[MED_NBR_GEOMETRIE_FACE] = { 3, 3, 4, 4 };
- med_int nfaces[MED_NBR_GEOMETRIE_FACE];
- char nomfac[MED_NBR_GEOMETRIE_FACE][MED_TAILLE_NOM + 1] =
- { "MED_TRIA3", "MED_TRIA6",
- "MED_QUAD4", "MED_QUAD8"
- };
- med_geometrie_element typare[MED_NBR_GEOMETRIE_ARETE] =
- { MED_SEG2, MED_SEG3 };
- med_int desare[MED_NBR_GEOMETRIE_ARETE] = { 2, 3 };
- med_int naretes[MED_NBR_GEOMETRIE_ARETE];
- char nomare[MED_NBR_GEOMETRIE_ARETE][MED_TAILLE_NOM + 1] =
- { "MED_SEG2", "MED_SEG3" };
-
- typ_con = MED_NOD;
- mode_coo = MED_FULL_INTERLACE;
- numero = myMeshId;
-
- //---- provisoire : switch pour ecrire les familles de mailles
- int besoinfamilledemaille = 1;
- //---- provisoire : switch pour ecrire les familles de mailles
-
- /****************************************************************************
- * OUVERTURE DU FICHIER EN ECRITURE *
- ****************************************************************************/
- char *file2Read = (char *)myFile.c_str();
-
- MESSAGE(" file2Read " << file2Read)
- myFileId = MEDouvrir(file2Read, MED_REMP);
- if (myFileId < 0)
- {
- fprintf(stderr, ">> ERREUR : ouverture du fichier %s \n", file2Read);
- exit(EXIT_FAILURE);
- }
-
- /****************************************************************************
- * NOMBRES D'OBJETS MED *
- ****************************************************************************/
- MESSAGE("(****************************)");
- MESSAGE("(* INFORMATIONS GENERALES : *)");
- MESSAGE("(****************************)");
-
- /* calcul de la dimension */
- mdim = 2;
- double epsilon = 0.00001;
- double nodeRefX;
- double nodeRefY;
- double nodeRefZ;
-
- bool dimX = true;
- bool dimY = true;
- bool dimZ = true;
-
- int inode = 0;
- SMDS_Iterator<const SMDS_MeshNode *> * myItNodes=myMesh->nodesIterator();
- while(myItNodes->more())
- {
- const SMDS_MeshNode * node = myItNodes->next();
- if (inode == 0)
- {
- nodeRefX = fabs(node->X());
- nodeRefY = fabs(node->Y());
- nodeRefZ = fabs(node->Z());
- }
- SCRUTE(inode);
- SCRUTE(nodeRefX);
- SCRUTE(nodeRefY);
- SCRUTE(nodeRefZ);
-
- if (inode != 0)
- {
- if ((fabs(fabs(node->X()) - nodeRefX) > epsilon) && dimX)
- dimX = false;
- if ((fabs(fabs(node->Y()) - nodeRefY) > epsilon) && dimY)
- dimY = false;
- if ((fabs(fabs(node->Z()) - nodeRefZ) > epsilon) && dimZ)
- dimZ = false;
- }
- if (!dimX && !dimY && !dimZ)
- {
- mdim = 3;
- break;
- }
- inode++;
- }
-
- if (mdim != 3)
- {
- if (dimX && dimY && dimZ)
- mdim = 0;
- else if (!dimX)
- {
- if (dimY && dimZ)
- mdim = 1;
- else if ((dimY && !dimZ) || (!dimY && dimZ))
- mdim = 2;
- }
- else if (!dimY)
- {
- if (dimX && dimZ)
- mdim = 1;
- else if ((dimX && !dimZ) || (!dimX && dimZ))
- mdim = 2;
- }
- else if (!dimZ)
- {
- if (dimY && dimX)
- mdim = 1;
- else if ((dimY && !dimX) || (!dimY && dimX))
- mdim = 2;
- }
- }
-
- MESSAGE(" mdim " << mdim);
-
- /* creation du maillage */
- //mdim=3;
- sprintf(nommaa, "Mesh %d", numero);
- SCRUTE(nommaa);
- ret = MEDmaaCr(myFileId, nommaa, mdim);
-
- ASSERT(ret == 0);
- SCRUTE(ret);
-
- /* Combien de noeuds ? */
- nnoe = myMesh->NbNodes();
- //SCRUTE(nnoe);
- /* Combien de mailles, faces ou aretes ? */
- for (i = 0; i < MED_NBR_GEOMETRIE_MAILLE; i++)
- nmailles[i] = 0;
-
- int nb_of_nodes, nb_of_faces, nb_of_edges;
- vector < int >elem_Id[MED_NBR_GEOMETRIE_MAILLE];
-
- nb_of_edges = myMesh->NbEdges();
- SMDS_Iterator<const SMDS_MeshEdge *> * itEdges=myMesh->edgesIterator();
- while(itEdges->more())
- {
- const SMDS_MeshEdge * elem = itEdges->next();
-
- nb_of_nodes = elem->NbNodes();
-
- switch (nb_of_nodes)
- {
- case 2:
- {
- elem_Id[1].push_back(elem->GetID());
- nmailles[1]++;
- break;
- }
- case 3:
- {
- elem_Id[2].push_back(elem->GetID());
- nmailles[2]++;
- break;
- }
- }
- }
-
- nb_of_faces = myMesh->NbFaces();
- SMDS_Iterator<const SMDS_MeshFace *> * itFaces=myMesh->facesIterator();
- while(itFaces->more())
- {
- const SMDS_MeshElement * elem = itFaces->next();
-
- nb_of_nodes = elem->NbNodes();
-
- switch (nb_of_nodes)
- {
- case 3:
- {
- elem_Id[3].push_back(elem->GetID());
- nmailles[3]++;
- break;
- }
- case 4:
- {
- elem_Id[5].push_back(elem->GetID());
- nmailles[5]++;
- break;
- }
- case 6:
- {
- elem_Id[4].push_back(elem->GetID());
- nmailles[4]++;
- break;
- }
- }
-
- }
-
- SMDS_Iterator<const SMDS_MeshVolume *> * itVolumes=myMesh->volumesIterator();
- while(itVolumes->more())
- {
- const SMDS_MeshElement * elem = itVolumes->next();
-
- nb_of_nodes = elem->NbNodes();
- switch (nb_of_nodes)
- {
- case 8:
- {
- elem_Id[9].push_back(elem->GetID());
- nmailles[9]++;
- break;
- }
- case 4 :
- {
- elem_Id[7].push_back(elem->GetID());
- nmailles[7]++;
- break;
- }
- }
- }
-
- /****************************************************************************
- * ECRITURE DES NOEUDS *
- ****************************************************************************/
- MESSAGE("(************************)");
- MESSAGE("(* NOEUDS DU MAILLAGE : *)");
- MESSAGE("(************************)");
-
- /* Allocations memoires */
- /* table des coordonnees
- * profil : (dimension * nombre de noeuds ) */
- coo = (med_float *) malloc(sizeof(med_float) * nnoe * mdim);
- /* table des numeros, des numeros de familles des noeuds
- * profil : (nombre de noeuds) */
- numnoe = (med_int *) malloc(sizeof(med_int) * nnoe);
- nufano = (med_int *) malloc(sizeof(med_int) * nnoe);
- /* table des noms des noeuds
- * profil : (nnoe*MED_TAILLE_PNOM+1) */
- nomnoe = "";
-
- /* PN pour aster, il faut une famille 0 pour les noeuds et une autre pour les elements */
- /* PN : Creation de la famille 0 */
- char *nomfam = "FAMILLE_0";
- char *attdes = "";
- char *gro = 0;
- med_int ngro = 0;
- med_int natt = 1;
- med_int attide = 0;
- med_int attval = 0;
- med_int numfam = 0;
- med_int attvalabs = 1;
- ret =
- MEDfamCr(myFileId, nommaa, nomfam, numfam, &attide, &attval, attdes,
- natt, gro, ngro);
- ASSERT(ret == 0);
-
- /* PN : FIN Creation de la famille 0 */
-
- map < int, int >mapNoeud;
- typedef pair < set < int >::iterator, bool > IsFamily;
- int nbFamillesNoeud;
-
- i = 0;
- set < int >FamilySet;
- nbFamillesNoeud = 0;
- int verifienbnoeuds = 0;
- med_int *rien = 0;
-
- SMDS_Iterator<const SMDS_MeshNode *> * itNodes=myMesh->nodesIterator();
- while(itNodes->more())
- {
- const SMDS_MeshNode * node = itNodes->next();
-
- if (mdim == 3)
- {
- coo[i * 3] = node->X();
- coo[i * 3 + 1] = node->Y();
- coo[i * 3 + 2] = node->Z();
- }
- else if (mdim == 2)
- {
- if (dimX)
- {
- coo[i * 2] = node->Y();
- coo[i * 2 + 1] = node->Z();
- }
- if (dimY)
- {
- coo[i * 2] = node->X();
- coo[i * 2 + 1] = node->Z();
- }
- if (dimZ)
- {
- coo[i * 2] = node->X();
- coo[i * 2 + 1] = node->Y();
- }
- }
- else
- {
- if (dimX)
- {
- coo[i * 2] = node->Y();
- coo[i * 2 + 1] = node->Z();
- }
- if (dimY)
- {
- coo[i * 2] = node->X();
- coo[i * 2 + 1] = node->Z();
- }
- if (dimZ)
- {
- coo[i * 2] = node->X();
- coo[i * 2 + 1] = node->Y();
- }
- }
- mapNoeud[node->GetID()] = i + 1;
-
- // renvoie 0 pour les noeuds internes du volume
- int numfamille = node->GetPosition()->GetShapeId();
- nufano[i] = numfamille;
-
- //SCRUTE(i);
- //SCRUTE(nufano[i]);
- //SCRUTE(coo[i*3]);
- //SCRUTE(coo[i*3+1]);
- //SCRUTE(coo[i*3+2]);
- if (nufano[i] != 0)
- {
- IsFamily deja = FamilySet.insert(nufano[i]); // insert if new, or gives existant
- if (deja.second) // actually inserted
- {
- char famille[MED_TAILLE_NOM + 1];
- sprintf(famille, "F%d", nufano[i]);
- // CreateFamily(strdup(nommaa),strdup(famille),nufano[i],attvalabs++);
- attvalabs++;
- CreateFamily(strdup(nommaa), strdup(famille), nufano[i],
- numfamille);
- //MESSAGE("---famille-noeud--- "<<nbFamillesNoeud<<" "<<nufano[i]);
- nbFamillesNoeud++;
- }
- }
-
- i++;
- verifienbnoeuds++;
- }
- ret = MEDnoeudsEcr(myFileId, nommaa, mdim, coo, mode_coo, MED_CART,
- nomcoo, unicoo, nomnoe, MED_FAUX, rien, MED_FAUX,
- nufano, nnoe, MED_REMP);
- ASSERT(ret == 0);
- MESSAGE("--- Creation de " << verifienbnoeuds << " noeuds");
- ASSERT(verifienbnoeuds == nnoe);
- MESSAGE("--- Creation de " << nbFamillesNoeud << " familles de noeuds");
-
- /* liberation memoire */
- free(coo);
- free(numnoe);
- free(nufano);
-
- /****************************************************************************
- * ECRITURE DES ELEMENTS *
- ****************************************************************************/
- MESSAGE("(**************************)");
- MESSAGE("(* ELEMENTS DU MAILLAGE : *)");
- MESSAGE("(**************************)");
-
- /* Ecriture des connectivites, noms, numeros des mailles */
-
- if (ret == 0)
- {
- int nbFamillesElts = 0;
- SMESHDS_Mesh * mySMESHDSMesh = dynamic_cast<SMESHDS_Mesh *>(myMesh);
- map<int,int> mapFamille;
-
- if(!mySMESHDSMesh->ShapeToMesh().IsNull())
- {
- TopTools_IndexedMapOfShape myIndexToShape;
- TopExp::MapShapes(mySMESHDSMesh->ShapeToMesh(), myIndexToShape);
-
-
- if (besoinfamilledemaille == 1)
- {
- int t;
- for (t = 1; t <= myIndexToShape.Extent(); t++)
- {
- const TopoDS_Shape S = myIndexToShape(t);
- if (mySMESHDSMesh->HasMeshElements(S))
- {
- //MESSAGE ("********* Traitement de la Famille "<<-t);
-
- SMESHDS_SubMesh * SM = mySMESHDSMesh->MeshElements(S);
- SMDS_Iterator<const SMDS_MeshElement*> * ite=SM->GetElements();
- bool plein = false;
- while(ite->more())
- {
- mapFamille[ite->next()->GetID()] = -t;
- plein = true;
- }
- if (plein)
- {
- nbFamillesElts++;
- char famille[MED_TAILLE_NOM + 1];
- sprintf(famille, "E%d", t);
- CreateFamily(strdup(nommaa), strdup(famille), -t,
- attvalabs++);
- }
- }
- }
- }
- }
- else besoinfamilledemaille = 0;
-
- int indice = 1;
- for (i = 0; i < MED_NBR_GEOMETRIE_MAILLE; i++)
- {
- if (nmailles[i] > 0 && ret == 0)
- {
- MESSAGE(" Start " << typmai[i]);
-
- /* dimension de la maille */
- edim = typmai[i] / 100;
- nsup = 0;
- if (mdim == 2 || mdim == 3)
- if (edim == 1)
- nsup = 1;
- if (mdim == 3)
- if (edim == 2)
- nsup = 1;
- //SCRUTE(nsup);
-
- taille = nsup + typmai[i] % 100;
- //SCRUTE(taille);
-
- /* allocation memoire */
- connectivite =
- (med_int *) malloc(sizeof(med_int) * taille * nmailles[i]);
- /* nomele =
- (char *)malloc(sizeof(char) * MED_TAILLE_PNOM *
- nmailles[i] + 1);*/
- nomele = "";
- numele = (med_int *) malloc(sizeof(med_int) * nmailles[i]);
- nufael = (med_int *) malloc(sizeof(med_int) * nmailles[i]);
- nbNodes = typmai[i] % 100;
-
- for (j = 0; j < nmailles[i]; j++)
- {
- myId = elem_Id[i][j];
- const SMDS_MeshElement * elem =
- myMesh->FindElement(myId);
- //*(numele+j) = myId;
- *(numele + j) = indice++;
-
- SMDS_Iterator<const SMDS_MeshElement *> * itk=elem->nodesIterator();
- for (k = 0; itk->more(); k++)
- {
- *(connectivite + j * taille + k) =
- mapNoeud[itk->next()->GetID()];
- }
- delete itk;
-
- if (nsup)
- *(connectivite + j * taille + nbNodes) = 0;
-
- if (besoinfamilledemaille == 1)
- {
- if (mapFamille.find(myId) != mapFamille.end())
- {
- nufael[j] = mapFamille[myId];
- }
- else
- {
- nufael[j] = 0;
- }
- }
- else
- {
- nufael[j] = 0;
- }
-
- //SCRUTE(myId);
- //SCRUTE(j);
- //SCRUTE(nufael[j]);
- }
-
- /* ecriture des données */
-
- med_int *rien = 0;
- ret =
- MEDelementsEcr(myFileId, nommaa, mdim, connectivite,
- mode_coo, nomele, MED_FAUX, numele, MED_VRAI, nufael,
- nmailles[i], MED_MAILLE, typmai[i], typ_con, MED_REMP);
- ASSERT(ret == 0);
- //SCRUTE(ret);
-
- if (ret < 0)
- MESSAGE(">> ERREUR : ecriture des mailles \n");
-
- /* liberation memoire */
- free(connectivite);
- free(numele);
- free(nufael);
- MESSAGE(" End " << typmai[i]);
- }
- };
- MESSAGE("--- Creation de " << nbFamillesElts << " familles d elements");
+void DriverMED_W_SMESHDS_Mesh::AddAllSubMeshes()
+{
+ myAllSubMeshes = true;
+}
- }
+void DriverMED_W_SMESHDS_Mesh::AddSubMesh(SMESHDS_SubMesh* theSubMesh, int theID)
+{
+ mySubMeshes[theID] = theSubMesh;
+}
- /****************************************************************************
- * FERMETURE DU FICHIER *
- ****************************************************************************/
+void DriverMED_W_SMESHDS_Mesh::AddGroupOfNodes()
+{
+ myDoGroupOfNodes = true;
+}
- ret = MEDfermer(myFileId);
+void DriverMED_W_SMESHDS_Mesh::AddGroupOfEdges()
+{
+ myDoGroupOfEdges = true;
+}
- if (ret != 0)
- fprintf(stderr, ">> ERREUR : erreur a la fermeture du fichier %s\n",
- file2Read);
- MESSAGE("fichier ferme");
+void DriverMED_W_SMESHDS_Mesh::AddGroupOfFaces()
+{
+ myDoGroupOfFaces = true;
+}
+void DriverMED_W_SMESHDS_Mesh::AddGroupOfVolumes()
+{
+ myDoGroupOfVolumes = true;
}
-void DriverMED_W_SMESHDS_Mesh::CreateFamily(char *nommaa, char *famille, int i,
- med_int k)
+void DriverMED_W_SMESHDS_Mesh::Write()
{
+ string myClass = string("SMDS_Mesh");
+ string myExtension = string("MED");
- med_int ngro = 0;
- med_int natt;
+ DriverMED_W_SMDS_Mesh *myWriter = new DriverMED_W_SMDS_Mesh;
- natt = 1;
- char attdes[MED_TAILLE_DESC + 1];
- char gro[MED_TAILLE_LNOM + 1];
- char fam2[MED_TAILLE_LNOM + 1];
+ myWriter->SetMesh(myMesh);
+ // myWriter->SetFile(myFile);
+ myWriter->SetMeshId(myMeshId);
+ myWriter->SetFileId(myFileId);
- strcpy(attdes, "");
- strcpy(gro, "");
- strcpy(fam2, famille);
+ myWriter->Write();
+}
- med_int *attide = new med_int[1];
- med_int *attval = new med_int[1];
- attide[0] = k;
- attval[0] = k;
+void DriverMED_W_SMESHDS_Mesh::Add()
+{
+ if (myMesh->hasConstructionEdges() || myMesh->hasConstructionFaces()) {
+ INFOS("SMDS_MESH with hasConstructionEdges() or hasConstructionFaces() do not supports!!!");
+ return;
+ }
+ try{
+ using namespace MEDA;
+ using namespace boost;
+
+ MESSAGE("Add - myFile : "<<myFile);
+ TWrapper aMed(myFile);
+
+ // Creating the MED mesh for corresponding SMDS structure
+ //-------------------------------------------------------
+ string aMeshName;
+ if (myMeshId != -1) {
+ ostringstream aMeshNameStr;
+ aMeshNameStr<<myMeshId;
+ aMeshName = aMeshNameStr.str();
+ } else {
+ aMeshName = myMeshName;
+ }
+ const int SMDS_MESH_DIM = 3;
+ PMeshInfo aMeshInfo = TWrapper::CrMeshInfo(SMDS_MESH_DIM,aMeshName);
+ MESSAGE("Add - aMeshName : "<<aMeshName<<"; "<<aMeshInfo->GetName());
+ aMed.SetMeshInfo(aMeshInfo);
+
+ // Storing SMDS groups and sub-meshes
+ //-----------------------------------
+ int myNodesDefaultFamilyId = 0;
+ int myEdgesDefaultFamilyId = 0;
+ int myFacesDefaultFamilyId = 0;
+ int myVolumesDefaultFamilyId = 0;
+ if (myDoGroupOfNodes)
+ myNodesDefaultFamilyId = REST_NODES_FAMILY;
+ if (myDoGroupOfEdges)
+ myEdgesDefaultFamilyId = REST_EDGES_FAMILY;
+ if (myDoGroupOfFaces)
+ myFacesDefaultFamilyId = REST_FACES_FAMILY;
+ if (myDoGroupOfVolumes)
+ myVolumesDefaultFamilyId = REST_VOLUMES_FAMILY;
+
+ MESSAGE("Add - aFamilyInfo");
+ map<const SMDS_MeshElement *, int> anElemFamMap;
+ list<DriverMED_FamilyPtr> aFamilies;
+ if (myAllSubMeshes) {
+ SMESHDS_Mesh* aSMESHDSMesh = dynamic_cast<SMESHDS_Mesh*>(myMesh);
+ if (!aSMESHDSMesh) {
+ EXCEPTION(runtime_error,"Can not cast SMDS_Mesh to SMESHDS_Mesh");
+ }
+ aFamilies = DriverMED_Family::MakeFamilies
+ (aSMESHDSMesh->SubMeshes(), myGroups,
+ myDoGroupOfNodes, myDoGroupOfEdges, myDoGroupOfFaces, myDoGroupOfVolumes);
+ } else {
+ aFamilies = DriverMED_Family::MakeFamilies
+ (mySubMeshes, myGroups,
+ myDoGroupOfNodes, myDoGroupOfEdges, myDoGroupOfFaces, myDoGroupOfVolumes);
+ }
+ list<DriverMED_FamilyPtr>::iterator aFamsIter = aFamilies.begin();
+
+ for (; aFamsIter != aFamilies.end(); aFamsIter++)
+ {
+ PFamilyInfo aFamilyInfo = (*aFamsIter)->GetFamilyInfo(aMeshInfo);
+ aMed.SetFamilyInfo(aFamilyInfo);
+ int aFamId = (*aFamsIter)->GetId();
+
+ const set<const SMDS_MeshElement *>& anElems = (*aFamsIter)->GetElements();
+ set<const SMDS_MeshElement *>::iterator anElemsIter = anElems.begin();
+ for (; anElemsIter != anElems.end(); anElemsIter++)
+ {
+ anElemFamMap[*anElemsIter] = aFamId;
+ }
+// delete (*aFamsIter);
+ }
+
+ // Storing SMDS nodes to the MED file for the MED mesh
+ //----------------------------------------------------
+ typedef map<med_int,med_int> TNodeIdMap;
+ TNodeIdMap aNodeIdMap;
+
+ med_int aNbElems = myMesh->NbNodes();
+ MED::TIntVector anElemNums(aNbElems);
+ MED::TIntVector aFamilyNums(aNbElems);
+ MED::TFloatVector aCoordinates(aNbElems*SMDS_MESH_DIM);
+ SMDS_NodeIteratorPtr aNodesIter = myMesh->nodesIterator();
+ for(med_int iNode = 0, iCoord = 0; aNodesIter->more(); iNode++, iCoord+=SMDS_MESH_DIM){
+ const SMDS_MeshNode* aNode = aNodesIter->next();
+ aCoordinates[iCoord] = aNode->X();
+ aCoordinates[iCoord+1] = aNode->Y();
+ aCoordinates[iCoord+2] = aNode->Z();
+ TNodeIdMap::key_type aNodeId = aNode->GetID();
+ anElemNums[iNode] = aNodeId;
+ aNodeIdMap[aNodeId] = iNode+1;
+ //cout<<aNode->GetID()<<": "<<aNode->X()<<", "<<aNode->Y()<<", "<<aNode->Z()<<endl;
+
+ if (anElemFamMap.find(aNode) != anElemFamMap.end())
+ aFamilyNums[iNode] = anElemFamMap[aNode];
+ else
+ aFamilyNums[iNode] = myNodesDefaultFamilyId;
+ }
+
+ MED::TStringVector aCoordNames(3);
+ aCoordNames[0] = "x"; aCoordNames[1] = "y"; aCoordNames[2] = "z";
+
+ MED::TStringVector aCoordUnits(3);
+ aCoordUnits[0] = "m"; aCoordUnits[1] = "m"; aCoordUnits[2] = "m";
+
+ const med_repere SMDS_COORDINATE_SYSTEM = MED_CART;
+
+ PNodeInfo aNodeInfo = TWrapper::CrNodeInfo(aMeshInfo,
+ SMDS_COORDINATE_SYSTEM,
+ aCoordinates,
+ aCoordNames,
+ aCoordUnits,
+ aFamilyNums,
+ anElemNums);
+ MESSAGE("Add - aNodeInfo->GetNbElem() = "<<aNbElems);
+ aMed.SetNodeInfo(aNodeInfo);
+
+
+ // Storing others SMDS elements to the MED file for the MED mesh
+ //--------------------------------------------------------------
+ const med_entite_maillage SMDS_MED_ENTITY = MED_MAILLE;
+ const med_connectivite SMDS_MED_CONNECTIVITY = MED_NOD;
+
+ // Storing SMDS Edges
+ if(med_int aNbElems = myMesh->NbEdges()){
+ SMDS_EdgeIteratorPtr anIter = myMesh->edgesIterator();
+ med_int aNbConnectivity = MED::GetNbConn(SMDS_MED_ENTITY,MED_SEG2,SMDS_MESH_DIM);
+ MED::TIntVector anElemNums(aNbElems);
+ MED::TIntVector aFamilyNums(aNbElems);
+ MED::TIntVector aConnectivity(aNbElems*aNbConnectivity);
+
+ for(med_int iElem = 0, iConn = 0; anIter->more(); iElem++, iConn+=aNbConnectivity){
+ const SMDS_MeshEdge* anElem = anIter->next();
+ SMDS_ElemIteratorPtr aNodesIter = anElem->nodesIterator();
+ for(med_int iNode = 0; iNode < aNbConnectivity && aNodesIter->more(); iNode++){
+ const SMDS_MeshElement* aNode = aNodesIter->next();
+ aConnectivity[iConn+iNode] = aNodeIdMap[aNode->GetID()];
+ }
+ anElemNums[iElem] = anElem->GetID();
+
+ if (anElemFamMap.find(anElem) != anElemFamMap.end())
+ aFamilyNums[iElem] = anElemFamMap[anElem];
+ else
+ aFamilyNums[iElem] = myEdgesDefaultFamilyId;
+ }
+
+ PCellInfo aCellInfo = TWrapper::CrCellInfo(aMeshInfo,
+ SMDS_MED_ENTITY,
+ MED_SEG2,
+ SMDS_MED_CONNECTIVITY,
+ aConnectivity,
+ aFamilyNums,
+ anElemNums);
+ aMed.SetCellInfo(aCellInfo);
+ }
+
+ // Storing SMDS Faces
+ if(med_int aNbElems = myMesh->NbFaces()){
+ SMDS_FaceIteratorPtr anIter = myMesh->facesIterator();
+
+ med_int aNbTriaConn = MED::GetNbConn(SMDS_MED_ENTITY,MED_TRIA3,SMDS_MESH_DIM);
+ MED::TIntVector anTriaElemNums;
+ anTriaElemNums.reserve(aNbElems);
+ MED::TIntVector aTriaFamilyNums;
+ aTriaFamilyNums.reserve(aNbElems);
+ MED::TIntVector aTriaConn;
+ aTriaConn.reserve(aNbElems*aNbTriaConn);
+
+ med_int aNbQuadConn = MED::GetNbConn(SMDS_MED_ENTITY,MED_QUAD4,SMDS_MESH_DIM);
+ MED::TIntVector aQuadElemNums;
+ aQuadElemNums.reserve(aNbElems);
+ MED::TIntVector aQuadFamilyNums;
+ aQuadFamilyNums.reserve(aNbElems);
+ MED::TIntVector aQuadConn;
+ aQuadConn.reserve(aNbElems*aNbQuadConn);
+
+ for(med_int iElem = 0; iElem < aNbElems && anIter->more(); iElem++){
+ const SMDS_MeshFace* anElem = anIter->next();
+ med_int aNbNodes = anElem->NbNodes();
+ SMDS_ElemIteratorPtr aNodesIter = anElem->nodesIterator();
+ med_int aNbConnectivity;
+ MED::TIntVector* anElemNums;
+ MED::TIntVector* aFamilyNums;
+ MED::TIntVector* aConnectivity;
+ switch(aNbNodes){
+ case 3:
+ aNbConnectivity = aNbTriaConn;
+ anElemNums = &anTriaElemNums;
+ aFamilyNums = &aTriaFamilyNums;
+ aConnectivity = &aTriaConn;
+ break;
+ case 4:
+ aNbConnectivity = aNbQuadConn;
+ anElemNums = &aQuadElemNums;
+ aFamilyNums = &aQuadFamilyNums;
+ aConnectivity = &aQuadConn;
+ break;
+ }
+ MED::TIntVector aVector(aNbNodes);
+ for(med_int iNode = 0; aNodesIter->more(); iNode++){
+ const SMDS_MeshElement* aNode = aNodesIter->next();
+ aVector[iNode] = aNode->GetID();
+ }
- //MESSAGE("-------- Creation de la Famille : "<< famille << "numero " << i << " --------------");
- med_int ret =
- MEDfamCr(myFileId, nommaa, fam2, i, attide, attval, attdes, natt, gro,
- ngro);
- ASSERT(ret == 0);
- delete[]attide;
- delete[]attval;
+ med_int aSize = aConnectivity->size();
+ aConnectivity->resize(aSize+aNbConnectivity);
+ // There is some differnce between SMDS and MED in cells mapping
+ switch(aNbNodes){
+ case 4:
+ (*aConnectivity)[aSize+0] = aNodeIdMap[aVector[0]];
+ (*aConnectivity)[aSize+1] = aNodeIdMap[aVector[1]];
+ (*aConnectivity)[aSize+2] = aNodeIdMap[aVector[3]];
+ (*aConnectivity)[aSize+3] = aNodeIdMap[aVector[2]];
+ default:
+ for(med_int iNode = 0; iNode < aNbNodes; iNode++)
+ (*aConnectivity)[aSize+iNode] = aNodeIdMap[aVector[iNode]];
+ }
+ anElemNums->push_back(anElem->GetID());
+
+ if (anElemFamMap.find(anElem) != anElemFamMap.end())
+ aFamilyNums->push_back(anElemFamMap[anElem]);
+ else
+ aFamilyNums->push_back(myFacesDefaultFamilyId);
+ }
+ if(med_int aNbElems = anTriaElemNums.size()){
+ PCellInfo aCellInfo = TWrapper::CrCellInfo(aMeshInfo,
+ SMDS_MED_ENTITY,
+ MED_TRIA3,
+ SMDS_MED_CONNECTIVITY,
+ aTriaConn,
+ aTriaFamilyNums,
+ anTriaElemNums);
+ MESSAGE("Add - anEntity = "<<SMDS_MED_ENTITY<<"; aGeom = "<<MED_TRIA3<<"; aNbElems = "<<aNbElems);
+ aMed.SetCellInfo(aCellInfo);
+ }
+ if(med_int aNbElems = aQuadElemNums.size()){
+ PCellInfo aCellInfo = TWrapper::CrCellInfo(aMeshInfo,
+ SMDS_MED_ENTITY,
+ MED_QUAD4,
+ SMDS_MED_CONNECTIVITY,
+ aQuadConn,
+ aQuadFamilyNums,
+ aQuadElemNums);
+ MESSAGE("Add - anEntity = "<<SMDS_MED_ENTITY<<"; aGeom = "<<MED_QUAD4<<"; aNbElems = "<<aNbElems);
+ aMed.SetCellInfo(aCellInfo);
+ }
+ }
+
+ // Storing SMDS Volumes
+ if(med_int aNbElems = myMesh->NbVolumes()){
+ SMDS_VolumeIteratorPtr anIter = myMesh->volumesIterator();
+
+ med_int aNbTetraConn = MED::GetNbConn(SMDS_MED_ENTITY,MED_TETRA4,SMDS_MESH_DIM);
+ MED::TIntVector anTetraElemNums;
+ anTetraElemNums.reserve(aNbElems);
+ MED::TIntVector aTetraFamilyNums;
+ aTetraFamilyNums.reserve(aNbElems);
+ MED::TIntVector aTetraConn;
+ aTetraConn.reserve(aNbElems*aNbTetraConn);
+
+ med_int aNbPyraConn = MED::GetNbConn(SMDS_MED_ENTITY,MED_PYRA5,SMDS_MESH_DIM);
+ MED::TIntVector anPyraElemNums;
+ anPyraElemNums.reserve(aNbElems);
+ MED::TIntVector aPyraFamilyNums;
+ aPyraFamilyNums.reserve(aNbElems);
+ MED::TIntVector aPyraConn;
+ aPyraConn.reserve(aNbElems*aNbPyraConn);
+
+ med_int aNbPentaConn = MED::GetNbConn(SMDS_MED_ENTITY,MED_PENTA6,SMDS_MESH_DIM);
+ MED::TIntVector anPentaElemNums;
+ anPentaElemNums.reserve(aNbElems);
+ MED::TIntVector aPentaFamilyNums;
+ aPentaFamilyNums.reserve(aNbElems);
+ MED::TIntVector aPentaConn;
+ aPentaConn.reserve(aNbElems*aNbPentaConn);
+
+ med_int aNbHexaConn = MED::GetNbConn(SMDS_MED_ENTITY,MED_HEXA8,SMDS_MESH_DIM);
+ MED::TIntVector aHexaElemNums;
+ aHexaElemNums.reserve(aNbElems);
+ MED::TIntVector aHexaFamilyNums;
+ aHexaFamilyNums.reserve(aNbElems);
+ MED::TIntVector aHexaConn;
+ aHexaConn.reserve(aNbElems*aNbHexaConn);
+
+ for(med_int iElem = 0; iElem < aNbElems && anIter->more(); iElem++){
+ const SMDS_MeshVolume* anElem = anIter->next();
+ med_int aNbNodes = anElem->NbNodes();
+ SMDS_ElemIteratorPtr aNodesIter = anElem->nodesIterator();
+ med_int aNbConnectivity;
+ MED::TIntVector* anElemNums;
+ MED::TIntVector* aFamilyNums;
+ MED::TIntVector* aConnectivity;
+ switch(aNbNodes){
+ case 4:
+ aNbConnectivity = aNbTetraConn;
+ anElemNums = &anTetraElemNums;
+ aFamilyNums = &aTetraFamilyNums;
+ aConnectivity = &aTetraConn;
+ break;
+ case 5:
+ aNbConnectivity = aNbPyraConn;
+ anElemNums = &anPyraElemNums;
+ aFamilyNums = &aPyraFamilyNums;
+ aConnectivity = &aPyraConn;
+ break;
+ case 6:
+ aNbConnectivity = aNbPentaConn;
+ anElemNums = &anPentaElemNums;
+ aFamilyNums = &aPentaFamilyNums;
+ aConnectivity = &aPentaConn;
+ break;
+ case 8:
+ aNbConnectivity = aNbHexaConn;
+ anElemNums = &aHexaElemNums;
+ aFamilyNums = &aHexaFamilyNums;
+ aConnectivity = &aHexaConn;
+ }
+ MED::TIntVector aVector(aNbNodes);
+ for(med_int iNode = 0; aNodesIter->more(); iNode++){
+ const SMDS_MeshElement* aNode = aNodesIter->next();
+ aVector[iNode] = aNode->GetID();
+ }
+ med_int aSize = aConnectivity->size();
+ aConnectivity->resize(aSize+aNbConnectivity);
+ // There is some difference between SMDS and MED in cells mapping
+ switch(aNbNodes){
+ case 5:
+ (*aConnectivity)[aSize+0] = aNodeIdMap[aVector[0]];
+ (*aConnectivity)[aSize+1] = aNodeIdMap[aVector[3]];
+ (*aConnectivity)[aSize+2] = aNodeIdMap[aVector[2]];
+ (*aConnectivity)[aSize+3] = aNodeIdMap[aVector[1]];
+ (*aConnectivity)[aSize+4] = aNodeIdMap[aVector[4]];
+ default:
+ for(med_int iNode = 0; iNode < aNbNodes; iNode++)
+ (*aConnectivity)[aSize+iNode] = aNodeIdMap[aVector[iNode]];
+ }
+ anElemNums->push_back(anElem->GetID());
+
+ if (anElemFamMap.find(anElem) != anElemFamMap.end())
+ aFamilyNums->push_back(anElemFamMap[anElem]);
+ else
+ aFamilyNums->push_back(myVolumesDefaultFamilyId);
+ }
+
+ if(med_int aNbElems = anTetraElemNums.size()){
+ PCellInfo aCellInfo = TWrapper::CrCellInfo(aMeshInfo,
+ SMDS_MED_ENTITY,
+ MED_TETRA4,
+ SMDS_MED_CONNECTIVITY,
+ aTetraConn,
+ aTetraFamilyNums,
+ anTetraElemNums);
+ MESSAGE("Add - anEntity = "<<SMDS_MED_ENTITY<<"; aGeom = "<<MED_TETRA4<<"; aNbElems = "<<aNbElems);
+ aMed.SetCellInfo(aCellInfo);
+ }
+ if(med_int aNbElems = anPyraElemNums.size()){
+ PCellInfo aCellInfo = TWrapper::CrCellInfo(aMeshInfo,
+ SMDS_MED_ENTITY,
+ MED_PYRA5,
+ SMDS_MED_CONNECTIVITY,
+ aPyraConn,
+ aPyraFamilyNums,
+ anPyraElemNums);
+ MESSAGE("Add - anEntity = "<<SMDS_MED_ENTITY<<"; aGeom = "<<MED_PYRA5<<"; aNbElems = "<<aNbElems);
+ aMed.SetCellInfo(aCellInfo);
+ }
+ if(med_int aNbElems = anPentaElemNums.size()){
+ PCellInfo aCellInfo = TWrapper::CrCellInfo(aMeshInfo,
+ SMDS_MED_ENTITY,
+ MED_PENTA6,
+ SMDS_MED_CONNECTIVITY,
+ aPentaConn,
+ aPentaFamilyNums,
+ anPentaElemNums);
+ MESSAGE("Add - anEntity = "<<SMDS_MED_ENTITY<<"; aGeom = "<<MED_PENTA6<<"; aNbElems = "<<aNbElems);
+ aMed.SetCellInfo(aCellInfo);
+ }
+ if(med_int aNbElems = aHexaElemNums.size()){
+ PCellInfo aCellInfo = TWrapper::CrCellInfo(aMeshInfo,
+ SMDS_MED_ENTITY,
+ MED_HEXA8,
+ SMDS_MED_CONNECTIVITY,
+ aHexaConn,
+ aHexaFamilyNums,
+ aHexaElemNums);
+ MESSAGE("Add - anEntity = "<<SMDS_MED_ENTITY<<"; aGeom = "<<MED_HEXA8<<"; aNbElems = "<<aNbElems);
+ aMed.SetCellInfo(aCellInfo);
+ }
+ }
+ }catch(const std::exception& exc){
+ INFOS("Follow exception was cought:\n\t"<<exc.what());
+ }catch(...){
+ INFOS("Unknown exception was cought !!!");
+ }
+
+ myMeshId = -1;
+ myGroups.clear();
+ mySubMeshes.clear();
}
#include "Mesh_Writer.h"
#include <string>
+#include <list>
+#include <map>
extern "C"
{
#include <med.h>
}
+using namespace std;
+
+class SMESHDS_Group;
+class SMESHDS_SubMesh;
+
class DriverMED_W_SMESHDS_Mesh:public Mesh_Writer
{
+ public:
- public:DriverMED_W_SMESHDS_Mesh();
- ~DriverMED_W_SMESHDS_Mesh();
+ DriverMED_W_SMESHDS_Mesh();
+ ~DriverMED_W_SMESHDS_Mesh();
- void Add();
- void Write();
- void SetMesh(SMDS_Mesh * aMesh);
- void SetFile(string);
+ /*! sets file name; only for usage with Add(), not Write()
+ */
+ void SetFile(string);
+ void AddGroupOfNodes();
+ void AddGroupOfEdges();
+ void AddGroupOfFaces();
+ void AddGroupOfVolumes();
- void SetFileId(med_idt);
- void SetMeshId(int);
+ /*! functions to prepare adding one mesh
+ */
+ void SetMesh(SMDS_Mesh * aMesh);
+ void SetMeshId(int);
+ void SetMeshName(string theMeshName);
+ void AddGroup(SMESHDS_Group* theGroup);
+ void AddAllSubMeshes();
+ void AddSubMesh(SMESHDS_SubMesh* theSubMesh, int theID);
- void CreateFamily(char *, char *, int, med_int);
+ /*! add one mesh
+ */
+ void Add();
- private: SMDS_Mesh * myMesh;
- string myFile;
- med_idt myFileId;
- int myMeshId;
+ /*! functions to write via DriverMED_W_SMDS_Mesh (no groups)
+ */
+ void SetFileId(med_idt);
+ void Write();
+ private:
+
+ SMDS_Mesh * myMesh;
+ string myFile;
+ med_idt myFileId;
+ int myMeshId;
+ string myMeshName;
+ list<SMESHDS_Group*> myGroups;
+ bool myAllSubMeshes;
+ map<int,SMESHDS_SubMesh*> mySubMeshes;
+ bool myDoGroupOfNodes;
+ bool myDoGroupOfEdges;
+ bool myDoGroupOfFaces;
+ bool myDoGroupOfVolumes;
};
#endif
+
--- /dev/null
+// Copyright (C) 2003 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
+// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
+//
+// This library 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.
+//
+// This library 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 this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+//
+// See http://www.opencascade.org/SALOME/ or email : webmaster.salome@opencascade.org
+
+#include "DriverMED_R_SMESHDS_Mesh.h"
+#include "DriverMED_W_SMESHDS_Mesh.h"
+
+int main(int argc, char** argv)
+{
+ DriverMED_R_SMESHDS_Mesh aR;
+ DriverMED_W_SMESHDS_Mesh aW;
+ return 1;
+}
#
# See http://www.opencascade.org/SALOME/ or email : webmaster.salome@opencascade.org
#
+#
+#
# File : Makefile.in
# Author : Marc Tajchman (CEA)
# Module : SMESH
+# $Header$
top_srcdir=@top_srcdir@
top_builddir=../..
# header files
EXPORT_HEADERS = \
- DriverMED_R_SMESHDS_Mesh.h \
- DriverMED_R_SMESHDS_Document.h \
- DriverMED_R_SMDS_Mesh.h \
- DriverMED_W_SMESHDS_Mesh.h
- #DriverMED_W_SMDS_Mesh.h \
- #DriverMED_W_SMESHDS_Document.h
+ DriverMED_R_SMDS_Mesh.h DriverMED_R_SMESHDS_Mesh.h DriverMED_R_SMESHDS_Document.h \
+ DriverMED_W_SMDS_Mesh.h DriverMED_W_SMESHDS_Mesh.h DriverMED_W_SMESHDS_Document.h \
+ DriverMED_Family.h
# Libraries targets
LIB = libMeshDriverMED.la
LIB_SRC = \
+ DriverMED_R_SMDS_Mesh.cxx \
DriverMED_R_SMESHDS_Mesh.cxx \
DriverMED_R_SMESHDS_Document.cxx \
- DriverMED_R_SMDS_Mesh.cxx \
- DriverMED_W_SMESHDS_Mesh.cxx
- #DriverMED_W_SMDS_Mesh.cxx \
- #DriverMED_W_SMESHDS_Document.cxx
+ DriverMED_W_SMDS_Mesh.cxx \
+ DriverMED_W_SMESHDS_Document.cxx \
+ DriverMED_W_SMESHDS_Mesh.cxx \
+ DriverMED_Family.cxx
+
LIB_CLIENT_IDL =
LIB_SERVER_IDL =
# additionnal information to compil and link file
-CPPFLAGS += $(OCC_INCLUDES) $(QT_INCLUDES) -I${KERNEL_ROOT_DIR}/include/salome
+CPPFLAGS += $(OCC_INCLUDES) $(QT_INCLUDES) -I${KERNEL_ROOT_DIR}/include/salome $(BOOST_CPPFLAGS)
CXXFLAGS += $(OCC_CXXFLAGS) $(MED2_INCLUDES) -I${KERNEL_ROOT_DIR}/include/salome
-LDFLAGS += $(MED2_LIBS) -lMeshDriver -lmed
+LDFLAGS += $(MED2_LIBS) -lMeshDriver -L${KERNEL_ROOT_DIR}/lib/salome -lMEDWrapper
%_moc.cxx: %.h
$(MOC) $< -o $@
#include "utilities.h"
-
-extern "C"
-{
-
-/**
- * Factory function which will be called by SMESHDriver
- */
-void * SMESH_createUNVMeshReader()
-{
- return new DriverUNV_R_SMDS_Mesh();
-}
-
-}
-
DriverUNV_R_SMDS_Mesh::DriverUNV_R_SMDS_Mesh()
{
;
+using namespace std;
#include "DriverUNV_W_SMDS_Mesh.h"
+
#include "SMDS_MeshElement.hxx"
#include "SMDS_MeshNode.hxx"
+
+
+
+
#include <utilities.h>
#define sNODE_UNV_ID " 2411"
#define sELT_BEAM_DESC1 "%10d %2d 1 1 7 %1d\n"
#define sELT_BEAM_DESC2 " 0 1 1\n"
-extern "C"
-{
-
-/**
- * Factory function which will be called by SMESHDriver
- */
-void * SMESH_createUNVMeshWriter()
-{
- return new DriverUNV_W_SMDS_Mesh();
-}
-
-}
-
DriverUNV_W_SMDS_Mesh::DriverUNV_W_SMDS_Mesh()
{
;
SCRUTE(nb_of_volumes);
fprintf(stdout, "%d %d\n", nbNodes, nbCells);
+ fprintf(myFileId, "%d %d\n", nbNodes, nbCells);
/****************************************************************************
* ECRITURE DES NOEUDS *
fprintf(myFileId, "%s\n", sUNV_SEPARATOR);
fprintf(myFileId, "%s\n", sNODE_UNV_ID);
- SMDS_Iterator<const SMDS_MeshNode *> * itNodes=myMesh->nodesIterator();
+ SMDS_NodeIteratorPtr itNodes=myMesh->nodesIterator();
while(itNodes->more())
{
const SMDS_MeshNode * node = itNodes->next();
fprintf(myFileId, "%25.16E%25.16E%25.16E\n", node->X(), node->Y(),
node->Z());
}
- delete itNodes;
fprintf(myFileId, "%s\n", sUNV_SEPARATOR);
/****************************************************************************
fprintf(myFileId, "%s\n", sUNV_SEPARATOR);
fprintf(myFileId, "%s\n", sELT_UNV_ID);
- SMDS_Iterator<const SMDS_MeshEdge *> * itEdges=myMesh->edgesIterator();
+ SMDS_EdgeIteratorPtr itEdges=myMesh->edgesIterator();
while(itEdges->more())
{
const SMDS_MeshElement * elem = itEdges->next();
- SMDS_Iterator<const SMDS_MeshElement*> *itn=elem->nodesIterator();
+ SMDS_ElemIteratorPtr itn=elem->nodesIterator();
switch (elem->NbNodes())
{
break;
}
- delete itn;
}
- delete itEdges;
- SMDS_Iterator<const SMDS_MeshFace*> * itFaces=myMesh->facesIterator();
+ SMDS_FaceIteratorPtr itFaces=myMesh->facesIterator();
while(itFaces->more())
{
const SMDS_MeshElement * elem = itFaces->next();
fprintf(myFileId, "element not registered\n");
}
- SMDS_Iterator<const SMDS_MeshElement*> *itn=elem->nodesIterator();
+ SMDS_ElemIteratorPtr itn=elem->nodesIterator();
while(itn->more()) fprintf(myFileId, "%10d", itn->next()->GetID());
- delete itn;
fprintf(myFileId, "\n");
}
- delete itFaces;
- SMDS_Iterator<const SMDS_MeshVolume*> * itVolumes=myMesh->volumesIterator();
+ SMDS_VolumeIteratorPtr itVolumes=myMesh->volumesIterator();
while(itVolumes->more())
{
const SMDS_MeshElement * elem = itVolumes->next();
break;
}
- SMDS_Iterator<const SMDS_MeshElement*> *itn=elem->nodesIterator();
+ SMDS_ElemIteratorPtr itn=elem->nodesIterator();
while(itn->more()) fprintf(myFileId, "%10d", itn->next()->GetID());
- delete itn;
fprintf(myFileId, "\n");
}
- delete itVolumes;
fprintf(myFileId, "%s\n", sUNV_SEPARATOR);
fprintf(myFileId, "%s\n", sUNV_SEPARATOR);
fprintf(myFileId, "%s\n", sNODE_UNV_ID);
- SMDS_Iterator<const SMDS_MeshNode *> * itNodes=myMesh->nodesIterator();
+ SMDS_NodeIteratorPtr itNodes=myMesh->nodesIterator();
while(itNodes->more())
{
const SMDS_MeshNode * node = itNodes->next();
fprintf(myFileId, "%25.16E%25.16E%25.16E\n", node->X(), node->Y(),
node->Z());
}
- delete itNodes;
fprintf(myFileId, "%s\n", sUNV_SEPARATOR);
/****************************************************************************
fprintf(myFileId, "%s\n", sUNV_SEPARATOR);
fprintf(myFileId, "%s\n", sELT_UNV_ID);
- SMDS_Iterator<const SMDS_MeshEdge *> * itEdges=myMesh->edgesIterator();
+ SMDS_EdgeIteratorPtr itEdges=myMesh->edgesIterator();
while(itEdges->more())
{
const SMDS_MeshEdge * elem = itEdges->next();
- SMDS_Iterator<const SMDS_MeshElement*> *itn=elem->nodesIterator();
+ SMDS_ElemIteratorPtr itn=elem->nodesIterator();
switch (elem->NbNodes())
{
itn->next()->GetID(), itn->next()->GetID());
break;
}
- delete itn;
}
- delete itEdges;
- SMDS_Iterator<const SMDS_MeshFace*> * itFaces=myMesh->facesIterator();
+ SMDS_FaceIteratorPtr itFaces=myMesh->facesIterator();
while(itFaces->more())
{
const SMDS_MeshElement * elem = itFaces->next();
fprintf(myFileId, "element not registered\n");
}
- SMDS_Iterator<const SMDS_MeshElement*> *itn=elem->nodesIterator();
+ SMDS_ElemIteratorPtr itn=elem->nodesIterator();
while(itn->more()) fprintf(myFileId, "%10d", itn->next()->GetID());
- delete itn;
fprintf(myFileId, "\n");
}
- delete itFaces;
- SMDS_Iterator<const SMDS_MeshVolume*> * itVolumes=myMesh->volumesIterator();
+ SMDS_VolumeIteratorPtr itVolumes=myMesh->volumesIterator();
while(itVolumes->more())
{
const SMDS_MeshElement * elem = itVolumes->next();
break;
}
- SMDS_Iterator<const SMDS_MeshElement*> *itn=elem->nodesIterator();
+ SMDS_ElemIteratorPtr itn=elem->nodesIterator();
while(itn->more()) fprintf(myFileId, "%10d", itn->next()->GetID());
- delete itn;
fprintf(myFileId, "\n");
}
- delete itVolumes;
fprintf(myFileId, "%s\n", sUNV_SEPARATOR);
fclose(myFileId);
@COMMENCE@
# header files
-EXPORT_HEADERS = \
- DriverUNV_R_SMDS_Mesh.h \
- DriverUNV_W_SMDS_Mesh.h
- #DriverUNV_W_SMESHDS_Mesh.h \
- #DriverUNV_W_SMESHDS_Document.h \
- #DriverUNV_R_SMESHDS_Mesh.h \
- #DriverUNV_R_SMESHDS_Document.h \
+EXPORT_HEADERS= DriverUNV_R_SMDS_Mesh.h DriverUNV_R_SMESHDS_Mesh.h DriverUNV_R_SMESHDS_Document.h \
+ DriverUNV_W_SMDS_Mesh.h DriverUNV_W_SMESHDS_Mesh.h DriverUNV_W_SMESHDS_Document.h
# Libraries targets
LIB = libMeshDriverUNV.la
LIB_SRC = \
DriverUNV_R_SMDS_Mesh.cxx \
- DriverUNV_W_SMDS_Mesh.cxx
- #DriverUNV_W_SMESHDS_Mesh.cxx \
- #DriverUNV_R_SMESHDS_Mesh.cxx \
- #DriverUNV_R_SMESHDS_Document.cxx \
- #DriverUNV_W_SMESHDS_Document.cxx \
+ DriverUNV_R_SMESHDS_Mesh.cxx \
+ DriverUNV_R_SMESHDS_Document.cxx \
+ DriverUNV_W_SMESHDS_Document.cxx \
+ DriverUNV_W_SMDS_Mesh.cxx \
+ DriverUNV_W_SMESHDS_Mesh.cxx
LIB_CLIENT_IDL =
LIB_SERVER_IDL =
# additionnal information to compil and link file
-CPPFLAGS += $(OCC_INCLUDES) -I${KERNEL_ROOT_DIR}/include/salome
+CPPFLAGS += $(OCC_INCLUDES) -I${KERNEL_ROOT_DIR}/include/salome $(BOOST_CPPFLAGS)
CXXFLAGS += $(OCC_CXXFLAGS) $(MED2_INCLUDES) -I${KERNEL_ROOT_DIR}/include/salome
LDFLAGS += $(MED2_LIBS) -lMeshDriver
--- /dev/null
+// Copyright (C) 2003 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
+// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
+//
+// This library 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.
+//
+// This library 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 this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+//
+// See http://www.opencascade.org/SALOME/ or email : webmaster.salome@opencascade.org
+
+#include <fstream>
+
+#include "UNV2411_Structure.hxx"
+#include "UNV_Utilities.hxx"
+
+using namespace std;
+using namespace UNV;
+using namespace UNV2411;
+
+#ifdef _DEBUG_
+static int MYDEBUG = 1;
+#else
+static int MYDEBUG = 0;
+#endif
+
+static string _label_dataset = "2411";
+
+UNV2411::TRecord::TRecord():
+ exp_coord_sys_num(0),
+ disp_coord_sys_num(0),
+ color(0)
+{}
+
+void UNV2411::Read(std::ifstream& in_stream, TDataSet& theDataSet)
+{
+ if(!in_stream.good())
+ EXCEPTION(runtime_error,"ERROR: Input file not good.");
+
+ /*
+ * adjust the \p istream to our
+ * position
+ */
+ if(!beginning_of_dataset(in_stream,_label_dataset))
+ EXCEPTION(runtime_error,"ERROR: Could not find "<<_label_dataset<<" dataset!");
+
+ /**
+ * always 3 coordinates in the UNV file, no matter
+ * which dimensionality libMesh is in
+ */
+ TNodeLab aLabel;
+ std::string num_buf;
+ for(; !in_stream.eof();){
+ in_stream >> aLabel ;
+ if(aLabel == -1){
+ // end of dataset is reached
+ break;
+ }
+
+ TRecord aRec;
+ in_stream>>aRec.exp_coord_sys_num;
+ in_stream>>aRec.disp_coord_sys_num;
+ in_stream>>aRec.color;
+
+ /*
+ * take care of the
+ * floating-point data
+ */
+ for(int d = 0; d < 3; d++){
+ in_stream>>num_buf;
+ aRec.coord[d] = D_to_e(num_buf);
+ }
+
+ theDataSet.insert(TDataSet::value_type(aLabel,aRec));
+ }
+}
+
+
+void UNV2411::Write(std::ofstream& out_stream, const TDataSet& theDataSet)
+{
+ if(!out_stream.good())
+ EXCEPTION(runtime_error,"ERROR: Output file not good.");
+
+ /*
+ * Write beginning of dataset
+ */
+ out_stream<<" -1\n";
+ out_stream<<" "<<_label_dataset<<"\n";
+
+ TDataSet::const_iterator anIter = theDataSet.begin();
+ for(; anIter != theDataSet.end(); anIter++){
+ const TNodeLab& aLabel = anIter->first;
+ const TRecord& aRec = anIter->second;
+ char buf[78];
+ sprintf(buf, "%10d%10d%10d%10d\n",
+ aLabel,
+ aRec.exp_coord_sys_num,
+ aRec.disp_coord_sys_num,
+ aRec.color);
+ out_stream<<buf;
+
+ // the coordinates
+ sprintf(buf, "%25.16E%25.16E%25.16E\n",
+ aRec.coord[0],
+ aRec.coord[1],
+ aRec.coord[2]);
+ out_stream<<buf;
+ }
+
+
+ /*
+ * Write end of dataset
+ */
+ out_stream<<" -1\n";
+}
--- /dev/null
+// Copyright (C) 2003 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
+// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
+//
+// This library 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.
+//
+// This library 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 this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+//
+// See http://www.opencascade.org/SALOME/ or email : webmaster.salome@opencascade.org
+
+#ifndef UNV2411_Structure_HeaderFile
+#define UNV2411_Structure_HeaderFile
+
+#include <map>
+#include <fstream>
+
+namespace UNV2411{
+
+ struct TRecord{
+ TRecord();
+ int exp_coord_sys_num; // export coordinate system number
+ int disp_coord_sys_num; // displacement coordinate system number
+ int color; // color
+ double coord[3]; // node coordinates in the part coordinate system
+ };
+
+ typedef int TNodeLab; // type of node label
+ typedef std::map<TNodeLab,TRecord> TDataSet;
+
+ void Read(std::ifstream& in_stream, TDataSet& theDataSet);
+
+ void Write(std::ofstream& out_stream, const TDataSet& theDataSet);
+
+};
+
+
+#endif
--- /dev/null
+// Copyright (C) 2003 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
+// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
+//
+// This library 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.
+//
+// This library 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 this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+//
+// See http://www.opencascade.org/SALOME/ or email : webmaster.salome@opencascade.org
+
+#include <fstream>
+#include <iomanip>
+
+#include "UNV2412_Structure.hxx"
+#include "UNV_Utilities.hxx"
+
+using namespace std;
+using namespace UNV;
+using namespace UNV2412;
+
+#ifdef _DEBUG_
+static int MYDEBUG = 1;
+#else
+static int MYDEBUG = 0;
+#endif
+
+static string _label_dataset = "2412";
+
+UNV2412::TRecord::TRecord():
+ phys_prop_tab_num(2),
+ mat_prop_tab_num(1),
+ color(7),
+ beam_orientation(0),
+ beam_fore_end(0),
+ beam_aft_end(0)
+{}
+
+void UNV2412::Read(std::ifstream& in_stream, TDataSet& theDataSet)
+{
+ if(!in_stream.good())
+ EXCEPTION(runtime_error,"ERROR: Input file not good.");
+
+ /*
+ * adjust the \p istream to our
+ * position
+ */
+ if(!beginning_of_dataset(in_stream,_label_dataset))
+ EXCEPTION(runtime_error,"ERROR: Could not find "<<_label_dataset<<" dataset!");
+
+ TElementLab aLabel;
+ for(; !in_stream.eof();){
+ in_stream >> aLabel ;
+ if(aLabel == -1){
+ // end of dataset is reached
+ break;
+ }
+
+ int n_nodes;
+ TRecord aRec;
+ in_stream>>aRec.fe_descriptor_id;
+ in_stream>>aRec.phys_prop_tab_num;
+ in_stream>>aRec.mat_prop_tab_num;
+ in_stream>>aRec.color;
+ in_stream>>n_nodes;
+
+ if(IsBeam(aRec.fe_descriptor_id)){
+ in_stream>>aRec.beam_orientation;
+ in_stream>>aRec.beam_fore_end;
+ in_stream>>aRec.beam_aft_end;
+ }
+
+ aRec.node_labels.resize(n_nodes);
+ for(int j=0; j < n_nodes; j++){
+ // read node labels
+ in_stream>>aRec.node_labels[j];
+ }
+
+ theDataSet.insert(TDataSet::value_type(aLabel,aRec));
+ }
+
+}
+
+
+void UNV2412::Write(std::ofstream& out_stream, const TDataSet& theDataSet)
+{
+ if(!out_stream.good())
+ EXCEPTION(runtime_error,"ERROR: Output file not good.");
+
+ /*
+ * Write beginning of dataset
+ */
+ out_stream<<" -1\n";
+ out_stream<<" "<<_label_dataset<<"\n";
+
+ TDataSet::const_iterator anIter = theDataSet.begin();
+ for(; anIter != theDataSet.end(); anIter++){
+ const TElementLab& aLabel = anIter->first;
+ const TRecord& aRec = anIter->second;
+ out_stream<<std::setw(10)<<aLabel; /* element ID */
+ out_stream<<std::setw(10)<<aRec.fe_descriptor_id; /* type of element */
+ out_stream<<std::setw(10)<<aRec.phys_prop_tab_num;
+ out_stream<<std::setw(10)<<aRec.mat_prop_tab_num;
+ out_stream<<std::setw(10)<<aRec.color;
+ out_stream<<std::setw(10)<<aRec.node_labels.size()<<std::endl; /* No. of nodes per element */
+
+ if(IsBeam(aRec.fe_descriptor_id)){
+ out_stream<<std::setw(10)<<aRec.beam_orientation;
+ out_stream<<std::setw(10)<<aRec.beam_fore_end;
+ out_stream<<std::setw(10)<<aRec.beam_aft_end<<std::endl;
+ }
+
+ int n_nodes = aRec.node_labels.size();
+ int iEnd = (n_nodes-1)/8 + 1;
+ for(int i = 0, k = 0; i < iEnd; i++){
+ int jEnd = n_nodes - 8*(i+1);
+ if(jEnd < 0)
+ jEnd = 8 + jEnd;
+ else
+ jEnd = 8;
+ for(int j = 0; j < jEnd ; k++, j++){
+ out_stream<<std::setw(10)<<aRec.node_labels[k];
+ }
+ out_stream<<std::endl;
+ }
+ }
+
+ /*
+ * Write end of dataset
+ */
+ out_stream<<" -1\n";
+}
+
+
+bool UNV2412::IsBeam(int theFeDescriptorId){
+ switch (theFeDescriptorId){
+ case 11:
+ case 21:
+ case 22:
+ case 24:
+ case 25:
+ return true;
+ }
+ return false;
+}
+
+
+bool UNV2412::IsFace(int theFeDescriptorId){
+ switch (theFeDescriptorId){
+
+ case 71: // TRI3
+ case 72:
+ case 74:
+
+ case 41: // Plane Stress Linear Triangle - TRI3
+ case 91: // Thin Shell Linear Triangle - TRI3
+
+ case 42: // Plane Stress Quadratic Triangle - TRI6
+ case 92: // Thin Shell Quadratic Triangle - TRI6
+
+ case 43: // Plane Stress Cubic Triangle
+
+ case 44: // Plane Stress Linear Quadrilateral - QUAD4
+ case 94: // Thin Shell Linear Quadrilateral - QUAD4
+
+ case 45: // Plane Stress Quadratic Quadrilateral - QUAD8
+ case 95: // Thin Shell Quadratic Quadrilateral - QUAD8
+
+ case 46: // Plane Stress Cubic Quadrilateral
+
+ return true;
+ }
+ return false;
+}
+
+
+bool UNV2412::IsVolume(int theFeDescriptorId){
+ //if(!IsBeam(theFeDescriptorId) && !IsFace(theFeDescriptorId))
+ // return true;
+ switch (theFeDescriptorId){
+
+ case 111: // Solid Linear Tetrahedron - TET4
+ case 118: // Solid Quadratic Tetrahedron - TET10
+
+ case 112: // Solid Linear Prism - PRISM6
+
+ case 115: // Solid Linear Brick - HEX8
+ case 116: // Solid Quadratic Brick - HEX20
+
+ case 117: // Solid Cubic Brick
+ return true;
+ }
+ return false;
+}
--- /dev/null
+// Copyright (C) 2003 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
+// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
+//
+// This library 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.
+//
+// This library 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 this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+//
+// See http://www.opencascade.org/SALOME/ or email : webmaster.salome@opencascade.org
+
+#ifndef UNV2412_Structure_HeaderFile
+#define UNV2412_Structure_HeaderFile
+
+#include <map>
+#include <vector>
+#include <fstream>
+
+
+namespace UNV2412{
+
+ struct TRecord{
+ TRecord();
+
+ int fe_descriptor_id; // FE descriptor id
+ int phys_prop_tab_num; // physical property table number
+ int mat_prop_tab_num; // material property table number
+ int color; // color
+ std::vector<int> node_labels; // node labels defining element
+
+ //FOR BEAM ELEMENTS ONLY
+ int beam_orientation; // beam orientation node number
+ int beam_fore_end; // beam fore-end cross section number
+ int beam_aft_end; // beam aft-end cross section number
+ };
+
+ typedef int TElementLab; // type of element label
+ typedef std::map<TElementLab,TRecord> TDataSet;
+
+ void Read(std::ifstream& in_stream, TDataSet& theDataSet);
+
+ void Write(std::ofstream& out_stream, const TDataSet& theDataSet);
+
+ bool IsBeam(int theFeDescriptorId);
+ bool IsFace(int theFeDescriptorId);
+ bool IsVolume(int theFeDescriptorId);
+
+};
+
+
+#endif
--- /dev/null
+// Copyright (C) 2003 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
+// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
+//
+// This library 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.
+//
+// This library 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 this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+//
+// See http://www.opencascade.org/SALOME/ or email : webmaster.salome@opencascade.org
+
+#include "UNV2411_Structure.hxx"
+#include "UNV2412_Structure.hxx"
+#include "UNV_Utilities.hxx"
+
+#include "DriverUNV_R_SMDS_Mesh.h"
+#include "DriverUNV_W_SMDS_Mesh.h"
+
+using namespace std;
+
+#ifdef DEBUG
+static int MYDEBUG = 1;
+#else
+static int MYDEBUG = 0;
+#endif
+
+
+void ReadMed(const char* theFileName){
+ std::ifstream in_stream(theFileName);
+
+ UNV2411::TDataSet aDataSet2411;
+ UNV2411::Read(in_stream,aDataSet2411);
+
+ in_stream.seekg(0);
+ UNV2412::TDataSet aDataSet2412;
+ UNV2412::Read(in_stream,aDataSet2412);
+
+ string aFileName(theFileName);
+ aFileName += "-";
+ std::ofstream out_stream(aFileName.c_str());
+
+ UNV2411::Write(out_stream,aDataSet2411);
+ UNV2412::Write(out_stream,aDataSet2412);
+}
+
+
+int main(int argc, char** argv){
+ DriverUNV_R_SMDS_Mesh aR;
+ DriverUNV_W_SMDS_Mesh aW;
+ try{
+ if(argc > 1){
+ ReadMed(argv[1]);
+ }
+ return 0;
+ }catch(std::exception& exc){
+ cout<<"Follow exception was accured :\n"<<exc.what()<<endl;
+ }catch(...){
+ cout<<"Unknown exception was accured !!!"<<endl;
+ }
+ return 1;
+}
--- /dev/null
+// Copyright (C) 2003 CEA/DEN, EDF R&D
+//
+//
+//
+// File : VISU_DatConvertor.cxx
+// Author : Alexey PETROV
+// Module : VISU
+
+#include "UNV_Utilities.hxx"
+
+using namespace std;
+
+#ifdef _DEBUG_
+static int MYDEBUG = 1;
+#else
+static int MYDEBUG = 0;
+#endif
+
+
+int UNV::PrefixPrinter::myCounter = 0;
+
+UNV::PrefixPrinter::PrefixPrinter()
+{
+ myCounter++;
+}
+
+UNV::PrefixPrinter::~PrefixPrinter()
+{
+ myCounter--;
+}
+
+string UNV::PrefixPrinter::GetPrefix()
+{
+ if(myCounter)
+ return string(myCounter*2,' ');
+ return "";
+}
--- /dev/null
+// Copyright (C) 2003 CEA/DEN, EDF R&D
+//
+//
+//
+// File : VISU_DatConvertor.hxx
+// Author : Alexey PETROV
+// Module : VISU
+
+#ifndef MED_Utilities_HeaderFile
+#define MED_Utilities_HeaderFile
+
+#include <iostream>
+#include <sstream>
+#include <string>
+#include <stdexcept>
+
+
+namespace UNV{
+ using namespace std;
+
+ class PrefixPrinter{
+ static int myCounter;
+ public:
+ PrefixPrinter();
+ ~PrefixPrinter();
+
+ static string GetPrefix();
+ };
+
+ /**
+ * @returns \p false when error occured, \p true otherwise.
+ * Adjusts the \p in_stream to the beginning of the
+ * dataset \p ds_name.
+ */
+ inline bool beginning_of_dataset(std::istream& in_file, const std::string& ds_name)
+ {
+ assert (in_file.good());
+ assert (!ds_name.empty());
+
+ std::string olds, news;
+
+ while(true){
+ in_file >> olds >> news;
+ /*
+ * a "-1" followed by a number means the beginning of a dataset
+ * stop combing at the end of the file
+ */
+ while( ((olds != "-1") || (news == "-1") ) && !in_file.eof() ){
+ olds = news;
+ in_file >> news;
+ }
+ if(in_file.eof())
+ return false;
+ if (news == ds_name)
+ return true;
+ }
+ // should never end up here
+ return false;
+ }
+
+ /**
+ * Method for converting exponential notation
+ * from "D" to "e", for example
+ * \p 3.141592654D+00 \p --> \p 3.141592654e+00
+ * in order to make it readable for C++.
+ */
+ inline double D_to_e(std::string& number)
+ {
+ /* find "D" in string, start looking at
+ * 6th element, to improve speed.
+ * We dont expect a "D" earlier
+ */
+ const int position = number.find("D",6);
+ if(position != std::string::npos){
+ number.replace(position, 1, "e");
+ }
+ return atof (number.c_str());
+ }
+
+};
+
+
+#ifndef MESSAGE
+
+#define MESSAGE(msg) std::cout<<__FILE__<<"["<<__LINE__<<"]::"<<msg<<endl;
+
+#define BEGMSG(msg) std::cout<<UNV::PrefixPrinter::GetPrefix()<<msg
+
+#define ADDMSG(msg) std::cout<<msg
+
+#endif
+
+
+#ifndef EXCEPTION
+
+#define EXCEPTION(TYPE, MSG) {\
+ std::ostringstream aStream;\
+ aStream<<__FILE__<<"["<<__LINE__<<"]::"<<MSG;\
+ throw TYPE(aStream.str());\
+}
+
+#endif
+
+#endif
@COMMENCE@
-SUBDIRS = OBJECT SMDS SMESHDS Driver DriverMED DriverDAT DriverUNV MEFISTO2 \
- SMESH SMESH_I SMESHFiltersSelection SMESHGUI \
- SMESH_SWIG
-
-ifeq (@WITHNETGEN@,yes)
-SUBDIRS = OBJECT SMDS SMESHDS Driver DriverMED DriverDAT DriverUNV MEFISTO2 \
- NETGEN SMESH SMESH_I SMESHFiltersSelection SMESHGUI \
- SMESH_SWIG
-endif
+SUBDIRS = \
+ SMDS SMESHDS Driver DriverMED DriverDAT DriverUNV \
+ SMESH SMESH_I OBJECT SMESHFiltersSelection SMESHGUI SMESH_SWIG \
+ MEFISTO2 StdMeshers StdMeshers_I StdMeshersGUI
@MODULE@
--- /dev/null
+# SMESH NETGENPlugin : implementaion of SMESH idl descriptions
+#
+# Copyright (C) 2004 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
+# CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
+#
+# This library 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.
+#
+# This library 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 this library; if not, write to the Free Software
+# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+#
+# See http://www.opencascade.org/SALOME/ or email : webmaster.salome@opencascade.org
+#
+#
+#
+# File : Makefile.in
+# Author : Julia DOROVSKIKH
+# Module : SMESH
+# $Header$
+
+top_srcdir=@top_srcdir@
+top_builddir=../..
+srcdir=@srcdir@
+VPATH=.:@srcdir@:@top_srcdir@/idl:$(top_builddir)/idl:
+
+
+@COMMENCE@
+
+EXPORT_PYSCRIPTS =
+
+# .po files to transform in .qm
+PO_FILES = NETGENPlugin_icons.po
+
+# Libraries targets
+LIB = libNETGENEngine.la
+LIB_SRC = \
+ NETGENPlugin_NETGEN_3D.cxx \
+ NETGENPlugin_NETGEN_3D_i.cxx \
+ NETGENPlugin_i.cxx
+
+LIB_SERVER_IDL = SMESH_NetgenAlgorithm.idl
+
+LIB_CLIENT_IDL = SMESH_Gen.idl SMESH_Mesh.idl SMESH_Group.idl
+
+# Executables targets
+BIN =
+BIN_SRC =
+
+# additionnal information to compil and link file
+NETGEN_INCLUDES=@NETGEN_INCLUDES@
+
+CPPFLAGS+= $(OCC_INCLUDES) $(HDF5_INCLUDES) -I${KERNEL_ROOT_DIR}/include/salome \
+ -I${GEOM_ROOT_DIR}/include/salome $(NETGEN_INCLUDES) $(BOOST_CPPFLAGS)
+CXXFLAGS+= $(OCC_CXXFLAGS) $(HDF5_INCLUDES) -I${KERNEL_ROOT_DIR}/include/salome \
+ -I${GEOM_ROOT_DIR}/include/salome $(NETGEN_INCLUDES)
+
+LDFLAGS+= $(HDF5_LIBS) -lSMESHimpl -lSMESHEngine -lStdMeshers -lStdMeshersEngine -lNETGEN -L${KERNEL_ROOT_DIR}/lib/salome -L${GEOM_ROOT_DIR}/lib/salome -lSalomeGenericObj
+
+@CONCLUDE@
--- /dev/null
+//=============================================================================
+// File : NETGENPlugin_NETGEN_3D.cxx
+// Moved here from SMESH_NETGEN_3D.cxx
+// Created : lundi 27 Janvier 2003
+// Author : Nadir BOUHAMOU (CEA)
+// Project : SALOME
+// Copyright : CEA 2003
+// $Header$
+//=============================================================================
+using namespace std;
+
+#include "NETGENPlugin_NETGEN_3D.hxx"
+#include "SMESH_Gen.hxx"
+#include "SMESH_Mesh.hxx"
+
+#include "SMDS_MeshElement.hxx"
+#include "SMDS_MeshNode.hxx"
+#include "SMDS_FacePosition.hxx"
+
+#include <TopExp.hxx>
+#include <TopTools_IndexedDataMapOfShapeListOfShape.hxx>
+#include <TopTools_ListOfShape.hxx>
+#include <TopTools_ListIteratorOfListOfShape.hxx>
+#include <TColStd_ListIteratorOfListOfInteger.hxx>
+
+#include <BRep_Tool.hxx>
+#include <Geom_Surface.hxx>
+#include <Geom_Curve.hxx>
+#include <Geom2d_Curve.hxx>
+
+#include "utilities.h"
+
+/*
+ Netgen include files
+*/
+
+#include "nglib.h"
+
+//=============================================================================
+/*!
+ *
+ */
+//=============================================================================
+
+NETGENPlugin_NETGEN_3D::NETGENPlugin_NETGEN_3D(int hypId, int studyId,
+ SMESH_Gen* gen)
+ : SMESH_3D_Algo(hypId, studyId, gen)
+{
+ MESSAGE("NETGENPlugin_NETGEN_3D::NETGENPlugin_NETGEN_3D");
+ _name = "NETGEN_3D";
+// _shapeType = TopAbs_SOLID;
+ _shapeType = (1 << TopAbs_SHELL) | (1 << TopAbs_SOLID);// 1 bit /shape type
+// MESSAGE("_shapeType octal " << oct << _shapeType);
+ _compatibleHypothesis.push_back("MaxElementVolume");
+
+ _maxElementVolume = 0.;
+
+ _hypMaxElementVolume = NULL;
+}
+
+//=============================================================================
+/*!
+ *
+ */
+//=============================================================================
+
+NETGENPlugin_NETGEN_3D::~NETGENPlugin_NETGEN_3D()
+{
+ MESSAGE("NETGENPlugin_NETGEN_3D::~NETGENPlugin_NETGEN_3D");
+}
+
+//=============================================================================
+/*!
+ *
+ */
+//=============================================================================
+
+bool NETGENPlugin_NETGEN_3D::CheckHypothesis
+ (SMESH_Mesh& aMesh,
+ const TopoDS_Shape& aShape,
+ SMESH_Hypothesis::Hypothesis_Status& aStatus)
+{
+ MESSAGE("NETGENPlugin_NETGEN_3D::CheckHypothesis");
+
+ _hypMaxElementVolume = NULL;
+
+ list<const SMESHDS_Hypothesis*>::const_iterator itl;
+ const SMESHDS_Hypothesis* theHyp;
+
+ const list<const SMESHDS_Hypothesis*>& hyps = GetUsedHypothesis(aMesh, aShape);
+ int nbHyp = hyps.size();
+ if (!nbHyp)
+ {
+ aStatus = SMESH_Hypothesis::HYP_MISSING;
+ return false; // can't work with no hypothesis
+ }
+
+ itl = hyps.begin();
+ theHyp = (*itl); // use only the first hypothesis
+
+ string hypName = theHyp->GetName();
+ int hypId = theHyp->GetID();
+ SCRUTE(hypName);
+
+ bool isOk = false;
+
+ if (hypName == "MaxElementVolume")
+ {
+ _hypMaxElementVolume = static_cast<const StdMeshers_MaxElementVolume*> (theHyp);
+ ASSERT(_hypMaxElementVolume);
+ _maxElementVolume = _hypMaxElementVolume->GetMaxVolume();
+ isOk =true;
+ aStatus = SMESH_Hypothesis::HYP_OK;
+ }
+ else
+ aStatus = SMESH_Hypothesis::HYP_INCOMPATIBLE;
+
+ return isOk;
+}
+
+//=============================================================================
+/*!
+ *Here we are going to use the NETGEN mesher
+ */
+//=============================================================================
+
+bool NETGENPlugin_NETGEN_3D::Compute(SMESH_Mesh& aMesh,
+ const TopoDS_Shape& aShape)
+{
+ MESSAGE("NETGENPlugin_NETGEN_3D::Compute with maxElmentsize = " << _maxElementVolume);
+
+ bool isOk = false;
+ SMESHDS_Mesh* meshDS = aMesh.GetMeshDS();
+ SMESH_subMesh* theSubMesh = aMesh.GetSubMesh(aShape);
+ //const Handle(SMESHDS_SubMesh)& subMeshDS = theSubMesh->GetSubMeshDS();
+
+ map<int, const SMDS_MeshNode*> netgenToDS;
+
+ MESSAGE("NETGENPlugin_NETGEN_3D::Compute Checking the mesh Faces");
+
+ // check if all faces were meshed by a triangle mesher (here MESFISTO_2D)
+
+ vector<SMESH_subMesh*> meshFaces;
+ vector<TopoDS_Shape> shapeFaces;
+
+ for (TopExp_Explorer exp(aShape,TopAbs_FACE);exp.More();exp.Next())
+ {
+ TopoDS_Shape aShapeFace = exp.Current();
+ SMESH_subMesh* aSubMesh = aMesh.GetSubMeshContaining(exp.Current());
+ ASSERT (aSubMesh);
+ int internal_size = meshFaces.size();
+ int index = 0;
+ for (int i = 0;i<internal_size;i++)
+ {
+ if (aSubMesh == meshFaces[i]) index = 1;
+ }
+ if (index == 0) meshFaces.push_back(aSubMesh);
+
+ internal_size = shapeFaces.size();
+ index = 0;
+ for (int i = 0;i<internal_size;i++)
+ {
+ if (aShapeFace == shapeFaces[i]) index = 1;
+ }
+ if (index == 0) shapeFaces.push_back(aShapeFace);
+ }
+
+ int numberOfFaces = meshFaces.size();
+ int numberOfShapeFaces = shapeFaces.size();
+
+ SCRUTE(numberOfFaces);
+ SCRUTE(numberOfShapeFaces);
+
+ MESSAGE("---");
+
+ int NbTotOfTria = 0;
+ int NbTotOfNodesFaces = 0;
+
+ for (int i=0; i<numberOfFaces; i++)
+ {
+ TopoDS_Shape aShapeFace = meshFaces[i]->GetSubShape();
+ TopoDS_Shape aFace = shapeFaces[i];
+ SMESH_Algo* algoFace = _gen->GetAlgo(aMesh, aShapeFace);
+ string algoFaceName = algoFace->GetName();
+ SCRUTE(algoFaceName);
+ if (algoFaceName != "MEFISTO_2D")
+ {
+ SCRUTE(algoFaceName);
+ ASSERT(0);
+ return false;
+ }
+
+ bool orientationMeshFace = (aFace.Orientation() == aShapeFace.Orientation());
+
+ const SMESHDS_SubMesh* aSubMeshDSFace = meshFaces[i]->GetSubMeshDS();
+ SCRUTE(aSubMeshDSFace);
+
+ int nbNodes = aSubMeshDSFace->NbNodes();
+ NbTotOfNodesFaces += nbNodes;
+ int nbTria = aSubMeshDSFace->NbElements();
+ NbTotOfTria += nbTria;
+ int index = 0;
+
+ MESSAGE("NETGENPlugin_NETGEN_3D::Compute The mesh Face " << (i+1) << " has " << nbNodes << " face internal Nodes, " << nbTria << " triangles");
+
+ SCRUTE(orientationMeshFace);
+
+ if (orientationMeshFace)
+ {
+ MESSAGE("The mesh and face have the same orientation");
+ }
+ else
+ {
+ MESSAGE("The mesh and face have different orientations");
+ }
+
+ SMDS_NodeIteratorPtr iteratorNodes = aSubMeshDSFace->GetNodes();
+ SCRUTE(nbNodes);
+ index = 0;
+ while(iteratorNodes->more())
+ {
+ index++;
+ const SMDS_MeshNode * node = iteratorNodes->next();
+// int nodeId = node->GetID();
+// double nodeX = node->X();
+// double nodeY = node->Y();
+// double nodeZ = node->Z();
+// MESSAGE("NODE -> ID = " << nodeId << " X = " << nodeX << " Y = " << nodeY << " Z = " << nodeZ);
+ }
+
+ SCRUTE(index);
+
+ SMDS_ElemIteratorPtr iteratorTriangle = aSubMeshDSFace->GetElements();
+
+ SCRUTE(nbTria);
+ index = 0;
+ int numberOfDegeneratedTriangle = 0;
+ while(iteratorTriangle->more())
+ {
+ index++;
+ const SMDS_MeshElement * triangle = iteratorTriangle->next();
+ int triangleId = triangle->GetID();
+
+ SMDS_ElemIteratorPtr triangleNodesIt = triangle->nodesIterator();
+
+ const SMDS_MeshNode * node1 = static_cast<const SMDS_MeshNode *>(triangleNodesIt->next());
+ double node1X = node1->X();
+ double node1Y = node1->Y();
+ double node1Z = node1->Z();
+
+ const SMDS_MeshNode * node2 = static_cast<const SMDS_MeshNode *>(triangleNodesIt->next());
+ double node2X = node2->X();
+ double node2Y = node2->Y();
+ double node2Z = node2->Z();
+
+ const SMDS_MeshNode * node3 = static_cast<const SMDS_MeshNode *>(triangleNodesIt->next());
+ double node3X = node3->X();
+ double node3Y = node3->Y();
+ double node3Z = node3->Z();
+
+ int triangleNode1 = node1->GetID();
+ int triangleNode2 = node2->GetID();
+ int triangleNode3 = node3->GetID();
+
+ // Compute the triangle surface
+
+ double vect1 = ((node2Y - node1Y)*(node3Z - node1Z) - (node2Z - node1Z)*(node3Y - node1Y));
+ double vect2 = - ((node2X - node1X)*(node3Z - node1Z) - (node2Z - node1Z)*(node3X - node1X));
+ double vect3 = ((node2X - node1X)*(node3Y - node1Y) - (node2Y - node1Y)*(node3X - node1X));
+ double epsilon = 1.0e-6;
+
+ bool triangleIsDegenerated = ((abs(vect1)<epsilon) && (abs(vect2)<epsilon) && (abs(vect3)<epsilon));
+
+ if (triangleIsDegenerated)
+ {
+// MESSAGE("TRIANGLE -> ID = " << triangleId << " N1 = " << triangleNode1 << " N2 = " << triangleNode2 << " N3 = " << triangleNode3 << " is degenerated");
+// MESSAGE("NODE -> ID = " << triangleNode1 << " X = " << node1X << " Y = " << node1Y << " Z = " << node1Z);
+// MESSAGE("NODE -> ID = " << triangleNode2 << " X = " << node2X << " Y = " << node2Y << " Z = " << node2Z);
+// MESSAGE("NODE -> ID = " << triangleNode3 << " X = " << node3X << " Y = " << node3Y << " Z = " << node3Z);
+ numberOfDegeneratedTriangle++;
+ }
+ else
+ {
+// MESSAGE("TRIANGLE -> ID = " << triangleId << " N1 = " << triangleNode1 << " N2 = " << triangleNode2 << " N3 = " << triangleNode3 << " is normal");
+ }
+ }
+
+ if (numberOfDegeneratedTriangle > 0)
+ MESSAGE("WARNING THERE IS(ARE) " << numberOfDegeneratedTriangle << " degenerated triangle on this face");
+
+ SCRUTE(index);
+ }
+
+
+
+ SCRUTE(NbTotOfTria);
+ SCRUTE(NbTotOfNodesFaces);
+
+ MESSAGE("NETGENPlugin_NETGEN_3D::Compute Checking the mesh Edges");
+
+ // check if all edges were meshed by a edge mesher (here Regular_1D)
+
+ vector<SMESH_subMesh*> meshEdges;
+ for (TopExp_Explorer exp(aShape,TopAbs_EDGE);exp.More();exp.Next())
+ {
+ SMESH_subMesh* aSubMesh = aMesh.GetSubMeshContaining(exp.Current());
+ ASSERT (aSubMesh);
+ int internal_size = meshEdges.size();
+ int index = 0;
+ for (int i = 0;i<internal_size;i++)
+ {
+ if (aSubMesh == meshEdges[i]) index = 1;
+ }
+ if (index == 0) meshEdges.push_back(aSubMesh);
+ }
+
+ int numberOfEdges = meshEdges.size();
+ SCRUTE(numberOfEdges);
+
+ MESSAGE("---");
+
+ int NbTotOfNodesEdges = 0;
+ int NbTotOfSegs = 0;
+
+ for (int i=0; i<numberOfEdges; i++)
+ {
+ TopoDS_Shape aShapeEdge = meshEdges[i]->GetSubShape();
+ SMESH_Algo* algoEdge = _gen->GetAlgo(aMesh, aShapeEdge);
+ string algoEdgeName = algoEdge->GetName();
+ SCRUTE(algoEdgeName);
+ if (algoEdgeName != "Regular_1D")
+ {
+ SCRUTE(algoEdgeName);
+ ASSERT(0);
+ return false;
+ }
+
+ const SMESHDS_SubMesh* aSubMeshDSEdge = meshEdges[i]->GetSubMeshDS();
+ SCRUTE(aSubMeshDSEdge);
+
+ int nbNodes = aSubMeshDSEdge->NbNodes();
+ NbTotOfNodesEdges += nbNodes;
+ int nbSegs = aSubMeshDSEdge->NbElements();
+ NbTotOfSegs += nbSegs;
+
+ MESSAGE("NETGENPlugin_NETGEN_3D::Compute The mesh Edge " << (i+1) << " has " << nbNodes << " edge internal Nodes, " << nbSegs << " segments");
+
+ SMDS_NodeIteratorPtr iteratorNodes = aSubMeshDSEdge->GetNodes();
+ SCRUTE(nbNodes);
+ int index = 0;
+ while(iteratorNodes->more())
+ {
+ index++;
+ const SMDS_MeshNode * node = iteratorNodes->next();
+// int nodeId = node->GetID();
+// double nodeX = node->X();
+// double nodeY = node->Y();
+// double nodeZ = node->Z();
+// MESSAGE("NODE -> ID = " << nodeId << " X = " << nodeX << " Y = " << nodeY << " Z = " << nodeZ);
+ }
+
+ SCRUTE(index);
+ }
+
+ SCRUTE(NbTotOfNodesEdges);
+ SCRUTE(NbTotOfSegs);
+
+ MESSAGE("NETGENPlugin_NETGEN_3D::Compute Checking the mesh Vertices");
+
+ vector<SMESH_subMesh*> meshVertices;
+ for (TopExp_Explorer exp(aShape,TopAbs_VERTEX);exp.More();exp.Next())
+ {
+ SMESH_subMesh* aSubMesh = aMesh.GetSubMeshContaining(exp.Current());
+ ASSERT (aSubMesh);
+ int internal_size = meshVertices.size();
+ int index = 0;
+ for (int i = 0;i<internal_size;i++)
+ {
+ if (aSubMesh == meshVertices[i]) index = 1;
+ }
+ if (index == 0) meshVertices.push_back(aSubMesh);
+ }
+
+ int numberOfVertices = meshVertices.size();
+ SCRUTE(numberOfVertices);
+
+ MESSAGE("---");
+
+ int NbTotOfNodesVertices = 0;
+
+ for (int i=0; i<numberOfVertices; i++)
+ {
+ TopoDS_Shape aShapeVertex = meshVertices[i]->GetSubShape();
+
+ const SMESHDS_SubMesh * aSubMeshDSVertex = meshVertices[i]->GetSubMeshDS();
+ SCRUTE(aSubMeshDSVertex);
+
+ int nbNodes = aSubMeshDSVertex->NbNodes();
+ NbTotOfNodesVertices += nbNodes;
+
+ MESSAGE("NETGENPlugin_NETGEN_3D::Compute The mesh Vertex " << (i+1) << " has " << nbNodes << " Nodes");
+
+ SMDS_NodeIteratorPtr iteratorNodes = aSubMeshDSVertex->GetNodes();
+ SCRUTE(nbNodes);
+ int index = 0;
+ while(iteratorNodes->more())
+ {
+ index++;
+ const SMDS_MeshNode * node = iteratorNodes->next();
+// int nodeId = node->GetID();
+// double nodeX = node->X();
+// double nodeY = node->Y();
+// double nodeZ = node->Z();
+// MESSAGE("NODE -> ID = " << nodeId << " X = " << nodeX << " Y = " << nodeY << " Z = " << nodeZ);
+ }
+
+ SCRUTE(index);
+ }
+
+ SCRUTE(NbTotOfNodesVertices);
+
+ MESSAGE("NETGENPlugin_NETGEN_3D::Compute --> Analysis of all shell mesh");
+
+ vector<SMESH_subMesh*> meshShells;
+ TopoDS_Shell aShell;
+
+ for (TopExp_Explorer exp(aShape,TopAbs_SHELL);exp.More();exp.Next())
+ {
+ SMESH_subMesh* aSubMesh = aMesh.GetSubMesh(exp.Current());
+ ASSERT(aSubMesh);
+ SCRUTE(aSubMesh);
+ aShell = TopoDS::Shell(exp.Current());
+ meshShells.push_back(aSubMesh);
+ }
+
+ int numberOfShells = meshShells.size();
+ SCRUTE(numberOfShells);
+
+ if (numberOfShells == 1)
+ {
+ MESSAGE("NETGENPlugin_NETGEN_3D::Compute Only one shell --> generation of the mesh using directly Netgen");
+
+ /*
+ Prepare the Netgen surface mesh from the SMESHDS
+ */
+
+ MESSAGE("NETGENPlugin_NETGEN_3D::Compute Prepare the Netgen surface mesh from the SMESHDS");
+
+ int spaceDimension = 3;
+ int nbNodesByTri = 3;
+ int nbNodesByTetra = 4;
+
+ int Netgen_NbOfNodes = NbTotOfNodesFaces +
+ NbTotOfNodesEdges +
+ NbTotOfNodesVertices;
+ int Netgen_NbOfTria = NbTotOfTria;
+ int Netgen_param2ndOrder = 0;
+ double Netgen_paramFine = 1.;
+ double Netgen_paramSize = _maxElementVolume;
+
+ SCRUTE(Netgen_NbOfNodes);
+ SCRUTE(Netgen_NbOfTria);
+
+ double * Netgen_Coordinates = new double [spaceDimension*
+ Netgen_NbOfNodes];
+ int * listNodeCoresNetgenSmesh = new int [Netgen_NbOfNodes];
+ int * Netgen_Connectivity = new int [nbNodesByTri*Netgen_NbOfTria];
+ double * Netgen_point = new double [spaceDimension];
+ int * Netgen_triangle = new int [nbNodesByTri];
+ int * Netgen_tetrahedron = new int [nbNodesByTetra];
+
+ for (int i=0; i<Netgen_NbOfTria; i++)
+ {
+ for (int j=0; j<nbNodesByTri; j++)
+ Netgen_Connectivity[i*nbNodesByTri+j] = 0;
+ }
+
+ double bigNumber = 1.e20;
+
+ for (int i=0; i<Netgen_NbOfNodes; i++)
+ {
+ listNodeCoresNetgenSmesh[i] = 0;
+ for (int j=0; j<spaceDimension; j++)
+ Netgen_Coordinates[i*spaceDimension+j] = bigNumber;
+ }
+
+ int indexNodes = 0;
+ for (int i=0; i<numberOfVertices; i++)
+ {
+ const SMESHDS_SubMesh * aSubMeshDSVertex =
+ meshVertices[i]->GetSubMeshDS();
+
+ SMDS_NodeIteratorPtr iteratorNodes = aSubMeshDSVertex->GetNodes();
+
+ while(iteratorNodes->more())
+ {
+ const SMDS_MeshNode * node = iteratorNodes->next();
+ int nodeId = node->GetID();
+ double nodeX = node->X();
+ double nodeY = node->Y();
+ double nodeZ = node->Z();
+// MESSAGE("NODE -> ID = " << nodeId << " X = " << nodeX << " Y = " << nodeY << " Z = " << nodeZ);
+ listNodeCoresNetgenSmesh[indexNodes] = nodeId;
+ int index = indexNodes*spaceDimension;
+ Netgen_Coordinates[index] = nodeX;
+ Netgen_Coordinates[index+1] = nodeY;
+ Netgen_Coordinates[index+2] = nodeZ;
+ netgenToDS[indexNodes] = node;
+ indexNodes++;
+ }
+ }
+
+ for (int i=0; i<numberOfEdges; i++)
+ {
+ const SMESHDS_SubMesh * aSubMeshDSEdge =
+ meshEdges[i]->GetSubMeshDS();
+
+ SMDS_NodeIteratorPtr iteratorNodes = aSubMeshDSEdge->GetNodes();
+
+ while(iteratorNodes->more())
+ {
+ const SMDS_MeshNode * node = iteratorNodes->next();
+ int nodeId = node->GetID();
+ double nodeX = node->X();
+ double nodeY = node->Y();
+ double nodeZ = node->Z();
+// MESSAGE("NODE -> ID = " << nodeId << " X = " << nodeX << " Y = " << nodeY << " Z = " << nodeZ);
+ listNodeCoresNetgenSmesh[indexNodes] = node->GetID();
+ int index = indexNodes*spaceDimension;
+ Netgen_Coordinates[index] = node->X();
+ Netgen_Coordinates[index+1] = node->Y();
+ Netgen_Coordinates[index+2] = node->Z();
+ netgenToDS[indexNodes] = node;
+ indexNodes++;
+ }
+ }
+
+ for (int i=0; i<numberOfFaces; i++)
+ {
+ const SMESHDS_SubMesh * aSubMeshDSFace =
+ meshFaces[i]->GetSubMeshDS();
+
+ SMDS_NodeIteratorPtr iteratorNodes = aSubMeshDSFace->GetNodes();
+
+ while(iteratorNodes->more())
+ {
+ const SMDS_MeshNode * node = iteratorNodes->next();
+ int nodeId = node->GetID();
+ double nodeX = node->X();
+ double nodeY = node->Y();
+ double nodeZ = node->Z();
+// MESSAGE("NODE -> ID = " << nodeId << " X = " << nodeX << " Y = " << nodeY << " Z = " << nodeZ);
+ listNodeCoresNetgenSmesh[indexNodes] = nodeId;
+ int index = indexNodes*spaceDimension;
+ Netgen_Coordinates[index] = nodeX;
+ Netgen_Coordinates[index+1] = nodeY;
+ Netgen_Coordinates[index+2] = nodeZ;
+ netgenToDS[indexNodes] = node;
+ indexNodes++;
+ }
+ }
+
+ SCRUTE(indexNodes);
+
+ for (int i=0; i<Netgen_NbOfNodes; i++)
+ {
+ ASSERT(listNodeCoresNetgenSmesh[i] != 0);
+
+ for (int j=0; j<Netgen_NbOfNodes && j!=i; j++)
+ ASSERT(listNodeCoresNetgenSmesh[i] != listNodeCoresNetgenSmesh[j]);
+
+ for (int j=0; j<spaceDimension; j++)
+ ASSERT(Netgen_Coordinates[i*spaceDimension+j] != bigNumber);
+ }
+
+ int indexTrias = 0;
+ for (int i=0; i<numberOfFaces; i++)
+ {
+ const SMESHDS_SubMesh * aSubMeshDSFace =
+ meshFaces[i]->GetSubMeshDS();
+
+ TopoDS_Shape aFace = shapeFaces[i];
+
+ SMDS_ElemIteratorPtr iteratorTriangle = aSubMeshDSFace->GetElements();
+
+ TopoDS_Shape aShapeFace = meshFaces[i]->GetSubShape();
+
+ bool orientationMeshFace = (aFace.Orientation() == aShapeFace.Orientation());
+
+ SCRUTE(orientationMeshFace);
+
+ if (orientationMeshFace)
+ {
+ MESSAGE("The mesh and face have the same orientation");
+
+ while(iteratorTriangle->more())
+ {
+ const SMDS_MeshElement * triangle = iteratorTriangle->next();
+ int triangleId = triangle->GetID();
+
+ SMDS_ElemIteratorPtr triangleNodesIt = triangle->nodesIterator();
+
+ int triangleNode1 = (triangleNodesIt->next())->GetID();
+ int triangleNode2 = (triangleNodesIt->next())->GetID();
+ int triangleNode3 = (triangleNodesIt->next())->GetID();
+
+// MESSAGE("TRIANGLE -> ID = " << triangleId << " N1 = " << triangleNode1 << " N2 = " << triangleNode2 << " N3 = " << triangleNode3);
+
+ int N1New = 0;
+ int N2New = 0;
+ int N3New = 0;
+ int index = indexTrias*nbNodesByTri;
+
+ for (int j=0; j<Netgen_NbOfNodes; j++)
+ {
+ int jp1 = j+1;
+
+ if (triangleNode1 == listNodeCoresNetgenSmesh[j])
+ N1New = jp1;
+ else if (triangleNode2 == listNodeCoresNetgenSmesh[j])
+ N2New = jp1;
+ else if (triangleNode3 == listNodeCoresNetgenSmesh[j])
+ N3New = jp1;
+ }
+
+ triangleNode1 = N1New;
+ triangleNode2 = N2New;
+ triangleNode3 = N3New;
+
+ Netgen_Connectivity[index] = triangleNode1;
+ Netgen_Connectivity[index+1] = triangleNode2;
+ Netgen_Connectivity[index+2] = triangleNode3;
+
+ indexTrias++;
+ }
+ }
+ else
+ {
+ MESSAGE("The mesh and face have different orientations");
+
+ while(iteratorTriangle->more())
+ {
+ const SMDS_MeshElement * triangle = iteratorTriangle->next();
+ int triangleId = triangle->GetID();
+
+ SMDS_ElemIteratorPtr triangleNodesIt = triangle->nodesIterator();
+
+ int triangleNode1 = (triangleNodesIt->next())->GetID();
+ int triangleNode3 = (triangleNodesIt->next())->GetID();
+ int triangleNode2 = (triangleNodesIt->next())->GetID();
+
+// MESSAGE("TRIANGLE -> ID = " << triangleId << " N1 = " << triangleNode1 << " N2 = " << triangleNode2 << " N3 = " << triangleNode3);
+
+ int N1New = 0;
+ int N2New = 0;
+ int N3New = 0;
+ int index = indexTrias*nbNodesByTri;
+
+ for (int j=0; j<Netgen_NbOfNodes; j++)
+ {
+ int jp1 = j+1;
+
+ if (triangleNode1 == listNodeCoresNetgenSmesh[j])
+ N1New = jp1;
+ else if (triangleNode2 == listNodeCoresNetgenSmesh[j])
+ N2New = jp1;
+ else if (triangleNode3 == listNodeCoresNetgenSmesh[j])
+ N3New = jp1;
+ }
+
+ triangleNode1 = N1New;
+ triangleNode2 = N2New;
+ triangleNode3 = N3New;
+
+ Netgen_Connectivity[index] = triangleNode1;
+ Netgen_Connectivity[index+1] = triangleNode2;
+ Netgen_Connectivity[index+2] = triangleNode3;
+
+ indexTrias++;
+ }
+ }
+ }
+
+ SCRUTE(indexTrias);
+
+ int * nodesUsed = new int[Netgen_NbOfNodes];
+
+ for (int i=0; i<Netgen_NbOfNodes; i++) nodesUsed[i] = 0;
+
+ for (int i=0; i<Netgen_NbOfTria; i++)
+ for (int j=0; j<nbNodesByTri; j++)
+ {
+ int Nij = Netgen_Connectivity[i*nbNodesByTri+j];
+
+ ASSERT((Nij>=1) && (Nij<=Netgen_NbOfNodes));
+
+ nodesUsed[Nij-1] = 1;
+ Netgen_Connectivity[i*nbNodesByTri+j] = Nij;
+ }
+
+ for (int i=0; i<Netgen_NbOfNodes; i++)
+ {
+ ASSERT(nodesUsed[i] != 0);
+ }
+
+ delete [] nodesUsed;
+
+ /*
+ Feed the Netgen surface mesh
+ */
+
+ MESSAGE("NETGENPlugin_NETGEN_3D::Compute Feed the Netgen surface mesh");
+
+ Ng_Mesh * Netgen_mesh;
+
+ Ng_Init();
+
+ Netgen_mesh = Ng_NewMesh();
+
+ Ng_Meshing_Parameters Netgen_param;
+
+ for (int i=0; i<Netgen_NbOfNodes; i++)
+ {
+ for (int j=0; j<spaceDimension; j++)
+ Netgen_point[j] = Netgen_Coordinates[i*spaceDimension+j];
+
+ Ng_AddPoint(Netgen_mesh, Netgen_point);
+ }
+
+ for (int i=0; i<Netgen_NbOfTria; i++)
+ {
+ for (int j=0; j<nbNodesByTri; j++)
+ Netgen_triangle[j] = Netgen_Connectivity[i*nbNodesByTri+j];
+
+ Ng_AddSurfaceElement(Netgen_mesh, NG_TRIG, Netgen_triangle);
+ }
+
+ SCRUTE(Netgen_paramSize);
+
+ Netgen_param.secondorder = Netgen_param2ndOrder;
+ Netgen_param.fineness = Netgen_paramFine;
+ Netgen_param.maxh = Netgen_paramSize;
+
+ /*
+ Generate the volume mesh
+ */
+
+ MESSAGE("NETGENPlugin_NETGEN_3D::Compute Generate the volume mesh");
+
+ SCRUTE(Netgen_NbOfNodes);
+ SCRUTE(Netgen_NbOfTria);
+
+ SCRUTE(Ng_GetNP(Netgen_mesh));
+ SCRUTE(Ng_GetNE(Netgen_mesh));
+ SCRUTE(Ng_GetNSE(Netgen_mesh));
+
+ ASSERT(Netgen_NbOfNodes == Ng_GetNP(Netgen_mesh));
+ ASSERT(Ng_GetNE(Netgen_mesh) == 0);
+ ASSERT(Netgen_NbOfTria == Ng_GetNSE(Netgen_mesh));
+
+ Ng_Result status;
+
+ status = Ng_GenerateVolumeMesh(Netgen_mesh, &Netgen_param);
+
+ SCRUTE(status);
+
+ int Netgen_NbOfNodesNew = Ng_GetNP(Netgen_mesh);
+
+ int Netgen_NbOfTetra = Ng_GetNE(Netgen_mesh);
+
+ SCRUTE(Netgen_NbOfNodesNew);
+
+ SCRUTE(Netgen_NbOfTetra);
+
+ if ((status != NG_OK) ||
+ (Netgen_NbOfNodesNew <= Netgen_NbOfNodes) ||
+ (Netgen_NbOfTetra <= 0))
+ {
+ MESSAGE("NETGENPlugin_NETGEN_3D::Compute The Volume Mesh Generation has failed ...");
+ SCRUTE(status);
+
+ /*
+ Free the memory needed by to generate the Netgen Mesh
+ */
+
+ MESSAGE("NETGENPlugin_NETGEN_3D::Compute Free the memory needed by to generate the Netgen Mesh");
+
+ delete [] Netgen_Coordinates;
+ delete [] Netgen_Connectivity;
+ delete [] Netgen_point;
+ delete [] Netgen_triangle;
+ delete [] Netgen_tetrahedron;
+
+ delete [] listNodeCoresNetgenSmesh;
+
+ Ng_DeleteMesh(Netgen_mesh);
+ Ng_Exit();
+
+ return false;
+ }
+
+ MESSAGE("NETGENPlugin_NETGEN_3D::Compute End of Volume Mesh Generation");
+ SCRUTE(status);
+
+ double * Netgen_CoordinatesNew = new double [spaceDimension*Netgen_NbOfNodesNew];
+ int * Netgen_ConnectivityNew = new int [nbNodesByTetra*Netgen_NbOfTetra];
+
+ for (int i=0; i<Netgen_NbOfNodesNew; i++)
+ {
+ Ng_GetPoint(Netgen_mesh, (i+1), Netgen_point);
+
+ for (int j=0; j<spaceDimension; j++)
+ Netgen_CoordinatesNew[i*spaceDimension+j] = Netgen_point[j];
+ }
+
+ for (int i=0; i<Netgen_NbOfNodes; i++)
+ for (int j=0; j<spaceDimension; j++)
+ ASSERT(Netgen_CoordinatesNew[i*spaceDimension+j] == Netgen_Coordinates[i*spaceDimension+j])
+
+ for (int i=0; i<Netgen_NbOfTetra; i++)
+ {
+ Ng_GetVolumeElement(Netgen_mesh, (i+1), Netgen_tetrahedron);
+
+ for (int j=0; j<nbNodesByTetra; j++)
+ Netgen_ConnectivityNew[i*nbNodesByTetra+j] = Netgen_tetrahedron[j];
+ }
+
+ /*
+ Feed back the SMESHDS with the generated Nodes and Volume Elements
+ */
+
+ MESSAGE("NETGENPlugin_NETGEN_3D::Compute Feed back the SMESHDS with the generated Nodes and Volume Elements");
+
+ int NbTotOfNodesShell = Netgen_NbOfNodesNew - Netgen_NbOfNodes;
+
+ SCRUTE(NbTotOfNodesShell);
+
+ int * listNodeShellCoresNetgenSmesh = new int [NbTotOfNodesShell];
+
+ for (int i=0; i<NbTotOfNodesShell; i++)
+ listNodeShellCoresNetgenSmesh[i] = 0;
+
+ MESSAGE("NETGENPlugin_NETGEN_3D::Compute --> Adding the New Nodes to SMESHDS");
+
+ for (int i=0; i<NbTotOfNodesShell; i++)
+ {
+ int index = (i+Netgen_NbOfNodes)*spaceDimension;
+
+ SMDS_MeshNode * node =
+ meshDS->AddNode(Netgen_CoordinatesNew[index],
+ Netgen_CoordinatesNew[index+1],
+ Netgen_CoordinatesNew[index+2]);
+
+ meshDS->SetNodeInVolume(node, aShell);
+
+ index = i+Netgen_NbOfNodes;
+ netgenToDS[index] = node;
+
+ listNodeShellCoresNetgenSmesh[i] = node->GetID();
+ }
+
+ SCRUTE(Netgen_NbOfNodesNew);
+
+ SCRUTE(netgenToDS.size());
+
+ for (int i=0; i<NbTotOfNodesShell; i++)
+ {
+ ASSERT(listNodeShellCoresNetgenSmesh[i] != 0);
+
+ for (int j=0; j<NbTotOfNodesShell && j!=i; j++)
+ ASSERT(listNodeShellCoresNetgenSmesh[i] != listNodeShellCoresNetgenSmesh[j]);
+ }
+
+ MESSAGE("NETGENPlugin_NETGEN_3D::Compute --> Adding the New elements (Tetrahedrons) to the SMESHDS");
+
+ for (int i=0; i<Netgen_NbOfTetra; i++)
+ {
+ int index = i*nbNodesByTetra;
+ int tetraNode1 = Netgen_ConnectivityNew[index];
+ int tetraNode2 = Netgen_ConnectivityNew[index+1];
+ int tetraNode3 = Netgen_ConnectivityNew[index+2];
+ int tetraNode4 = Netgen_ConnectivityNew[index+3];
+
+ const SMDS_MeshNode * node1 = netgenToDS[tetraNode1-1];
+ const SMDS_MeshNode * node2 = netgenToDS[tetraNode2-1];
+ const SMDS_MeshNode * node3 = netgenToDS[tetraNode3-1];
+ const SMDS_MeshNode * node4 = netgenToDS[tetraNode4-1];
+
+ index = tetraNode1;
+ if (index <= Netgen_NbOfNodes)
+ tetraNode1 = listNodeCoresNetgenSmesh[index-1];
+ else
+ tetraNode1 = listNodeShellCoresNetgenSmesh[index-Netgen_NbOfNodes-1];
+
+ index = tetraNode2;
+ if (index <= Netgen_NbOfNodes)
+ tetraNode2 = listNodeCoresNetgenSmesh[index-1];
+ else
+ tetraNode2 = listNodeShellCoresNetgenSmesh[index-Netgen_NbOfNodes-1];
+
+ index = tetraNode3;
+ if (index <= Netgen_NbOfNodes)
+ tetraNode3 = listNodeCoresNetgenSmesh[index-1];
+ else
+ tetraNode3 = listNodeShellCoresNetgenSmesh[index-Netgen_NbOfNodes-1];
+
+ index = tetraNode4;
+ if (index <= Netgen_NbOfNodes)
+ tetraNode4 = listNodeCoresNetgenSmesh[index-1];
+ else
+ tetraNode4 = listNodeShellCoresNetgenSmesh[index-Netgen_NbOfNodes-1];
+
+ SMDS_MeshVolume * elt =
+ meshDS->AddVolume(node1,node2,node3,node4);
+
+ meshDS->SetMeshElementOnShape(elt, aShell);
+ }
+
+ /*
+ Free the memory needed by to generate the Netgen Mesh
+ */
+
+ MESSAGE("NETGENPlugin_NETGEN_3D::Compute Free the memory needed by to generate the Netgen Mesh");
+
+ delete [] Netgen_Coordinates;
+ delete [] Netgen_Connectivity;
+ delete [] Netgen_CoordinatesNew;
+ delete [] Netgen_ConnectivityNew;
+ delete [] Netgen_point;
+ delete [] Netgen_triangle;
+ delete [] Netgen_tetrahedron;
+
+ delete [] listNodeCoresNetgenSmesh;
+ delete [] listNodeShellCoresNetgenSmesh;
+
+ Ng_DeleteMesh(Netgen_mesh);
+ Ng_Exit();
+
+ /*
+ Verification
+ */
+
+ {
+ MESSAGE("NETGENPlugin_NETGEN_3D::Compute Verification of the Shell mesh");
+
+ TopoDS_Shape aShapeShell = meshShells[0]->GetSubShape();
+ SMESH_Algo* algoShell = _gen->GetAlgo(aMesh, aShapeShell);
+ string algoShellName = algoShell->GetName();
+ SCRUTE(algoShellName);
+ if (algoShellName != "NETGEN_3D")
+ {
+ SCRUTE(algoShellName);
+ ASSERT(0);
+ return false;
+ }
+
+ const SMESHDS_SubMesh * aSubMeshDSShell = meshShells[0]->GetSubMeshDS();
+ SCRUTE(&aSubMeshDSShell);
+
+ int nbNodes = aSubMeshDSShell->NbNodes();
+ int nbTetra = aSubMeshDSShell->NbElements();
+
+ MESSAGE("NETGENPlugin_NETGEN_3D::Compute The mesh Shell has " << nbNodes << " shell internal Nodes, " << nbTetra << " tetrahedrons");
+
+ SMDS_NodeIteratorPtr iteratorNodes = aSubMeshDSShell->GetNodes();
+
+ SCRUTE(nbNodes);
+
+ int index;
+
+ index = 0;
+
+ while(iteratorNodes->more())
+ {
+ index++;
+ const SMDS_MeshNode * node = iteratorNodes->next();
+ int nodeId = node->GetID();
+ double nodeX = node->X();
+ double nodeY = node->Y();
+ double nodeZ = node->Z();
+// MESSAGE("NODE -> ID = " << nodeId << " X = " << nodeX << " Y = " << nodeY << " Z = " << nodeZ);
+ }
+
+ SCRUTE(index);
+
+ SMDS_ElemIteratorPtr iteratorTetra = aSubMeshDSShell->GetElements();
+
+ SCRUTE(nbTetra);
+
+ index = 0;
+ while(iteratorTetra->more())
+ {
+ index++;
+ const SMDS_MeshElement * tetra = iteratorTetra->next();
+ int tetraId = tetra->GetID();
+
+ SMDS_ElemIteratorPtr tetraNodesIt = tetra->nodesIterator();
+
+ int tetraNode1 = (tetraNodesIt->next())->GetID();
+ int tetraNode2 = (tetraNodesIt->next())->GetID();
+ int tetraNode3 = (tetraNodesIt->next())->GetID();
+ int tetraNode4 = (tetraNodesIt->next())->GetID();
+
+// MESSAGE("TETRAHEDRON -> ID = " << tetraId << " N1 = " << tetraNode1 << " N2 = " << tetraNode2 << " N3 = " << tetraNode3 << " N4 = " << tetraNode4);
+
+ }
+
+ SCRUTE(index);
+ }
+ }
+ else
+ {
+ SCRUTE(numberOfShells);
+ MESSAGE("NETGENPlugin_NETGEN_3D::Compute ERROR More than one shell ????? ");
+ return false;
+ }
+
+ return true;
+}
+
+
+//=============================================================================
+/*!
+ *
+ */
+//=============================================================================
+
+ostream & NETGENPlugin_NETGEN_3D::SaveTo(ostream & save)
+{
+ return save;
+}
+
+//=============================================================================
+/*!
+ *
+ */
+//=============================================================================
+
+istream & NETGENPlugin_NETGEN_3D::LoadFrom(istream & load)
+{
+ return load;
+}
+
+//=============================================================================
+/*!
+ *
+ */
+//=============================================================================
+
+ostream & operator << (ostream & save, NETGENPlugin_NETGEN_3D & hyp)
+{
+ return hyp.SaveTo( save );
+}
+
+//=============================================================================
+/*!
+ *
+ */
+//=============================================================================
+
+istream & operator >> (istream & load, NETGENPlugin_NETGEN_3D & hyp)
+{
+ return hyp.LoadFrom( load );
+}
--- /dev/null
+//=============================================================================
+// File : NETGENPlugin_NETGEN_3D.hxx
+// Moved here from SMESH_NETGEN_3D.hxx
+// Created : lundi 27 Janvier 2003
+// Author : Nadir BOUHAMOU (CEA)
+// Project : SALOME
+// Copyright : CEA 2003
+// $Header$
+//=============================================================================
+
+#ifndef _NETGENPlugin_NETGEN_3D_HXX_
+#define _NETGENPlugin_NETGEN_3D_HXX_
+
+#include "SMESH_3D_Algo.hxx"
+#include "SMESH_Mesh.hxx"
+#include "StdMeshers_MaxElementVolume.hxx"
+#include "Utils_SALOME_Exception.hxx"
+
+class NETGENPlugin_NETGEN_3D: public SMESH_3D_Algo
+{
+public:
+ NETGENPlugin_NETGEN_3D(int hypId, int studyId, SMESH_Gen* gen);
+ virtual ~NETGENPlugin_NETGEN_3D();
+
+ virtual bool CheckHypothesis(SMESH_Mesh& aMesh,
+ const TopoDS_Shape& aShape,
+ SMESH_Hypothesis::Hypothesis_Status& aStatus);
+
+ virtual bool Compute(SMESH_Mesh& aMesh,
+ const TopoDS_Shape& aShape);
+
+ ostream & SaveTo(ostream & save);
+ istream & LoadFrom(istream & load);
+ friend ostream & operator << (ostream & save, NETGENPlugin_NETGEN_3D & hyp);
+ friend istream & operator >> (istream & load, NETGENPlugin_NETGEN_3D & hyp);
+
+protected:
+ double _maxElementVolume;
+
+ const StdMeshers_MaxElementVolume* _hypMaxElementVolume;
+};
+
+#endif
--- /dev/null
+// SMESH SMESH_I : idl implementation based on 'SMESH' unit's calsses
+//
+// Copyright (C) 2003 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
+// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
+//
+// This library 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.
+//
+// This library 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 this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+//
+// See http://www.opencascade.org/SALOME/ or email : webmaster.salome@opencascade.org
+//
+//
+//
+// File : NETGENPlugin_NETGEN_3D_i.cxx
+// Moved here from SMESH_NETGEN_3D_i.cxx
+// Author : Nadir Bouhamou CEA
+// Module : SMESH
+// $Header$
+
+using namespace std;
+#include "NETGENPlugin_NETGEN_3D_i.hxx"
+#include "SMESH_Gen.hxx"
+
+#include "Utils_CorbaException.hxx"
+#include "utilities.h"
+
+//=============================================================================
+/*!
+ * NETGENPlugin_NETGEN_3D_i::NETGENPlugin_NETGEN_3D_i
+ *
+ * Constructor
+ */
+//=============================================================================
+
+NETGENPlugin_NETGEN_3D_i::NETGENPlugin_NETGEN_3D_i( PortableServer::POA_ptr thePOA,
+ int theStudyId,
+ ::SMESH_Gen* theGenImpl )
+ : SALOME::GenericObj_i( thePOA ),
+ SMESH_Hypothesis_i( thePOA ),
+ SMESH_Algo_i( thePOA ),
+ SMESH_3D_Algo_i( thePOA )
+{
+ MESSAGE( "NETGENPlugin_NETGEN_3D_i::NETGENPlugin_NETGEN_3D_i" );
+ myBaseImpl = new ::NETGENPlugin_NETGEN_3D( theGenImpl->GetANewId(),
+ theStudyId,
+ theGenImpl );
+}
+
+//=============================================================================
+/*!
+ * NETGENPlugin_NETGEN_3D_i::~NETGENPlugin_NETGEN_3D_i
+ *
+ * Destructor
+ */
+//=============================================================================
+
+NETGENPlugin_NETGEN_3D_i::~NETGENPlugin_NETGEN_3D_i()
+{
+ MESSAGE( "NETGENPlugin_NETGEN_3D_i::~NETGENPlugin_NETGEN_3D_i" );
+}
+
+//=============================================================================
+/*!
+ * NETGENPlugin_NETGEN_3D_i::GetImpl
+ *
+ * Get implementation
+ */
+//=============================================================================
+
+::NETGENPlugin_NETGEN_3D* NETGENPlugin_NETGEN_3D_i::GetImpl()
+{
+ MESSAGE( "NETGENPlugin_NETGEN_3D_i::GetImpl" );
+ return ( ::NETGENPlugin_NETGEN_3D* )myBaseImpl;
+}
+
--- /dev/null
+// SMESH SMESH_I : idl implementation based on 'SMESH' unit's calsses
+//
+// Copyright (C) 2003 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
+// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
+//
+// This library 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.
+//
+// This library 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 this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+//
+// See http://www.opencascade.org/SALOME/ or email : webmaster.salome@opencascade.org
+//
+//
+//
+// File : NETGENPlugin_NETGEN_3D_i.hxx
+// Moved here from SMESH_NETGEN_3D_i.hxx
+// Author : Nadir Bouhamou CEA
+// Module : SMESH
+// $Header$
+
+#ifndef _NETGENPlugin_NETGEN_3D_I_HXX_
+#define _NETGENPlugin_NETGEN_3D_I_HXX_
+
+#include <SALOMEconfig.h>
+#include CORBA_SERVER_HEADER(SMESH_NetgenAlgorithm)
+
+#include "SMESH_3D_Algo_i.hxx"
+#include "NETGENPlugin_NETGEN_3D.hxx"
+
+// ======================================================
+// NETGEN 3d algorithm
+// ======================================================
+class NETGENPlugin_NETGEN_3D_i:
+ public virtual POA_NETGENPlugin::NETGENPlugin_NETGEN_3D,
+ public virtual SMESH_3D_Algo_i
+{
+public:
+ // Constructor
+ NETGENPlugin_NETGEN_3D_i( PortableServer::POA_ptr thePOA,
+ int theStudyId,
+ ::SMESH_Gen* theGenImpl );
+ // Destructor
+ virtual ~NETGENPlugin_NETGEN_3D_i();
+
+ // Get implementation
+ ::NETGENPlugin_NETGEN_3D* GetImpl();
+};
+
+#endif
--- /dev/null
+// SMESH NETGENPlugin : implementaion of SMESH idl descriptions
+//
+// Copyright (C) 2003 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
+// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
+//
+// This library 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.
+//
+// This library 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 this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+//
+// See http://www.opencascade.org/SALOME/ or email : webmaster.salome@opencascade.org
+//
+//
+//
+// File : NETGENPlugin.cxx
+// Author : Julia DOROVSKIKH
+// Module : SMESH
+// $Header$
+
+using namespace std;
+#include "SMESH_Hypothesis_i.hxx"
+#include "SMESH_Gen_i.hxx"
+
+#include "utilities.h"
+
+#include "NETGENPlugin_NETGEN_3D_i.hxx"
+
+//=============================================================================
+/*!
+ *
+ */
+//=============================================================================
+
+extern "C"
+{
+ GenericHypothesisCreator_i* GetHypothesisCreator (const char* aHypName)
+ {
+ MESSAGE("GetHypothesisCreator " << aHypName);
+
+ GenericHypothesisCreator_i* aCreator = 0;
+
+ // Hypotheses
+
+ // Algorithms
+ if (strcmp(aHypName, "NETGEN_3D") == 0)
+ aCreator = new HypothesisCreator_i<NETGENPlugin_NETGEN_3D_i>;
+ else ;
+
+ return aCreator;
+ }
+}
--- /dev/null
+# This is a Qt message file in .po format. Each msgid starts with
+# a scope. This scope should *NOT* be translated - eg. "Foo::Bar"
+# would be translated to "Pub", not "Foo::Pub".
+msgid ""
+msgstr ""
+"Project-Id-Version: PROJECT VERSION\n"
+"POT-Creation-Date: 2002-05-28 10:57:43 AM CEST\n"
+"PO-Revision-Date: YYYY-MM-DD\n"
+"Last-Translator: FULLNAME <EMAIL@ADDRESS>\n"
+"Content-Type: text/plain; charset=iso-8859-1\n"
+
+
+#-----------------------------------------------------------
+# ObjectBrowser
+#-----------------------------------------------------------
+
+#mesh_tree_algo_netgen
+msgid "ICON_SMESH_TREE_ALGO_NETGEN_3D"
+msgstr "mesh_tree_algo_tetra.png"
+#msgstr "mesh_tree_algo_netgen.png"
top_srcdir=@top_srcdir@
top_builddir=../..
srcdir=@srcdir@
-VPATH=.:@srcdir@:@top_srcdir@/idl:$(top_builddir)/idl:${KERNEL_ROOT_DIR}/idl/salome:${MED_ROOT_DIR}/idl/salome
+VPATH=.:@srcdir@:@top_srcdir@/idl:$(top_builddir)/idl
@COMMENCE@
-EXPORT_HEADERS = SMESH_Actor.h \
- SMESH_Grid.h
+EXPORT_HEADERS = SMESH_Actor.h SMESH_Object.h
# Libraries targets
LIB = libSMESHObject.la
-LIB_SRC = SMESH_Actor.cxx \
- SMESH_Grid.cxx
+LIB_SRC = SMESH_Object.cxx SMESH_DeviceActor.cxx SMESH_Actor.cxx
+
+LIB_CLIENT_IDL = SALOME_Exception.idl \
+ SALOME_GenericObj.idl \
+ SMESH_Mesh.idl \
+ SMESH_Filter.idl \
+ SMESH_Group.idl
-LIB_CLIENT_IDL =
# Executables targets
BIN =
BIN_SRC =
-CPPFLAGS+=$(QT_INCLUDES) $(PYTHON_INCLUDES) $(OCC_INCLUDES) $(VTK_INCLUDES) $(OGL_INCLUDES) -I${KERNEL_ROOT_DIR}/include/salome
-LDFLAGS+=$(QT_MT_LIBS) $(OCC_KERNEL_LIBS) $(VTK_LIBS) $(OGL_LIBS) $(PYTHON_LIBS) -lSalomeObject -L${KERNEL_ROOT_DIR}/lib/salome
-
-%_moc.cxx: %.h
- $(MOC) $< -o $@
-
+CPPFLAGS+=$(OCC_INCLUDES) $(VTK_INCLUDES) -I${KERNEL_ROOT_DIR}/include/salome \
+ $(BOOST_CPPFLAGS) $(QT_INCLUDES)
+LDFLAGS+=$(OCC_KERNEL_LIBS) $(VTK_LIBS) -L${KERNEL_ROOT_DIR}/lib/salome -lSMDS \
+ -lSalomeGUI -lSalomeObject -lOpUtil
@CONCLUDE@
// Module : SMESH
// $Header$
-using namespace std;
-/*!
- \class SMESH_Actor SMESH_Actor.h
- \brief ...
-*/
#include "SMESH_Actor.h"
-#include "SMESH_Grid.h"
+#include "SMESH_DeviceActor.h"
+#include "SALOME_ExtractUnstructuredGrid.h"
+
+#include "QAD_Config.h"
#include "utilities.h"
+#include <qstringlist.h>
-// VTK Includes
#include <vtkObjectFactory.h>
-#include <vtkMergePoints.h>
-#include <vtkDataSetMapper.h>
-#include <vtkFeatureEdges.h>
-#include <vtkGeometryFilter.h>
+#include <vtkShrinkPolyData.h>
+#include <vtkMergeFilter.h>
+
+#include <vtkActor2D.h>
+#include <vtkPolyData.h>
+#include <vtkMaskPoints.h>
+#include <vtkCellCenters.h>
+#include <vtkTextProperty.h>
+#include <vtkLabeledDataMapper.h>
+#include <vtkSelectVisiblePoints.h>
+
+#include <vtkScalarBarActor.h>
+#include <vtkLookupTable.h>
+#include <vtkDoubleArray.h>
+
+#ifdef _DEBUG_
+static int MYDEBUG = 1;
+static int MYDEBUGWITHFILES = 0;
+#else
+static int MYDEBUG = 0;
+static int MYDEBUGWITHFILES = 0;
+#endif
-//-------------------------------------------------------------
-// Main methods
-//-------------------------------------------------------------
+using namespace std;
-SMESH_Actor* SMESH_Actor::New()
-{
- // First try to create the object from the vtkObjectFactory
- vtkObject* ret = vtkObjectFactory::CreateInstance("SMESH_Actor");
- if(ret)
- {
- return (SMESH_Actor*)ret;
- }
- // If the factory was unable to create the object, then create it here.
- return new SMESH_Actor;
+
+inline float GetFloat(const QString& theValue, float theDefault = 0){
+ if(theValue.isEmpty()) return theDefault;
+ QString aValue = QAD_CONFIG->getSetting(theValue);
+ if(aValue.isEmpty()) return theDefault;
+ return aValue.toFloat();
}
-SMESH_Actor::SMESH_Actor()
-{
- this->Device = vtkActor::New();
+SMESH_Actor* SMESH_Actor::New(){
+ return new SMESH_Actor();
+}
- this->EdgeDevice = vtkActor::New();
- EdgeDevice->VisibilityOff();
- EdgeDevice->PickableOff();
- this->EdgeShrinkDevice = vtkActor::New();
- EdgeShrinkDevice->VisibilityOff();
- EdgeShrinkDevice->PickableOff();
+SMESH_Actor* SMESH_Actor::New(TVisualObjPtr theVisualObj,
+ SMESH::FilterManager_ptr theFilterMgr,
+ const char* theEntry,
+ const char* theName,
+ int theIsClear)
+{
+ SMESH_Actor* anActor = SMESH_Actor::New();
+ anActor->Init(theVisualObj,theFilterMgr,theEntry,theName,theIsClear);
+ return anActor;
+}
- DataSource = NULL;
- myIO = NULL;
+SMESH_Actor::SMESH_Actor(){
+ if(MYDEBUG) MESSAGE("SMESH_Actor");
+
+ myIsPointsVisible = false;
+
+ myIsShrinkable = false;
+ myIsShrunk = false;
+
+ float aPointSize = GetFloat("SMESH:SettingsNodesSize",3);
+ float aLineWidth = GetFloat("SMESH:SettingsWidth",1);
+
+ vtkMatrix4x4 *aMatrix = vtkMatrix4x4::New();
+ SALOME_ExtractUnstructuredGrid* aFilter = NULL;
+
+ //Definition 2D and 3D divices of the actor
+ //-----------------------------------------
+ float anRGB[3] = {1,1,1};
+ mySurfaceProp = vtkProperty::New();
+ anRGB[0] = GetFloat("SMESH:SettingsFillColorRed", 0)/255.;
+ anRGB[1] = GetFloat("SMESH:SettingsFillColorGreen", 170)/255.;
+ anRGB[2] = GetFloat("SMESH:SettingsFillColorBlue", 255)/255.;
+ mySurfaceProp->SetColor(anRGB[0],anRGB[1],anRGB[2]);
+
+ myBackSurfaceProp = vtkProperty::New();
+ anRGB[0] = GetFloat("SMESH:SettingsBackFaceColorRed", 0)/255.;
+ anRGB[1] = GetFloat("SMESH:SettingsBackFaceColorGreen", 0)/255.;
+ anRGB[2] = GetFloat("SMESH:SettingsBackFaceColorBlue", 255)/255.;
+ myBackSurfaceProp->SetColor(anRGB[0],anRGB[1],anRGB[2]);
+
+ my2DActor = SMESH_DeviceActor::New();
+ my2DActor->SetUserMatrix(aMatrix);
+ my2DActor->SetStoreMapping(true);
+ my2DActor->PickableOff();
+ my2DActor->SetProperty(mySurfaceProp);
+ my2DActor->SetBackfaceProperty(myBackSurfaceProp);
+ my2DActor->SetRepresentation(SMESH_DeviceActor::eSurface);
+ aFilter = my2DActor->GetExtractUnstructuredGrid();
+ aFilter->SetModeOfChanging(SALOME_ExtractUnstructuredGrid::eAdding);
+ aFilter->RegisterCellsWithType(VTK_TRIANGLE);
+ aFilter->RegisterCellsWithType(VTK_POLYGON);
+ aFilter->RegisterCellsWithType(VTK_QUAD);
+
+ my3DActor = SMESH_DeviceActor::New();
+ my3DActor->SetUserMatrix(aMatrix);
+ my3DActor->SetStoreMapping(true);
+ my3DActor->PickableOff();
+ my3DActor->SetProperty(mySurfaceProp);
+ my3DActor->SetBackfaceProperty(myBackSurfaceProp);
+ my3DActor->SetRepresentation(SMESH_DeviceActor::eSurface);
+ aFilter = my3DActor->GetExtractUnstructuredGrid();
+ aFilter->SetModeOfChanging(SALOME_ExtractUnstructuredGrid::eAdding);
+ aFilter->RegisterCellsWithType(VTK_TETRA);
+ aFilter->RegisterCellsWithType(VTK_VOXEL);
+ aFilter->RegisterCellsWithType(VTK_HEXAHEDRON);
+ aFilter->RegisterCellsWithType(VTK_WEDGE);
+ aFilter->RegisterCellsWithType(VTK_PYRAMID);
+
+
+ //Definition 1D divice of the actor
+ //---------------------------------
+ myEdgeProp = vtkProperty::New();
+ myEdgeProp->SetAmbient(1.0);
+ myEdgeProp->SetDiffuse(0.0);
+ myEdgeProp->SetSpecular(0.0);
+ anRGB[0] = GetFloat("SMESH:SettingsOutlineColorRed", 0)/255.;
+ anRGB[1] = GetFloat("SMESH:SettingsOutlineColorGreen", 170)/255.;
+ anRGB[2] = GetFloat("SMESH:SettingsOutlineColorBlue", 255)/255.;
+ myEdgeProp->SetColor(anRGB[0],anRGB[1],anRGB[2]);
+ myEdgeProp->SetLineWidth(aLineWidth);
+
+ my1DActor = SMESH_DeviceActor::New();
+ my1DActor->SetUserMatrix(aMatrix);
+ my1DActor->SetStoreMapping(true);
+ my1DActor->PickableOff();
+ my1DActor->SetProperty(myEdgeProp);
+ my1DActor->SetRepresentation(SMESH_DeviceActor::eSurface);
+ aFilter = my1DActor->GetExtractUnstructuredGrid();
+ aFilter->SetModeOfChanging(SALOME_ExtractUnstructuredGrid::eAdding);
+ aFilter->RegisterCellsWithType(VTK_LINE);
+
+ my1DProp = vtkProperty::New();
+ my1DProp->DeepCopy(myEdgeProp);
+ static int aCotnrolLineWidth = 3;
+ my1DProp->SetLineWidth(aCotnrolLineWidth);
+ my1DProp->SetPointSize(aPointSize);
+
+ my1DExtProp = vtkProperty::New();
+ my1DExtProp->DeepCopy(myEdgeProp);
+ anRGB[0] = 1 - anRGB[0];
+ anRGB[1] = 1 - anRGB[1];
+ anRGB[2] = 1 - anRGB[2];
+ my1DExtProp->SetColor(anRGB[0],anRGB[1],anRGB[2]);
+ my1DExtProp->SetLineWidth(aCotnrolLineWidth);
+
+ my1DExtActor = SMESH_DeviceActor::New();
+ my1DExtActor->SetUserMatrix(aMatrix);
+ my1DExtActor->SetStoreMapping(true);
+ my1DExtActor->PickableOff();
+ my1DExtActor->SetVisibility(false);
+ my1DExtActor->SetProperty(my1DExtProp);
+ my1DExtActor->SetRepresentation(SMESH_DeviceActor::eInsideframe);
+ aFilter = my1DExtActor->GetExtractUnstructuredGrid();
+ aFilter->SetModeOfChanging(SALOME_ExtractUnstructuredGrid::eAdding);
+ aFilter->RegisterCellsWithType(VTK_LINE);
+
+
+ //Definition 0D divice of the actor
+ //---------------------------------
+ myNodeProp = vtkProperty::New();
+ anRGB[0] = GetFloat("SMESH:SettingsNodeColorRed",255)/255.;
+ anRGB[1] = GetFloat("SMESH:SettingsNodeColorGreen",0)/255.;
+ anRGB[2] = GetFloat("SMESH:SettingsNodeColorBlue",0)/255.;
+ myNodeProp->SetColor(anRGB[0],anRGB[1],anRGB[2]);
+ myNodeProp->SetPointSize(aPointSize);
+
+ myNodeActor = SMESH_DeviceActor::New();
+ myNodeActor->SetUserMatrix(aMatrix);
+ myNodeActor->SetStoreMapping(true);
+ myNodeActor->PickableOff();
+ myNodeActor->SetVisibility(false);
+ myNodeActor->SetProperty(myNodeProp);
+ myNodeActor->SetRepresentation(SMESH_DeviceActor::ePoint);
+ aFilter = myNodeActor->GetExtractUnstructuredGrid();
+ aFilter->SetModeOfExtraction(SALOME_ExtractUnstructuredGrid::ePoints);
+
+
+ //Definition of Pickable and Highlitable engines
+ //----------------------------------------------
+
+ myBaseActor = SMESH_DeviceActor::New();
+ myBaseActor->SetUserMatrix(aMatrix);
+ myBaseActor->SetStoreMapping(true);
+ myBaseActor->GetProperty()->SetOpacity(0.0);
+
+ myPickableActor = myBaseActor;
+
+ myHighlightProp = vtkProperty::New();
+ myHighlightProp->SetAmbient(1.0);
+ myHighlightProp->SetDiffuse(0.0);
+ myHighlightProp->SetSpecular(0.0);
+ anRGB[0] = GetFloat("SMESH:SettingsSelectColorRed", 255)/255.; // 1;
+ anRGB[1] = GetFloat("SMESH:SettingsSelectColorGreen", 255)/255.; // 1;
+ anRGB[2] = GetFloat("SMESH:SettingsSelectColorBlue", 255)/255.; // 1;
+ myHighlightProp->SetColor(anRGB[0],anRGB[1],anRGB[2]);
+ myHighlightProp->SetPointSize(aPointSize);
+ myHighlightProp->SetRepresentation(1);
+
+ myPreselectProp = vtkProperty::New();
+ myPreselectProp->SetAmbient(1.0);
+ myPreselectProp->SetDiffuse(0.0);
+ myPreselectProp->SetSpecular(0.0);
+ anRGB[0] = GetFloat("SMESH:SettingsPreSelectColorRed", 0)/255.; // 0;
+ anRGB[1] = GetFloat("SMESH:SettingsPreSelectColorGreen", 255)/255.; // 1;
+ anRGB[2] = GetFloat("SMESH:SettingsPreSelectColorBlue", 255)/255.; // 1;
+ myPreselectProp->SetColor(anRGB[0],anRGB[1],anRGB[2]);
+ myPreselectProp->SetPointSize(aPointSize);
+ myPreselectProp->SetRepresentation(1);
+
+ myHighlitableActor = SMESH_DeviceActor::New();
+ myHighlitableActor->SetUserMatrix(aMatrix);
+ myHighlitableActor->SetStoreMapping(false);
+ myHighlitableActor->PickableOff();
+ myHighlitableActor->SetRepresentation(SMESH_DeviceActor::eWireframe);
+
+
+ SetShrinkFactor(GetFloat("SMESH:SettingsShrinkCoeff", 75)/100.);
+
myName = "";
+ myIO = NULL;
myDisplayMode = 0;
ishighlighted = false;
ispreselected = false;
- edgeColor.r = 0.;
- edgeColor.g = 0.;
- edgeColor.b = 0.;
-
- edgeHighlightColor.r = 1.;
- edgeHighlightColor.g = 1.;
- edgeHighlightColor.b = 1.;
+ myColorMode = eNone;
+ my1DColorMode = e1DNone;
+ myControlActor = my2DActor;
- edgePreselectedColor.r = 0.;
- edgePreselectedColor.g = 1.;
- edgePreselectedColor.b = 1.;
+ //Definition of myScalarBarActor
+ //------------------------------
+ myLookupTable = vtkLookupTable::New();
+ //Fix for Bug PAL5195 - SMESH764:
+ //Controls - Aspect Ratio: incorrect colors of the best and worst values
+ myLookupTable->SetHueRange(0.667,0.0);
- actorColor.r = 1.;
- actorColor.g = 1.;
- actorColor.b = 0.;
+ myScalarBarActor = vtkScalarBarActor::New();
+ myScalarBarActor->SetVisibility(false);
+ myScalarBarActor->SetLookupTable(myLookupTable);
- actorHighlightColor.r = 1.;
- actorHighlightColor.g = 1.;
- actorHighlightColor.b = 1.;
+ vtkTextProperty* aScalarBarTitleProp = vtkTextProperty::New();
- actorPreselectedColor.r = 0.;
- actorPreselectedColor.g = 1.;
- actorPreselectedColor.b = 1.;
+ if ( QAD_CONFIG->hasSetting( "SMESH:ScalarBarTitleColor" ) ) {
+ QStringList aTColor = QStringList::split( ":", QAD_CONFIG->getSetting( "SMESH:ScalarBarTitleColor" ), false );
+ aScalarBarTitleProp->SetColor( ( aTColor.count() > 0 ? aTColor[0].toInt()/255. : 1.0 ),
+ ( aTColor.count() > 1 ? aTColor[1].toInt()/255. : 1.0 ),
+ ( aTColor.count() > 2 ? aTColor[2].toInt()/255. : 1.0 ) );
+ }
+ else
+ aScalarBarTitleProp->SetColor( 1.0, 1.0, 1.0 );
+
+ aScalarBarTitleProp->SetFontFamilyToArial();
+ if( QAD_CONFIG->hasSetting( "SMESH:ScalarBarTitleFont" ) ){
+ if ( QAD_CONFIG->getSetting( "SMESH:ScalarBarTitleFont" ) == "Arial" )
+ aScalarBarTitleProp->SetFontFamilyToArial();
+ else if ( QAD_CONFIG->getSetting( "SMESH:ScalarBarTitleFont" ) == "Courier" )
+ aScalarBarTitleProp->SetFontFamilyToCourier();
+ else if ( QAD_CONFIG->getSetting( "SMESH:ScalarBarTitleFont" ) == "Times" )
+ aScalarBarTitleProp->SetFontFamilyToTimes();
+ }
- actorNodeColor.r = 1.;
- actorNodeColor.g = 1.;
- actorNodeColor.b = 0.;
+ if ( QAD_CONFIG->getSetting( "SMESH:ScalarBarTitleBold" ) == "true" )
+ aScalarBarTitleProp->BoldOn();
+ else
+ aScalarBarTitleProp->BoldOff();
- actorNodeSize = 2 ;
-
-}
+ if ( QAD_CONFIG->getSetting( "SMESH:ScalarBarTitleItalic" ) == "true" )
+ aScalarBarTitleProp->ItalicOn();
+ else
+ aScalarBarTitleProp->ItalicOff();
-SMESH_Actor::~SMESH_Actor()
-{
- this->EdgeDevice->Delete();
- this->EdgeShrinkDevice->Delete();
-}
+ if ( QAD_CONFIG->getSetting( "SMESH:ScalarBarTitleShadow" ) == "true" )
+ aScalarBarTitleProp->ShadowOn();
+ else
+ aScalarBarTitleProp->ShadowOff();
-void SMESH_Actor::setReader(vtkUnstructuredGridReader* r) {
- myReader=r;
-}
+ myScalarBarActor->SetTitleTextProperty( aScalarBarTitleProp );
+ aScalarBarTitleProp->Delete();
+
+ vtkTextProperty* aScalarBarLabelProp = vtkTextProperty::New();
+
+ if ( QAD_CONFIG->hasSetting( "SMESH:ScalarBarLabelColor" ) ) {
+ QStringList aTColor = QStringList::split( ":", QAD_CONFIG->getSetting( "SMESH:ScalarBarLabelColor" ), false );
+ aScalarBarLabelProp->SetColor( ( aTColor.count() > 0 ? aTColor[0].toInt()/255. : 1.0 ),
+ ( aTColor.count() > 1 ? aTColor[1].toInt()/255. : 1.0 ),
+ ( aTColor.count() > 2 ? aTColor[2].toInt()/255. : 1.0 ) );
+ }
+ else
+ aScalarBarLabelProp->SetColor( 1.0, 1.0, 1.0 );
+
+ aScalarBarLabelProp->SetFontFamilyToArial();
+ if( QAD_CONFIG->hasSetting( "SMESH:ScalarBarLabelFont" ) ){
+ if ( QAD_CONFIG->getSetting( "SMESH:ScalarBarLabelFont" ) == "Arial" )
+ aScalarBarLabelProp->SetFontFamilyToArial();
+ else if ( QAD_CONFIG->getSetting( "SMESH:ScalarBarLabelFont" ) == "Courier" )
+ aScalarBarLabelProp->SetFontFamilyToCourier();
+ else if ( QAD_CONFIG->getSetting( "SMESH:ScalarBarLabelFont" ) == "Times" )
+ aScalarBarLabelProp->SetFontFamilyToTimes();
+ }
+
+ if ( QAD_CONFIG->getSetting( "SMESH:ScalarBarLabelBold" ) == "true" )
+ aScalarBarLabelProp->BoldOn();
+ else
+ aScalarBarLabelProp->BoldOff();
+
+ if ( QAD_CONFIG->getSetting( "SMESH:ScalarBarLabelItalic" ) == "true" )
+ aScalarBarLabelProp->ItalicOn();
+ else
+ aScalarBarLabelProp->ItalicOff();
+
+ if ( QAD_CONFIG->getSetting( "SMESH:ScalarBarLabelShadow" ) == "true" )
+ aScalarBarLabelProp->ShadowOn();
+ else
+ aScalarBarLabelProp->ShadowOff();
+
+ myScalarBarActor->SetLabelTextProperty( aScalarBarLabelProp );
+ aScalarBarLabelProp->Delete();
+
+ if ( QAD_CONFIG->getSetting("SMESH:ScalarBarOrientation") == "Horizontal" )
+ myScalarBarActor->SetOrientationToHorizontal();
+ else
+ myScalarBarActor->SetOrientationToVertical();
+
+ float aXVal = QAD_CONFIG->getSetting("SMESH:ScalarBarOrientation") == "Horizontal" ? 0.20 : 0.01;
+ if ( QAD_CONFIG->hasSetting( "SMESH:ScalarBarXPosition" ) )
+ aXVal = QAD_CONFIG->getSetting( "SMESH:ScalarBarXPosition" ).toFloat();
+ float aYVal = QAD_CONFIG->getSetting("SMESH:ScalarBarOrientation") == "Horizontal" ? 0.01 : 0.1;
+ if ( QAD_CONFIG->hasSetting( "SMESH:ScalarBarYPosition" ) )
+ aYVal = QAD_CONFIG->getSetting( "SMESH:ScalarBarYPosition" ).toFloat();
+ myScalarBarActor->SetPosition( aXVal, aYVal );
+
+ float aWVal = QAD_CONFIG->getSetting("SMESH:ScalarBarOrientation") == "Horizontal" ? 0.60 : 0.10;
+ if ( QAD_CONFIG->hasSetting( "SMESH:ScalarBarWidth" ) )
+ aWVal = QAD_CONFIG->getSetting( "SMESH:ScalarBarWidth" ).toFloat();
+ myScalarBarActor->SetWidth( aWVal );
+
+ float aHVal = QAD_CONFIG->getSetting("SMESH:ScalarBarOrientation") == "Horizontal" ? 0.12 : 0.80;
+ if ( QAD_CONFIG->hasSetting( "SMESH:ScalarBarHeight" ) )
+ aHVal = QAD_CONFIG->getSetting( "SMESH:ScalarBarHeight" ).toFloat();
+ myScalarBarActor->SetHeight( aHVal );
+
+ int anIntVal = 5;
+ if ( QAD_CONFIG->hasSetting( "SMESH:ScalarBarNbOfLabels" ) )
+ anIntVal = QAD_CONFIG->getSetting("SMESH:ScalarBarNbOfLabels").toInt();
+ myScalarBarActor->SetNumberOfLabels(anIntVal == 0? 5: anIntVal);
+
+ anIntVal = 64;
+ if ( QAD_CONFIG->hasSetting( "SMESH:ScalarBarNbOfColors" ) )
+ anIntVal = QAD_CONFIG->getSetting("SMESH:ScalarBarNbOfColors").toInt();
+ myScalarBarActor->SetMaximumNumberOfColors(anIntVal == 0? 64: anIntVal);
+
+
+ //Definition of points numbering pipeline
+ //---------------------------------------
+ myPointsNumDataSet = vtkUnstructuredGrid::New();
+
+ myPtsMaskPoints = vtkMaskPoints::New();
+ myPtsMaskPoints->SetInput(myPointsNumDataSet);
+ myPtsMaskPoints->SetOnRatio(1);
+
+ myPtsSelectVisiblePoints = vtkSelectVisiblePoints::New();
+ myPtsSelectVisiblePoints->SetInput(myPtsMaskPoints->GetOutput());
+ myPtsSelectVisiblePoints->SelectInvisibleOff();
+ myPtsSelectVisiblePoints->SetTolerance(0.1);
+
+ myPtsLabeledDataMapper = vtkLabeledDataMapper::New();
+ myPtsLabeledDataMapper->SetInput(myPtsSelectVisiblePoints->GetOutput());
+ myPtsLabeledDataMapper->SetLabelFormat("%g");
+ myPtsLabeledDataMapper->SetLabelModeToLabelScalars();
+
+ vtkTextProperty* aPtsTextProp = vtkTextProperty::New();
+ aPtsTextProp->SetFontFamilyToTimes();
+ static int aPointsFontSize = 10;
+ aPtsTextProp->SetFontSize(aPointsFontSize);
+ aPtsTextProp->SetBold(1);
+ aPtsTextProp->SetItalic(0);
+ aPtsTextProp->SetShadow(0);
+ myPtsLabeledDataMapper->SetLabelTextProperty(aPtsTextProp);
+ aPtsTextProp->Delete();
+
+ myIsPointsLabeled = false;
+
+ myPointLabels = vtkActor2D::New();
+ myPointLabels->SetMapper(myPtsLabeledDataMapper);
+ myPointLabels->GetProperty()->SetColor(1,1,1);
+ myPointLabels->SetVisibility(myIsPointsLabeled);
+
+
+ //Definition of cells numbering pipeline
+ //---------------------------------------
+ myCellsNumDataSet = vtkUnstructuredGrid::New();
+
+ myCellCenters = vtkCellCenters::New();
+ myCellCenters->SetInput(myCellsNumDataSet);
-vtkUnstructuredGridReader* SMESH_Actor::getReader() {
- return (myReader);
+ myClsMaskPoints = vtkMaskPoints::New();
+ myClsMaskPoints->SetInput(myCellCenters->GetOutput());
+ myClsMaskPoints->SetOnRatio(1);
+
+ myClsSelectVisiblePoints = vtkSelectVisiblePoints::New();
+ myClsSelectVisiblePoints->SetInput(myClsMaskPoints->GetOutput());
+ myClsSelectVisiblePoints->SelectInvisibleOff();
+ myClsSelectVisiblePoints->SetTolerance(0.1);
+
+ myClsLabeledDataMapper = vtkLabeledDataMapper::New();
+ myClsLabeledDataMapper->SetInput(myClsSelectVisiblePoints->GetOutput());
+ myClsLabeledDataMapper->SetLabelFormat("%g");
+ myClsLabeledDataMapper->SetLabelModeToLabelScalars();
+
+ vtkTextProperty* aClsTextProp = vtkTextProperty::New();
+ aClsTextProp->SetFontFamilyToTimes();
+ static int aCellsFontSize = 12;
+ aClsTextProp->SetFontSize(aCellsFontSize);
+ aClsTextProp->SetBold(1);
+ aClsTextProp->SetItalic(0);
+ aClsTextProp->SetShadow(0);
+ myClsLabeledDataMapper->SetLabelTextProperty(aClsTextProp);
+ aClsTextProp->Delete();
+
+ myIsCellsLabeled = false;
+
+ myCellsLabels = vtkActor2D::New();
+ myCellsLabels->SetMapper(myClsLabeledDataMapper);
+ myCellsLabels->GetProperty()->SetColor(0,1,0);
+ myCellsLabels->SetVisibility(myIsCellsLabeled);
}
-vtkMapper* SMESH_Actor::getMapper() {
- return (this->Mapper);
+
+SMESH_Actor::~SMESH_Actor(){
+ if(MYDEBUG) MESSAGE("~SMESH_Actor");
+
+ myScalarBarActor->Delete();
+ myLookupTable->Delete();
+
+ mySurfaceProp->Delete();
+ myBackSurfaceProp->Delete();
+
+ myEdgeProp->Delete();
+ myHighlightProp->Delete();
+ myPreselectProp->Delete();
+
+ myNodeProp->Delete();
+
+ my1DProp->Delete();
+ my1DActor->Delete();
+
+ my1DExtProp->Delete();
+ my1DExtActor->Delete();
+
+ my2DActor->Delete();
+ my3DActor->Delete();
+
+ myNodeActor->Delete();
+ myBaseActor->Delete();
+ myHighlitableActor->Delete();
+
+
+ //Deleting of pints numbering pipeline
+ //---------------------------------------
+ myPointsNumDataSet->Delete();
+
+ myPtsLabeledDataMapper->RemoveAllInputs();
+ myPtsLabeledDataMapper->Delete();
+
+ myPtsSelectVisiblePoints->UnRegisterAllOutputs();
+ myPtsSelectVisiblePoints->Delete();
+
+ myPtsMaskPoints->UnRegisterAllOutputs();
+ myPtsMaskPoints->Delete();
+
+ myPointLabels->Delete();
+
+
+ //Deleting of cells numbering pipeline
+ //---------------------------------------
+ myCellsNumDataSet->Delete();
+
+ myClsLabeledDataMapper->RemoveAllInputs();
+ myClsLabeledDataMapper->Delete();
+
+ myClsSelectVisiblePoints->UnRegisterAllOutputs();
+ myClsSelectVisiblePoints->Delete();
+
+ myClsMaskPoints->UnRegisterAllOutputs();
+ myClsMaskPoints->Delete();
+
+ myCellCenters->UnRegisterAllOutputs();
+ myCellCenters->Delete();
+
+ myCellsLabels->Delete();
}
-void SMESH_Actor::ShallowCopy(vtkProp *prop)
+
+void SMESH_Actor::SetPointsLabeled( bool theIsPointsLabeled )
{
- SMESH_Actor *f = SMESH_Actor::SafeDownCast(prop);
- if ( f != NULL )
+ myIsPointsLabeled = theIsPointsLabeled;
+
+ if ( myIsPointsLabeled )
+ {
+ myPointsNumDataSet->ShallowCopy( GetUnstructuredGrid() );
+ vtkDataSet *aDataSet = myPointsNumDataSet;
+
+ int aNbElem = aDataSet->GetNumberOfPoints();
+
+ vtkIntArray *anArray = vtkIntArray::New();
+ anArray->SetNumberOfValues( aNbElem );
+
+ for ( int anId = 0; anId < aNbElem; anId++ )
{
- this->setName( f->getName() );
- if ( f->hasIO() )
- this->setIO( f->getIO() );
- this->setDisplayMode( f->getDisplayMode() );
-
- // Copy devices
- vtkActor* tempDev = vtkActor::New();
- tempDev->ShallowCopy(f->Device);
- vtkProperty* prp = vtkProperty::New();
- prp->DeepCopy(f->Device->GetProperty());
- tempDev->SetProperty(prp);
- prp = vtkProperty::New();
- prp->DeepCopy(f->Device->GetBackfaceProperty());
- tempDev->SetBackfaceProperty(prp);
- this->Device = tempDev;
-
- tempDev = vtkActor::New();
- tempDev->ShallowCopy(f->EdgeDevice);
- prp = vtkProperty::New();
- prp->DeepCopy(f->EdgeDevice->GetProperty());
- tempDev->SetProperty(prp);
- prp = vtkProperty::New();
- prp->DeepCopy(f->EdgeDevice->GetBackfaceProperty());
- tempDev->SetBackfaceProperty(prp);
- this->EdgeDevice = tempDev;
-
- tempDev = vtkActor::New();
- tempDev->ShallowCopy(f->EdgeShrinkDevice);
- prp = vtkProperty::New();
- prp->DeepCopy(f->EdgeShrinkDevice->GetProperty());
- tempDev->SetProperty(prp);
- prp = vtkProperty::New();
- prp->DeepCopy(f->EdgeShrinkDevice->GetBackfaceProperty());
- tempDev->SetBackfaceProperty(prp);
- this->EdgeShrinkDevice = tempDev;
-
- // Copy data source
- this->DataSource = f->DataSource;
-
- this->myReader = f->myReader;
+ int aSMDSId = myVisualObj->GetNodeObjId( anId );
+ anArray->SetValue( anId, aSMDSId );
}
-
- // Now do superclass
- this->SALOME_Actor::ShallowCopy(prop);
-
- // Here we need to modify default ShallowCopy() results
- // Create copies of properties
- if ( f != NULL ) {
- vtkProperty* prp = vtkProperty::New();
- prp->DeepCopy(f->GetProperty());
- this->SetProperty(prp);
-
- prp = vtkProperty::New();
- prp->DeepCopy(f->GetBackfaceProperty());
- this->SetBackfaceProperty(prp);
-
- // Copy the mapper
- vtkDataSetMapper* mpr = vtkDataSetMapper::New();
- mpr->ShallowCopy(f->GetMapper());
- mpr->SetInput(f->DataSource);
- this->SetMapper(mpr);
+
+ aDataSet->GetPointData()->SetScalars( anArray );
+ anArray->Delete();
+ myPtsMaskPoints->SetInput( aDataSet );
+ myPointLabels->SetVisibility( GetVisibility() );
}
-}
-
-void SMESH_Actor::Render(vtkRenderer *ren, vtkMapper *Mapper )
-{
- if (this->Mapper == NULL) {
- MESSAGE ("No mapper for actor.")
- return;
+ else
+ {
+ myPointLabels->SetVisibility( false );
}
+
+ SetRepresentation( GetRepresentation() );
+}
- if ( myDisplayMode == 1 ) {
- EdgeDevice->VisibilityOn();
- EdgeShrinkDevice->VisibilityOff();
- } else if ( myDisplayMode == 2 ) {
- EdgeShrinkDevice->VisibilityOn();
- EdgeDevice->VisibilityOff();
- } else {
- EdgeShrinkDevice->VisibilityOff();
- EdgeDevice->VisibilityOff();
- }
-
-
- vtkMapper *bestMapper;
- bestMapper = this->Mapper;
-
- /* render the property */
- if (!this->Property) {
- // force creation of a property
- this->GetProperty();
- }
- if ( ishighlighted ) {
- if ( myDisplayMode == 1 ) {
- EdgeDevice->GetProperty()->SetColor(edgeHighlightColor.r,edgeHighlightColor.g,edgeHighlightColor.b);
- this->GetProperty()->SetColor(actorColor.r,actorColor.g,actorColor.b);
- } else if ( myDisplayMode == 2 ) {
- EdgeShrinkDevice->GetProperty()->SetColor(edgeHighlightColor.r,edgeHighlightColor.g,edgeHighlightColor.b);
- } else {
- this->GetProperty()->SetColor(actorHighlightColor.r,actorHighlightColor.g,actorHighlightColor.b);
- }
- } else if (! ispreselected ) {
- if ( myDisplayMode == 1 ) {
- EdgeDevice->GetProperty()->SetColor(edgeColor.r,edgeColor.g,edgeColor.b);
- this->GetProperty()->SetColor(actorColor.r,actorColor.g,actorColor.b);
+void SMESH_Actor::SetCellsLabeled(bool theIsCellsLabeled){
+ myIsCellsLabeled = theIsCellsLabeled;
+ if(myIsCellsLabeled){
+ myCellsNumDataSet->ShallowCopy(GetUnstructuredGrid());
+ vtkDataSet *aDataSet = myCellsNumDataSet;
+ int aNbElem = aDataSet->GetNumberOfCells();
+ vtkIntArray *anArray = vtkIntArray::New();
+ anArray->SetNumberOfValues(aNbElem);
+ for(int anId = 0; anId < aNbElem; anId++){
+ int aSMDSId = myVisualObj->GetElemObjId(anId);
+ anArray->SetValue(anId,aSMDSId);
}
- else if ( myDisplayMode == 2 )
- EdgeShrinkDevice->GetProperty()->SetColor(edgeColor.r,edgeColor.g,edgeColor.b);
- else
- this->GetProperty()->SetColor(actorColor.r,actorColor.g,actorColor.b);
- }
- else {
- if ( myDisplayMode == 1 )
- EdgeDevice->GetProperty()->SetColor(edgePreselectedColor.r,edgePreselectedColor.g,edgePreselectedColor.b);
- else if ( myDisplayMode == 2 )
- EdgeShrinkDevice->GetProperty()->SetColor(edgePreselectedColor.r,edgePreselectedColor.g,edgePreselectedColor.b);
- else
- this->GetProperty()->SetColor(actorPreselectedColor.r,actorPreselectedColor.g,actorPreselectedColor.b);
+ aDataSet->GetCellData()->SetScalars(anArray);
+ myCellCenters->SetInput(aDataSet);
+ myCellsLabels->SetVisibility(GetVisibility());
+ }else{
+ myCellsLabels->SetVisibility(false);
}
+}
- this->Property->Render(this, ren);
- if (this->BackfaceProperty) {
- this->BackfaceProperty->BackfaceRender(this, ren);
- this->Device->SetBackfaceProperty(this->BackfaceProperty);
- }
- this->Device->SetProperty(this->Property);
-
- /* render the texture */
- if (this->Texture) {
- this->Texture->Render(ren);
+
+void SMESH_Actor::SetControlMode(eControl theMode){
+ myColorMode = eNone;
+ my1DColorMode = e1DNone;
+
+ my1DActor->GetMapper()->SetScalarVisibility(false);
+ my2DActor->GetMapper()->SetScalarVisibility(false);
+ my3DActor->GetMapper()->SetScalarVisibility(false);
+ myScalarBarActor->SetVisibility(false);
+
+ bool anIsScalarVisible = theMode > eNone;
+
+ if(anIsScalarVisible){
+ SMESH::NumericalFunctor_var aFunctor;
+ SMESH::Predicate_var aPredicate;
+
+ switch(theMode){
+ case eLengthEdges:
+ aFunctor = myFilterMgr->CreateLength();
+ myControlActor = my1DActor;
+ break;
+ case eFreeBorders:
+ aPredicate = myFilterMgr->CreateFreeBorders();
+ myControlActor = my1DActor;
+ break;
+ case eMultiConnection:
+ aFunctor = myFilterMgr->CreateMultiConnection();
+ myControlActor = my1DActor;
+ break;
+ case eArea:
+ aFunctor = myFilterMgr->CreateArea();
+ myControlActor = my2DActor;
+ break;
+ case eTaper:
+ aFunctor = myFilterMgr->CreateTaper();
+ myControlActor = my2DActor;
+ break;
+ case eAspectRatio:
+ aFunctor = myFilterMgr->CreateAspectRatio();
+ myControlActor = my2DActor;
+ break;
+ case eMinimumAngle:
+ aFunctor = myFilterMgr->CreateMinimumAngle();
+ myControlActor = my2DActor;
+ break;
+ case eWarping:
+ aFunctor = myFilterMgr->CreateWarping();
+ myControlActor = my2DActor;
+ break;
+ case eSkew:
+ aFunctor = myFilterMgr->CreateSkew();
+ myControlActor = my2DActor;
+ break;
+ default:
+ return;
+ }
+
+ vtkUnstructuredGrid* aGrid = myControlActor->GetUnstructuredGrid();
+ vtkIdType aNbCells = aGrid->GetNumberOfCells();
+ if(aNbCells){
+ if(theMode == eFreeBorders){
+ if(!aPredicate->_is_nil()){
+ myVisualObj->UpdateFunctor(aPredicate);
+ SALOME_ExtractUnstructuredGrid* aFilter =
+ my1DExtActor->GetExtractUnstructuredGrid();
+ aFilter->SetModeOfChanging(SALOME_ExtractUnstructuredGrid::eAdding);
+ aFilter->ClearRegisteredCells();
+ for( vtkIdType i = 0; i < aNbCells; i++ ){
+ vtkIdType anObjId = myControlActor->GetElemObjId( i );
+ CORBA::Boolean aValue = aPredicate->IsSatisfy(anObjId);
+ if(aValue)
+ aFilter->RegisterCell(i);
+ }
+ if(!aFilter->IsCellsRegistered())
+ aFilter->RegisterCell(-1);
+ aPredicate->Destroy();
+ }
+ myColorMode = theMode;
+ my1DColorMode = e1DHighlited;
+ }else{
+ myColorMode = theMode;
+ if(myControlActor == my1DActor)
+ my1DColorMode = e1DColored;
+
+ vtkUnstructuredGrid* aDataSet = vtkUnstructuredGrid::New();
+ aDataSet->ShallowCopy(aGrid);
+ myScalarBarActor->SetVisibility(true);
+ myControlActor->GetMapper()->SetScalarVisibility(true);
+
+ vtkDoubleArray *aScalars = vtkDoubleArray::New();
+ aScalars->SetNumberOfComponents( 1 );
+ aScalars->SetNumberOfTuples(aNbCells);
+
+ if(!aFunctor->_is_nil()){
+ myVisualObj->UpdateFunctor(aFunctor);
+ for( vtkIdType i = 0; i < aNbCells; i++ ){
+ vtkIdType anObjId = myControlActor->GetElemObjId( i );
+ CORBA::Double aValue = aFunctor->GetValue(anObjId);
+ aScalars->SetValue( i, aValue );
+ }
+ aFunctor->Destroy();
+ }else if(!aPredicate->_is_nil()){
+ myVisualObj->UpdateFunctor(aPredicate);
+ for( vtkIdType i = 0; i < aNbCells; i++ ){
+ vtkIdType anObjId = myControlActor->GetElemObjId( i );
+ CORBA::Boolean aValue = aPredicate->IsSatisfy(anObjId);
+ aScalars->SetValue( i, aValue );
+ }
+ aPredicate->Destroy();
+ }
+ aDataSet->GetCellData()->SetScalars(aScalars);
+ aScalars->Delete();
+
+ float aRange[2];
+ aScalars->GetRange(aRange);
+ myLookupTable->SetRange(aRange);
+ myLookupTable->Build();
+
+ myControlActor->GetMergeFilter()->SetScalars(aDataSet);
+ aDataSet->Delete();
+ if(MYDEBUGWITHFILES)
+ WriteUnstructuredGrid(aDataSet,"/tmp/SetControlMode.vtk");
+ }
+ }
}
+ SetRepresentation(GetRepresentation());
-
- // Store information on time it takes to render.
- // We might want to estimate time from the number of polygons in mapper.
- this->Device->Render(ren,bestMapper);
- this->EstimatedRenderTime = bestMapper->GetTimeToDraw();
+ Modified();
}
-int SMESH_Actor::RenderOpaqueGeometry(vtkViewport *vp)
+
+void SMESH_Actor::AddToRender(vtkRenderer* theRenderer){
+ SALOME_Actor::AddToRender(theRenderer);
+
+ theRenderer->AddActor(myNodeActor);
+ theRenderer->AddActor(myBaseActor);
+
+ theRenderer->AddActor(my3DActor);
+ theRenderer->AddActor(my2DActor);
+
+ theRenderer->AddActor(my1DActor);
+ theRenderer->AddActor(my1DExtActor);
+
+ theRenderer->AddActor(myHighlitableActor);
+
+ theRenderer->AddActor2D(myScalarBarActor);
+
+ myPtsSelectVisiblePoints->SetRenderer(theRenderer);
+ myClsSelectVisiblePoints->SetRenderer(theRenderer);
+
+ theRenderer->AddActor2D(myPointLabels);
+ theRenderer->AddActor2D(myCellsLabels);
+}
+
+void SMESH_Actor::RemoveFromRender(vtkRenderer* theRenderer){
+ SALOME_Actor::RemoveFromRender(theRenderer);
+
+ theRenderer->RemoveActor(myNodeActor);
+ theRenderer->RemoveActor(myBaseActor);
+ theRenderer->RemoveActor(myHighlitableActor);
+
+ theRenderer->RemoveActor(my1DActor);
+ theRenderer->RemoveActor(my1DExtActor);
+
+ theRenderer->RemoveActor(my2DActor);
+ theRenderer->RemoveActor(my3DActor);
+
+ theRenderer->RemoveActor(myScalarBarActor);
+ theRenderer->RemoveActor(myPointLabels);
+ theRenderer->RemoveActor(myCellsLabels);
+}
+
+
+void SMESH_Actor::Init(TVisualObjPtr theVisualObj,
+ SMESH::FilterManager_ptr theFilterMgr,
+ const char* theEntry,
+ const char* theName,
+ int theIsClear)
{
- int renderedSomething = 0;
- vtkRenderer *ren = (vtkRenderer *)vp;
-
- if ( ! this->Mapper ) {
- return 0;
- }
-
- // make sure we have a property
- if (!this->Property) {
- // force creation of a property
- this->GetProperty();
- }
+ Handle(SALOME_InteractiveObject) anIO =
+ new SALOME_InteractiveObject(strdup(theEntry),strdup("MESH"),strdup(theName));
+ setIO(anIO);
+ setName(strdup(theName));
+
+ myVisualObj = theVisualObj;
+ myNodeActor->myVisualObj = myVisualObj;
+ myBaseActor->myVisualObj = myVisualObj;
+ myHighlitableActor->myVisualObj = myVisualObj;
+
+ my1DActor->myVisualObj = myVisualObj;
+ my1DExtActor->myVisualObj = myVisualObj;
+
+ my2DActor->myVisualObj = myVisualObj;
+ my3DActor->myVisualObj = myVisualObj;
+
+ myVisualObj->Update(theIsClear);
+ SetUnstructuredGrid(myVisualObj->GetUnstructuredGrid());
- if ( ishighlighted ) {
- if ( myDisplayMode == 1 ) {
- EdgeDevice->GetProperty()->SetColor(edgeHighlightColor.r,edgeHighlightColor.g,edgeHighlightColor.b);
- } else if ( myDisplayMode == 2 ) {
- EdgeShrinkDevice->GetProperty()->SetColor(edgeHighlightColor.r,edgeHighlightColor.g,edgeHighlightColor.b);
- } else {
- this->GetProperty()->SetColor(actorHighlightColor.r,actorHighlightColor.g,actorHighlightColor.b);
- }
- } else if (! ispreselected ) {
- if ( myDisplayMode == 1 )
- EdgeDevice->GetProperty()->SetColor(edgeColor.r,edgeColor.g,edgeColor.b);
- else if ( myDisplayMode == 2 )
- EdgeShrinkDevice->GetProperty()->SetColor(edgeColor.r,edgeColor.g,edgeColor.b);
- else
- this->GetProperty()->SetColor(actorColor.r,actorColor.g,actorColor.b);
+ myFilterMgr = SMESH::FilterManager::_duplicate(theFilterMgr);
+
+ QString aMode = QAD_CONFIG->getSetting("SMESH:DisplayMode");
+ SetRepresentation(-1);
+ if(aMode.compare("Wireframe") == 0){
+ SetRepresentation(eEdge);
+ }else if(aMode.compare("Shading") == 0){
+ SetRepresentation(eSurface);
+ }else if(aMode.compare("Nodes") == 0){
+ SetRepresentation(ePoint);
}
- else {
- if ( myDisplayMode == 1 )
- EdgeDevice->GetProperty()->SetColor(edgePreselectedColor.r,edgePreselectedColor.g,edgePreselectedColor.b);
- else if ( myDisplayMode == 2 )
- EdgeShrinkDevice->GetProperty()->SetColor(edgePreselectedColor.r,edgePreselectedColor.g,edgePreselectedColor.b);
- else
- this->GetProperty()->SetColor(actorPreselectedColor.r,actorPreselectedColor.g,actorPreselectedColor.b);
+
+ aMode = QAD_CONFIG->getSetting("SMESH:Shrink");
+ if(aMode == "yes"){
+ SetShrink();
}
- // is this actor opaque ?
- if (this->GetIsOpaque()) {
- this->Property->Render(this, ren);
-
- // render the backface property
- if (this->BackfaceProperty) {
- this->BackfaceProperty->BackfaceRender(this, ren);
- }
-
- // render the texture
- if (this->Texture) {
- this->Texture->Render(ren);
- }
- this->Render(ren,this->Mapper);
+ Modified();
+}
+
+
+vtkPolyData* SMESH_Actor::GetPolyDataInput(){
+ return myPickableActor->GetPolyDataInput();
+}
+
+
+void SMESH_Actor::SetTransform(SALOME_Transform* theTransform){
+ myNodeActor->SetTransform(theTransform);
+ myBaseActor->SetTransform(theTransform);
+ myHighlitableActor->SetTransform(theTransform);
+
+ my1DActor->SetTransform(theTransform);
+ my1DExtActor->SetTransform(theTransform);
+
+ my2DActor->SetTransform(theTransform);
+ my3DActor->SetTransform(theTransform);
+
+ Modified();
+}
+
+
+void SMESH_Actor::SetUnstructuredGrid(vtkUnstructuredGrid* theGrid){
+ if(theGrid){
+ myNodeActor->SetUnstructuredGrid(theGrid);
+ myBaseActor->SetUnstructuredGrid(theGrid);
+ myHighlitableActor->SetUnstructuredGrid(theGrid);
+
+ my1DActor->SetUnstructuredGrid(theGrid);
+ my1DExtActor->SetUnstructuredGrid(theGrid);
+
+ my2DActor->SetUnstructuredGrid(theGrid);
+ my3DActor->SetUnstructuredGrid(theGrid);
+
+ my1DActor->GetMapper()->SetLookupTable(myLookupTable);
+ my2DActor->GetMapper()->SetLookupTable(myLookupTable);
+ my3DActor->GetMapper()->SetLookupTable(myLookupTable);
- renderedSomething = 1;
+ float aFactor, aUnits;
+ my2DActor->GetPolygonOffsetParameters(aFactor,aUnits);
+ my2DActor->SetPolygonOffsetParameters(aFactor,aUnits*0.75);
+
+ //SetIsShrunkable(theGrid->GetNumberOfCells() > 10);
+ SetIsShrunkable(true);
+
+ Modified();
}
-
- return renderedSomething;
}
-void SMESH_Actor::SetColor(float r,float g,float b)
-{
- actorColor.r = r;
- actorColor.g = g;
- actorColor.b = b;
+void SMESH_Actor::SetMapper(vtkMapper* theMapper){
+ vtkLODActor::SetMapper(theMapper);
}
-void SMESH_Actor::GetColor(float& r,float& g,float& b)
-{
- r = actorColor.r;
- g = actorColor.g;
- b = actorColor.b;
+
+void SMESH_Actor::ShallowCopy(vtkProp *prop){
+ SALOME_Actor::ShallowCopy(prop);
}
-void SMESH_Actor::SetPreselectedColor(float r,float g,float b)
-{
- actorPreselectedColor.r = r;
- actorPreselectedColor.g = g;
- actorPreselectedColor.b = b;
+
+vtkMapper* SMESH_Actor::GetMapper(){
+ return myPickableActor->GetMapper();
}
-void SMESH_Actor::GetPreselectedColor(float& r,float& g,float& b)
-{
- r = actorPreselectedColor.r;
- g = actorPreselectedColor.g;
- b = actorPreselectedColor.b;
+
+vtkUnstructuredGrid* SMESH_Actor::GetUnstructuredGrid(){
+ return myVisualObj->GetUnstructuredGrid();
}
-void SMESH_Actor::SetHighlightColor(float r,float g,float b)
-{
- actorHighlightColor.r = r;
- actorHighlightColor.g = g;
- actorHighlightColor.b = b;
+
+bool SMESH_Actor::IsInfinitive(){
+ vtkDataSet *aDataSet = myPickableActor->GetUnstructuredGrid();
+ aDataSet->Update();
+ myIsInfinite = aDataSet->GetNumberOfCells() == 0;
+ return SALOME_Actor::IsInfinitive();
}
-void SMESH_Actor::GetHighlightColor(float& r,float& g,float& b)
-{
- r = actorHighlightColor.r;
- g = actorHighlightColor.g;
- b = actorHighlightColor.b;
+
+void SMESH_Actor::SetIsShrunkable(bool theShrunkable){
+ myIsShrinkable = theShrunkable;
+ Modified();
}
-void SMESH_Actor::SetEdgeColor(float r,float g,float b)
-{
- edgeColor.r = r;
- edgeColor.g = g;
- edgeColor.b = b;
+float SMESH_Actor::GetShrinkFactor(){
+ return myBaseActor->GetShrinkFactor();
}
-void SMESH_Actor::GetEdgeColor(float& r,float& g,float& b)
-{
- r = edgeColor.r;
- g = edgeColor.g;
- b = edgeColor.b;
+void SMESH_Actor::SetShrinkFactor(float theValue){
+ myBaseActor->SetShrinkFactor(theValue);
+
+ my1DActor->SetShrinkFactor(theValue);
+ my1DExtActor->SetShrinkFactor(theValue);
+
+ my2DActor->SetShrinkFactor(theValue);
+ my3DActor->SetShrinkFactor(theValue);
+
+ Modified();
}
-void SMESH_Actor::SetEdgeHighlightColor(float r,float g,float b)
-{
- edgeHighlightColor.r = r;
- edgeHighlightColor.g = g;
- edgeHighlightColor.b = b;
+void SMESH_Actor::SetShrink(){
+ if(!myIsShrinkable) return;
+
+ myBaseActor->SetShrink();
+
+ my1DActor->SetShrink();
+ my1DExtActor->SetShrink();
+
+ my2DActor->SetShrink();
+ my3DActor->SetShrink();
+
+ myIsShrunk = true;
+ Modified();
}
-void SMESH_Actor::GetEdgeHighlightColor(float& r,float& g,float& b)
-{
- r = edgeHighlightColor.r;
- g = edgeHighlightColor.g;
- b = edgeHighlightColor.b;
+void SMESH_Actor::UnShrink(){
+ if(!myIsShrunk) return;
+
+ myBaseActor->UnShrink();
+
+ my1DActor->UnShrink();
+ my1DExtActor->UnShrink();
+
+ my2DActor->UnShrink();
+ my3DActor->UnShrink();
+
+ myIsShrunk = false;
+ Modified();
}
-void SMESH_Actor::SetEdgePreselectedColor(float r,float g,float b)
-{
- edgePreselectedColor.r = r;
- edgePreselectedColor.g = g;
- edgePreselectedColor.b = b;
+
+int SMESH_Actor::GetObjId(int theVtkID){
+ if (GetRepresentation() == 0){
+ return GetNodeObjId(theVtkID);
+ }else{
+ return GetElemObjId(theVtkID);
+ }
}
-void SMESH_Actor::GetEdgePreselectedColor(float& r,float& g,float& b)
-{
- r = edgePreselectedColor.r;
- g = edgePreselectedColor.g;
- b = edgePreselectedColor.b;
+SALOME_Actor::TVectorId SMESH_Actor::GetVtkId(int theObjID){
+ if (GetRepresentation() == 0){
+ return GetNodeVtkId(theObjID);
+ }else{
+ return GetElemVtkId(theObjID);
+ }
}
-void SMESH_Actor::SetNodeColor(float r,float g,float b)
-{
- actorNodeColor.r = r ;
- actorNodeColor.g = g ;
- actorNodeColor.b = b ;
+int SMESH_Actor::GetNodeObjId(int theVtkID){
+ return myPickableActor->GetNodeObjId(theVtkID);
}
-void SMESH_Actor::GetNodeColor(float& r,float& g,float& b)
-{
- r = actorNodeColor.r ;
- g = actorNodeColor.g ;
- b = actorNodeColor.b ;
+SALOME_Actor::TVectorId SMESH_Actor::GetNodeVtkId(int theObjID){
+ return myPickableActor->GetNodeVtkId(theObjID);
}
-void SMESH_Actor::SetNodeSize(int size)
-{
- actorNodeSize = size ;
+
+int SMESH_Actor::GetElemObjId(int theVtkID){
+ return myPickableActor->GetElemObjId(theVtkID);
}
-int SMESH_Actor::GetNodeSize()
-{
- return actorNodeSize ;
+SALOME_Actor::TVectorId SMESH_Actor::GetElemVtkId(int theObjID){
+ return myPickableActor->GetElemVtkId(theObjID);
}
-void SMESH_Actor::AddNode(int idSMESHDSnode,int idVTKnode)
-{
- if (DataSource->IsA("SMESH_Grid")) {
- ((SMESH_Grid*)DataSource)->AddNode(idSMESHDSnode, idVTKnode);
- } else
- MESSAGE("AddNode() method has been moved to SMESH_Grid class");
+void SMESH_Actor::SetVisibility(int theMode){
+ SALOME_Actor::SetVisibility(theMode);
+ if(GetVisibility()){
+ SetRepresentation(GetRepresentation());
+
+ if(myColorMode != eNone){
+ if(my1DColorMode == e1DHighlited)
+ my1DExtActor->VisibilityOn();
+ else if(myControlActor->GetUnstructuredGrid()->GetNumberOfCells())
+ myScalarBarActor->VisibilityOn();
+ }
+
+ if(myRepresentation != ePoint)
+ myPickableActor->VisibilityOn();
+
+ my1DActor->VisibilityOn();
+
+ my2DActor->VisibilityOn();
+ my3DActor->VisibilityOn();
+
+ if(myIsPointsLabeled) myPointLabels->VisibilityOn();
+ if(myIsCellsLabeled) myCellsLabels->VisibilityOn();
+ }else{
+ myNodeActor->VisibilityOff();
+ myBaseActor->VisibilityOff();
+
+ my1DActor->VisibilityOff();
+ my1DExtActor->VisibilityOff();
+
+ my2DActor->VisibilityOff();
+ my3DActor->VisibilityOff();
+
+ myScalarBarActor->VisibilityOff();
+ myPointLabels->VisibilityOff();
+ myCellsLabels->VisibilityOff();
+ }
+ Modified();
}
-void SMESH_Actor::AddElement(int idSMESHDSelement, int idVTKelement)
-{
- if (DataSource->IsA("SMESH_Grid")) {
- ((SMESH_Grid*)DataSource)->AddElement(idSMESHDSelement, idVTKelement);
- } else
- MESSAGE("AddElement() method has been moved to SMESH_Grid class");
+
+
+void SMESH_Actor::SetRepresentation(int theMode){
+ int aNbEdges = myVisualObj->GetNbEntities(SMESH::EDGE);
+ int aNbFaces = myVisualObj->GetNbEntities(SMESH::FACE);
+ int aNbVolumes = myVisualObj->GetNbEntities(SMESH::VOLUME);
+ if(theMode < 0){
+ myRepresentation = eSurface;
+ if(!aNbFaces && !aNbVolumes && aNbEdges){
+ myRepresentation = eEdge;
+ }else if(!aNbFaces && !aNbVolumes && !aNbEdges){
+ myRepresentation = ePoint;
+ }
+ }else{
+ switch(theMode){
+ case eEdge:
+ if(!aNbFaces && !aNbVolumes && !aNbEdges) return;
+ break;
+ case eSurface:
+ if(!aNbFaces && !aNbVolumes) return;
+ break;
+ }
+ myRepresentation = theMode;
+ }
+
+ if(!GetUnstructuredGrid()->GetNumberOfCells())
+ myRepresentation = ePoint;
+
+ if(myIsShrunk){
+ if(myRepresentation == ePoint){
+ UnShrink();
+ myIsShrunk = true;
+ }else{
+ SetShrink();
+ }
+ }
+
+ myPickableActor = myBaseActor;
+ myNodeActor->SetVisibility(false);
+ vtkProperty *aProp = NULL, *aBackProp = NULL;
+ SMESH_DeviceActor::EReperesent aReperesent = SMESH_DeviceActor::EReperesent(-1);
+ switch(myRepresentation){
+ case ePoint:
+ myPickableActor = myNodeActor;
+ aProp = aBackProp = myNodeProp;
+ aReperesent = SMESH_DeviceActor::ePoint;
+ break;
+ case eEdge:
+ aProp = aBackProp = myEdgeProp;
+ aReperesent = SMESH_DeviceActor::eInsideframe;
+ break;
+ case eSurface:
+ aProp = mySurfaceProp;
+ aBackProp = myBackSurfaceProp;
+ aReperesent = SMESH_DeviceActor::eSurface;
+ break;
+ }
+
+ my2DActor->SetProperty(aProp);
+ my2DActor->SetBackfaceProperty(aBackProp);
+ my2DActor->SetRepresentation(aReperesent);
+
+ my3DActor->SetProperty(aProp);
+ my3DActor->SetBackfaceProperty(aBackProp);
+ my3DActor->SetRepresentation(aReperesent);
+
+ my1DExtActor->SetVisibility(false);
+ switch(my1DColorMode){
+ case e1DColored:
+ aProp = aBackProp = my1DProp;
+ if(myRepresentation != ePoint)
+ aReperesent = SMESH_DeviceActor::eInsideframe;
+ break;
+ case e1DHighlited:
+ my1DExtActor->SetVisibility(true);
+ break;
+ }
+
+ my1DActor->SetProperty(aProp);
+ my1DActor->SetBackfaceProperty(aBackProp);
+ my1DActor->SetRepresentation(aReperesent);
+
+ if ( GetPointRepresentation() || !GetUnstructuredGrid()->GetNumberOfCells() || myIsPointsLabeled )
+ {
+ myPickableActor = myNodeActor;
+ myNodeActor->SetVisibility(true);
+ }
+
+ SetMapper(myPickableActor->GetMapper());
+
+ Modified();
}
-void SMESH_Actor::SetIdsVTKNode(const TColStd_DataMapOfIntegerInteger& mapVTK)
-{
- if (DataSource->IsA("SMESH_Grid")) {
- ((SMESH_Grid*)DataSource)->SetIdsVTKNode(mapVTK);
- } else
- MESSAGE("SetIdsVTKNode() method has been moved to SMESH_Grid class");
+
+void SMESH_Actor::SetPointRepresentation(int theIsPointsVisible){
+ myIsPointsVisible = theIsPointsVisible;
+ SetRepresentation(GetRepresentation());
}
-void SMESH_Actor::SetIdsSMESHDSNode(const TColStd_DataMapOfIntegerInteger& mapSMESHDS)
-{
- if (DataSource->IsA("SMESH_Grid")) {
- ((SMESH_Grid*)DataSource)->SetIdsSMESHDSNode(mapSMESHDS);
- } else
- MESSAGE("SetIdsSMESHDSNode() method has been moved to SMESH_Grid class");
+
+
+void SMESH_Actor::UpdateHighlight(){
+ myHighlitableActor->SetVisibility(false);
+ myNodeActor->SetProperty(myNodeProp);
+ if(myPickableActor != myNodeActor)
+ myNodeActor->SetVisibility(false);
+
+ if(ishighlighted){
+ myHighlitableActor->SetProperty(myHighlightProp);
+ }else if(ispreselected){
+ myHighlitableActor->SetProperty(myPreselectProp);
+ }
+
+ if(ishighlighted || ispreselected){
+ if(!GetUnstructuredGrid()->GetNumberOfCells()){
+ myNodeActor->SetProperty(myHighlitableActor->GetProperty());
+ myNodeActor->SetRepresentation(SMESH_DeviceActor::ePoint);
+ myNodeActor->SetVisibility(GetVisibility());
+ }else{
+ myHighlitableActor->SetRepresentation(SMESH_DeviceActor::eWireframe);
+ myHighlitableActor->SetVisibility(GetVisibility());
+ }
+ }
}
-void SMESH_Actor::SetIdsVTKElement(const TColStd_DataMapOfIntegerInteger& mapVTK)
-{
- if (DataSource->IsA("SMESH_Grid")) {
- ((SMESH_Grid*)DataSource)->SetIdsVTKElement(mapVTK);
- } else
- MESSAGE("SetIdsVTKElement() method has been moved to SMESH_Grid class");
+
+void SMESH_Actor::highlight(Standard_Boolean highlight){
+ ishighlighted = highlight;
+ UpdateHighlight();
}
-void SMESH_Actor::SetIdsSMESHDSElement(const TColStd_DataMapOfIntegerInteger& mapSMESHDS)
-{
- if (DataSource->IsA("SMESH_Grid")) {
- ((SMESH_Grid*)DataSource)->SetIdsSMESHDSElement(mapSMESHDS);
- } else
- MESSAGE("SetIdsSMESHDSElement() method has been moved to SMESH_Grid class");
+
+
+void SMESH_Actor::SetPreSelected(Standard_Boolean presel){
+ ispreselected = presel;
+ UpdateHighlight();
}
-int SMESH_Actor::GetIdVTKNode(int idSMESHDSnode)
+
+// From vtkFollower
+int SMESH_Actor::RenderOpaqueGeometry(vtkViewport *vp)
{
- if (DataSource->IsA("SMESH_Grid")) {
- return ((SMESH_Grid*)DataSource)->GetIdVTKNode(idSMESHDSnode);
- } else {
- MESSAGE("GetIdVTKNode() method has been moved to SMESH_Grid class");
- return -1;
- }
+ if (myPickableActor->GetIsOpaque())
+ {
+ vtkRenderer *ren = static_cast<vtkRenderer *>(vp);
+ this->Render(ren);
+ return 1;
+ }
+ return 0;
}
-int SMESH_Actor::GetIdVTKElement(int idSMESHDSelement)
+
+
+int SMESH_Actor::RenderTranslucentGeometry(vtkViewport *vp)
{
- if (DataSource->IsA("SMESH_Grid")) {
- return ((SMESH_Grid*)DataSource)->GetIdVTKElement(idSMESHDSelement);
- } else {
- MESSAGE("GetIdVTKElement() method has been moved to SMESH_Grid class");
- return -1;
- }
+ if (!myPickableActor->GetIsOpaque())
+ {
+ vtkRenderer *ren = static_cast<vtkRenderer *>(vp);
+ this->Render(ren);
+ return 1;
+ }
+ return 0;
+}
+
+
+void SMESH_Actor::Render(vtkRenderer *ren){}
+
+void SMESH_Actor::ReleaseGraphicsResources(vtkWindow *renWin){
+ SALOME_Actor::ReleaseGraphicsResources(renWin);
+
+ myPickableActor->ReleaseGraphicsResources(renWin);
}
-int SMESH_Actor::GetIdSMESHDSNode(int idVTKnode)
-{
- if (DataSource->IsA("SMESH_Grid")) {
- return ((SMESH_Grid*)DataSource)->GetIdSMESHDSNode(idVTKnode);
- } else {
- MESSAGE("GetIdSMESHDSNode() method has been moved to SMESH_Grid class");
- return -1;
- }
+
+static void GetColor(vtkProperty *theProperty, float& r,float& g,float& b){
+ float* aColor = theProperty->GetColor();
+ r = aColor[0];
+ g = aColor[1];
+ b = aColor[2];
}
-int SMESH_Actor::GetIdSMESHDSElement(int idVTKelement)
-{
- if (DataSource->IsA("SMESH_Grid")) {
- return ((SMESH_Grid*)DataSource)->GetIdSMESHDSElement(idVTKelement);
- } else {
- MESSAGE("AddNode() method has been moved to SMESH_Grid class");
- return -1;
- }
+
+void SMESH_Actor::SetOpacity(float theValue){
+ mySurfaceProp->SetOpacity(theValue);
+ myBackSurfaceProp->SetOpacity(theValue);
+ myEdgeProp->SetOpacity(theValue);
+ myNodeProp->SetOpacity(theValue);
+
+ my1DProp->SetOpacity(theValue);
}
-void SMESH_Actor::ClearNode()
-{
- if (DataSource->IsA("SMESH_Grid")) {
- ((SMESH_Grid*)DataSource)->ClearNode();
- } else
- MESSAGE("ClearNode() method has been moved to SMESH_Grid class");
+
+float SMESH_Actor::GetOpacity(){
+ return mySurfaceProp->GetOpacity();
}
-void SMESH_Actor::ClearElement()
-{
- if (DataSource->IsA("SMESH_Grid")) {
- ((SMESH_Grid*)DataSource)->ClearElement();
- } else
- MESSAGE("ClearElement() method has been moved to SMESH_Grid class");
+
+void SMESH_Actor::SetSufaceColor(float r,float g,float b){
+ mySurfaceProp->SetColor(r,g,b);
+ Modified();
}
-void SMESH_Actor::RemoveNode(int id)
-{
- if (DataSource->IsA("SMESH_Grid")) {
- ((SMESH_Grid*)DataSource)->RemoveNode(id);
- } else
- MESSAGE("RemoveNode() method has been moved to SMESH_Grid class");
+void SMESH_Actor::GetSufaceColor(float& r,float& g,float& b){
+ ::GetColor(mySurfaceProp,r,g,b);
}
-void SMESH_Actor::RemoveElement(int id)
-{
- if (DataSource->IsA("SMESH_Grid")) {
- ((SMESH_Grid*)DataSource)->RemoveElement(id);
- } else
- MESSAGE("RemoveElement() method has been moved to SMESH_Grid class");
-}
-
-void SMESH_Actor::setDisplayMode(int thenewmode) {
- myDisplayMode = thenewmode;
- if ( myDisplayMode == 1 ) {
- EdgeDevice->VisibilityOn();
- EdgeShrinkDevice->VisibilityOff();
- } else if ( myDisplayMode == 2 ) {
- EdgeDevice->VisibilityOff();
- EdgeShrinkDevice->VisibilityOn();
- } else {
- EdgeDevice->VisibilityOff();
- EdgeShrinkDevice->VisibilityOff();
- }
+
+void SMESH_Actor::SetBackSufaceColor(float r,float g,float b){
+ myBackSurfaceProp->SetColor(r,g,b);
+ Modified();
}
-float SMESH_Actor::GetShrinkFactor()
-{
- return myShrinkFactor;
+void SMESH_Actor::GetBackSufaceColor(float& r,float& g,float& b){
+ ::GetColor(myBackSurfaceProp,r,g,b);
}
-void SMESH_Actor::SetShrinkFactor(float value )
-{
- if ( value <= 0.1 )
- value = 0.8;
+void SMESH_Actor::SetEdgeColor(float r,float g,float b){
+ myEdgeProp->SetColor(r,g,b);
+ my1DProp->SetColor(r,g,b);
+ my1DExtProp->SetColor(1.0-r,1.0-g,1.0-b);
+ Modified();
+}
- myShrinkFactor = value;
+void SMESH_Actor::GetEdgeColor(float& r,float& g,float& b){
+ ::GetColor(myEdgeProp,r,g,b);
}
-void SMESH_Actor::GetChildActors(vtkActorCollection* actors)
-{
- actors->AddItem(EdgeDevice);
- actors->AddItem(EdgeShrinkDevice);
+void SMESH_Actor::SetNodeColor(float r,float g,float b){
+ myNodeProp->SetColor(r,g,b);
+ Modified();
}
-void SMESH_Actor::SetVisibility(bool visibility)
-{
- if ( visibility ) {
- this->VisibilityOn();
- if ( myDisplayMode == 1 ) {
- EdgeDevice->VisibilityOn();
- EdgeShrinkDevice->VisibilityOff();
- } else if ( myDisplayMode == 2 ) {
- EdgeDevice->VisibilityOff();
- EdgeShrinkDevice->VisibilityOn();
- } else {
- EdgeDevice->VisibilityOff();
- EdgeShrinkDevice->VisibilityOff();
- }
- } else {
- this->VisibilityOff();
- EdgeDevice->VisibilityOff();
- EdgeShrinkDevice->VisibilityOff();
- }
+void SMESH_Actor::GetNodeColor(float& r,float& g,float& b){
+ ::GetColor(myNodeProp,r,g,b);
+}
+
+void SMESH_Actor::SetHighlightColor(float r,float g,float b){
+ myHighlightProp->SetColor(r,g,b);
+ Modified();
+}
+
+void SMESH_Actor::GetHighlightColor(float& r,float& g,float& b){
+ ::GetColor(myHighlightProp,r,g,b);
+}
+
+void SMESH_Actor::SetPreHighlightColor(float r,float g,float b){
+ myPreselectProp->SetColor(r,g,b);
+ Modified();
}
+void SMESH_Actor::GetPreHighlightColor(float& r,float& g,float& b){
+ ::GetColor(myPreselectProp,r,g,b);
+}
+
+
+float SMESH_Actor::GetLineWidth(){
+ return myEdgeProp->GetLineWidth();
+}
+
+
+void SMESH_Actor::SetLineWidth(float theVal){
+ myEdgeProp->SetLineWidth(theVal);
+ Modified();
+}
+
+
+void SMESH_Actor::SetNodeSize(float theSize){
+ myNodeProp->SetPointSize(theSize);
+ myHighlightProp->SetPointSize(theSize);
+ myPreselectProp->SetPointSize(theSize);
+
+ my1DExtProp->SetPointSize(theSize);
+ my1DProp->SetPointSize(theSize);
+
+ Modified();
+}
+
+float SMESH_Actor::GetNodeSize(){
+ return myNodeProp->GetPointSize();
+}
+
+int SMESH_Actor::GetObjDimension( const int theObjId )
+{
+ return myVisualObj->GetElemDimension( theObjId );
+}
#define SMESH_ACTOR_H
#include "SALOME_Actor.h"
+#include "SMESH_Object.h"
-// VTK Includes
-#include <vtkActor.h>
-#include <vtkDataSetMapper.h>
-#include <vtkUnstructuredGridReader.h>
+class vtkProperty;
+class vtkShrinkFilter;
+class vtkPolyDataMapper;
+class vtkUnstructuredGrid;
+class vtkMergeFilter;
+class vtkPolyData;
-// Open CASCADE Includes
-#include <TColStd_IndexedMapOfInteger.hxx>
-#include <TColStd_DataMapOfIntegerInteger.hxx>
+class vtkMapper;
+class vtkActor2D;
+class vtkMaskPoints;
+class vtkLabeledDataMapper;
+class vtkSelectVisiblePoints;
-typedef struct rgbStruct
-{
- float r;
- float g;
- float b;
-} RGBStruct;
+class vtkScalarBarActor;
+class vtkLookupTable;
-class SMESH_Actor : public SALOME_Actor {
+class SMESH_DeviceActor;
+class SALOME_ExtractUnstructuredGrid;
- public:
- vtkTypeMacro(SMESH_Actor,SALOME_Actor);
-
- static SMESH_Actor* New();
- // Description:
- // This causes the actor to be rendered. It, in turn, will render the actor`s
- // property and then mapper.
- virtual void Render(vtkRenderer *, vtkMapper *);
+class SMESH_Actor : public SALOME_Actor{
+ friend class SMESH_VisualObj;
- // Description:
- // This method is used internally by the rendering process.
- // We overide the superclass method to properly set the estimated render time.
- int RenderOpaqueGeometry(vtkViewport *viewport);
-
- void ShallowCopy(vtkProp *prop);
-
- void setReader(vtkUnstructuredGridReader* r) ;
- vtkUnstructuredGridReader* getReader();
+ public:
+ vtkTypeMacro(SMESH_Actor,SALOME_Actor);
+ static SMESH_Actor* New(TVisualObjPtr theVisualObj,
+ SMESH::FilterManager_ptr theFilterMgr,
+ const char* theEntry,
+ const char* theName,
+ int theIsClear);
+
+ virtual void ReleaseGraphicsResources(vtkWindow *renWin);
+ virtual int RenderOpaqueGeometry(vtkViewport *viewport);
+ virtual int RenderTranslucentGeometry(vtkViewport *viewport);
+ virtual void Render(vtkRenderer *ren);
+
+ virtual void AddToRender(vtkRenderer* theRenderer);
+ virtual void RemoveFromRender(vtkRenderer* theRenderer);
- // Highlight
virtual bool hasHighlight() { return true; }
+ virtual void highlight(Standard_Boolean highlight);
+ virtual void SetPreSelected(Standard_Boolean presel = Standard_False);
- vtkMapper* getMapper();
+ virtual bool IsInfinitive();
- void setDisplayMode(int);
+ virtual void SetOpacity(float theValue);
+ virtual float GetOpacity();
- void SetColor(float r,float g,float b);
- void GetColor(float& r,float& g,float& b);
- void SetHighlightColor(float r,float g,float b);
- void GetHighlightColor(float& r,float& g,float& b);
- void SetPreselectedColor(float r,float g,float b);
- void GetPreselectedColor(float& r,float& g,float& b);
+ void SetSufaceColor(float r,float g,float b);
+ void GetSufaceColor(float& r,float& g,float& b);
+
+ void SetBackSufaceColor(float r,float g,float b);
+ void GetBackSufaceColor(float& r,float& g,float& b);
void SetEdgeColor(float r,float g,float b);
void GetEdgeColor(float& r,float& g,float& b);
- void SetEdgeHighlightColor(float r,float g,float b);
- void GetEdgeHighlightColor(float& r,float& g,float& b);
- void SetEdgePreselectedColor(float r,float g,float b);
- void GetEdgePreselectedColor(float& r,float& g,float& b);
void SetNodeColor(float r,float g,float b);
void GetNodeColor(float& r,float& g,float& b);
+
+ void SetHighlightColor(float r,float g,float b);
+ void GetHighlightColor(float& r,float& g,float& b);
+
+ void SetPreHighlightColor(float r,float g,float b);
+ void GetPreHighlightColor(float& r,float& g,float& b);
- void SetNodeSize(int size) ;
- int GetNodeSize() ;
+ float GetLineWidth();
+ void SetLineWidth(float theVal);
+ void SetNodeSize(float size) ;
+ float GetNodeSize() ;
- void ClearNode();
- void ClearElement();
+ virtual int GetObjId(int theVtkID);
+ virtual TVectorId GetVtkId(int theObjID);
- void RemoveNode(int idSMESHDSnode);
- void RemoveElement(int idSMESHDSelement);
+ virtual int GetNodeObjId(int theVtkID);
+ virtual TVectorId GetNodeVtkId(int theObjID);
- void AddNode(int idSMESHDSnode, int idVTKnode);
- void AddElement(int idSMESHDSelement, int idVTKelement);
+ virtual int GetElemObjId(int theVtkID);
+ virtual TVectorId GetElemVtkId(int theObjID);
- int GetIdVTKNode(int idSMESHDSnode);
- int GetIdVTKElement(int idSMESHDSelement);
+ virtual int GetObjDimension( const int theObjId );
- int GetIdSMESHDSNode(int idVTKnode);
- int GetIdSMESHDSElement(int idVTKelement);
+ virtual void SetVisibility(int theMode);
- void SetIdsVTKNode(const TColStd_DataMapOfIntegerInteger& mapVTK);
- void SetIdsSMESHDSNode(const TColStd_DataMapOfIntegerInteger& mapSMESHDS);
+ enum EReperesent { ePoint, eEdge, eSurface};
+ virtual void SetRepresentation(int theMode);
+ void SetPointRepresentation(int theIsPointsVisible);
+ bool GetPointRepresentation(){ return myIsPointsVisible;}
- void SetIdsVTKElement(const TColStd_DataMapOfIntegerInteger& mapVTK);
- void SetIdsSMESHDSElement(const TColStd_DataMapOfIntegerInteger& mapSMESHDS);
+ virtual vtkPolyData* GetPolyDataInput();
+ virtual void SetTransform(SALOME_Transform* theTransform);
- vtkDataSet* DataSource;
- vtkActor* EdgeDevice;
- vtkActor* EdgeShrinkDevice;
+ vtkUnstructuredGrid* GetUnstructuredGrid();
+ virtual vtkMapper* GetMapper();
float GetShrinkFactor();
void SetShrinkFactor(float value );
- void GetChildActors(vtkActorCollection*);
+ bool IsShrunkable() { return myIsShrinkable;}
+ bool IsShrunk() { return myIsShrunk;}
+ void SetShrink();
+ void UnShrink();
- void SetVisibility(bool visibility);
+ void SetPointsLabeled(bool theIsPointsLabeled);
+ bool GetPointsLabeled(){ return myIsPointsLabeled;}
- protected:
+ void SetCellsLabeled(bool theIsCellsLabeled);
+ bool GetCellsLabeled(){ return myIsCellsLabeled;}
- SMESH_Actor();
- ~SMESH_Actor();
- SMESH_Actor(const SMESH_Actor&) {};
- void operator=(const SMESH_Actor&) {};
+ enum eControl{eNone, eLengthEdges, eFreeBorders, eMultiConnection,
+ eArea, eTaper, eAspectRatio, eMinimumAngle, eWarping, eSkew};
+ void SetControlMode(eControl theMode);
+ eControl GetControlMode(){ return myColorMode;}
+
+ enum e1DControl{e1DNone, e1DColored, e1DHighlited};
+ e1DControl Get1DControlMode(){ return my1DColorMode;}
- vtkUnstructuredGridReader* myReader;
+ vtkScalarBarActor* GetScalarBarActor(){ return myScalarBarActor;}
- float myShrinkFactor;
+ TVisualObjPtr GetObject() { return myVisualObj;}
- RGBStruct edgeColor;
- RGBStruct edgeHighlightColor;
- RGBStruct edgePreselectedColor;
+ protected:
+ TVisualObjPtr myVisualObj;
+
+ SMESH::FilterManager_var myFilterMgr;
+ vtkScalarBarActor* myScalarBarActor;
+ vtkLookupTable* myLookupTable;
+
+ vtkProperty* mySurfaceProp;
+ vtkProperty* myBackSurfaceProp;
+ vtkProperty* myEdgeProp;
+ vtkProperty* myNodeProp;
+
+ SMESH_DeviceActor* myBaseActor;
+ SMESH_DeviceActor* myNodeActor;
+ SMESH_DeviceActor* myPickableActor;
+
+ vtkProperty* myHighlightProp;
+ vtkProperty* myPreselectProp;
+ SMESH_DeviceActor* myHighlitableActor;
+
+ eControl myColorMode;
+ SMESH_DeviceActor* my2DActor;
+ SMESH_DeviceActor* my3DActor;
+ SMESH_DeviceActor* myControlActor;
+
+ e1DControl my1DColorMode;
+ vtkProperty* my1DProp;
+ SMESH_DeviceActor* my1DActor;
+ vtkProperty* my1DExtProp;
+ SMESH_DeviceActor* my1DExtActor;
+
+ bool myIsPointsVisible;
+
+ bool myIsShrinkable;
+ bool myIsShrunk;
+
+ bool myIsPointsLabeled;
+ vtkUnstructuredGrid* myPointsNumDataSet;
+ vtkActor2D *myPointLabels;
+ vtkMaskPoints* myPtsMaskPoints;
+ vtkLabeledDataMapper* myPtsLabeledDataMapper;
+ vtkSelectVisiblePoints* myPtsSelectVisiblePoints;
+
+ bool myIsCellsLabeled;
+ vtkUnstructuredGrid* myCellsNumDataSet;
+ vtkActor2D *myCellsLabels;
+ vtkMaskPoints* myClsMaskPoints;
+ vtkCellCenters* myCellCenters;
+ vtkLabeledDataMapper* myClsLabeledDataMapper;
+ vtkSelectVisiblePoints* myClsSelectVisiblePoints;
- RGBStruct actorColor;
- RGBStruct actorHighlightColor;
- RGBStruct actorPreselectedColor;
+ SMESH_Actor();
+ ~SMESH_Actor();
- RGBStruct actorNodeColor; // LPN
- int actorNodeSize; // LPN
+ void Init(TVisualObjPtr theVisualObj,
+ SMESH::FilterManager_ptr theFilterMgr,
+ const char* theEntry,
+ const char* theName,
+ int theIsClear);
+
+ void SetUnstructuredGrid(vtkUnstructuredGrid* theGrid);
+ void SetIsShrunkable(bool theShrunkable);
+ void UpdateHighlight();
+
+ private:
+ // hide the two parameter Render() method from the user and the compiler.
+ virtual void Render(vtkRenderer *, vtkMapper *) {};
+ virtual void ShallowCopy(vtkProp *prop);
+ virtual void SetMapper(vtkMapper *);
+ static SMESH_Actor* New();
+ // Not implemented.
+ SMESH_Actor(const SMESH_Actor&);
+ void operator=(const SMESH_Actor&);
};
+
+
#endif //SMESH_ACTOR_H
--- /dev/null
+// SMESH OBJECT : interactive object for SMESH visualization
+//
+// Copyright (C) 2003 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
+// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
+//
+// This library 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.
+//
+// This library 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 this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+//
+// See http://www.opencascade.org/SALOME/ or email : webmaster.salome@opencascade.org
+//
+//
+//
+// File : SMESH_Actor.cxx
+// Author : Nicolas REJNERI
+// Module : SMESH
+// $Header$
+
+
+#include "SMESH_DeviceActor.h"
+
+#include "SALOME_Transform.h"
+#include "SALOME_TransformFilter.h"
+#include "SALOME_PassThroughFilter.h"
+#include "SALOME_ExtractUnstructuredGrid.h"
+
+#include "utilities.h"
+
+// VTK Includes
+#include <vtkObjectFactory.h>
+#include <vtkShrinkFilter.h>
+#include <vtkShrinkPolyData.h>
+
+#include <vtkProperty.h>
+#include <vtkPolyData.h>
+#include <vtkMergeFilter.h>
+#include <vtkPolyDataMapper.h>
+#include <vtkUnstructuredGrid.h>
+
+#ifdef _DEBUG_
+static int MYDEBUG = 0;
+static int MYDEBUGWITHFILES = 0;
+#else
+static int MYDEBUG = 0;
+static int MYDEBUGWITHFILES = 0;
+#endif
+
+using namespace std;
+
+
+vtkStandardNewMacro(SMESH_DeviceActor);
+
+
+SMESH_DeviceActor::SMESH_DeviceActor(){
+ if(MYDEBUG) MESSAGE("SMESH_DeviceActor");
+ myIsShrunk = false;
+ myIsShrinkable = false;
+ myRepresentation = eSurface;
+
+ myProperty = vtkProperty::New();
+ myMapper = vtkPolyDataMapper::New();
+
+ vtkMapper::GetResolveCoincidentTopologyPolygonOffsetParameters(myPolygonOffsetFactor,
+ myPolygonOffsetUnits);
+ //myMapper->SetResolveCoincidentTopologyToShiftZBuffer();
+ //myMapper->SetResolveCoincidentTopologyZShift(0.02);
+
+ myMapper->UseLookupTableScalarRangeOn();
+ myMapper->SetColorModeToMapScalars();
+
+ myShrinkFilter = vtkShrinkFilter::New();
+
+ myExtractUnstructuredGrid = SALOME_ExtractUnstructuredGrid::New();
+ myExtractUnstructuredGrid->SetStoreMapping(true);
+
+ myMergeFilter = vtkMergeFilter::New();
+
+ myStoreMapping = false;
+ myGeomFilter = SALOME_GeometryFilter::New();
+
+ myTransformFilter = SALOME_TransformFilter::New();
+
+ for(int i = 0; i < 6; i++)
+ myPassFilter.push_back(SALOME_PassThroughFilter::New());
+}
+
+
+SMESH_DeviceActor::~SMESH_DeviceActor(){
+ if(MYDEBUG) MESSAGE("~SMESH_DeviceActor");
+ myProperty->Delete();
+
+ myMapper->RemoveAllInputs();
+ myMapper->Delete();
+
+ myShrinkFilter->UnRegisterAllOutputs();
+ myShrinkFilter->Delete();
+
+ myExtractUnstructuredGrid->UnRegisterAllOutputs();
+ myExtractUnstructuredGrid->Delete();
+
+ myMergeFilter->UnRegisterAllOutputs();
+ myMergeFilter->Delete();
+
+ myGeomFilter->UnRegisterAllOutputs();
+ myGeomFilter->Delete();
+
+ myTransformFilter->UnRegisterAllOutputs();
+ myTransformFilter->Delete();
+
+ for(int i = 0, iEnd = myPassFilter.size(); i < iEnd; i++){
+ myPassFilter[i]->UnRegisterAllOutputs();
+ myPassFilter[i]->Delete();
+ }
+}
+
+
+void SMESH_DeviceActor::SetStoreMapping(int theStoreMapping){
+ myStoreMapping = theStoreMapping;
+ Modified();
+}
+
+
+void SMESH_DeviceActor::SetUnstructuredGrid(vtkUnstructuredGrid* theGrid){
+ if(theGrid){
+ //myIsShrinkable = theGrid->GetNumberOfCells() > 10;
+ myIsShrinkable = true;
+
+ myExtractUnstructuredGrid->SetInput(theGrid);
+ myMergeFilter->SetGeometry(myExtractUnstructuredGrid->GetOutput());
+
+ theGrid = static_cast<vtkUnstructuredGrid*>(myMergeFilter->GetOutput());
+
+ int anId = 0;
+ myPassFilter.at( anId )->SetInput( theGrid );
+ myPassFilter.at( anId + 1)->SetInput( myPassFilter.at( anId )->GetOutput() );
+
+ anId++; // 1
+ myGeomFilter->SetStoreMapping( myStoreMapping );
+ myGeomFilter->SetInput( myPassFilter.at( anId )->GetOutput() );
+
+ anId++; // 2
+ myPassFilter.at( anId )->SetInput( myGeomFilter->GetOutput() );
+ myPassFilter.at( anId + 1 )->SetInput( myPassFilter.at( anId )->GetOutput() );
+
+ anId++; // 3
+ myTransformFilter->SetInput( myPassFilter.at( anId )->GetPolyDataOutput() );
+
+ anId++; // 4
+ myPassFilter.at( anId )->SetInput( myTransformFilter->GetOutput() );
+ myPassFilter.at( anId + 1 )->SetInput( myPassFilter.at( anId )->GetOutput() );
+
+ anId++; // 5
+ myMapper->SetInput( myPassFilter.at( anId )->GetPolyDataOutput() );
+
+ vtkLODActor::SetMapper( myMapper );
+ Modified();
+ }
+}
+
+
+SALOME_ExtractUnstructuredGrid* SMESH_DeviceActor::GetExtractUnstructuredGrid(){
+ return myExtractUnstructuredGrid;
+}
+
+
+vtkUnstructuredGrid* SMESH_DeviceActor::GetUnstructuredGrid(){
+ myExtractUnstructuredGrid->Update();
+ return myExtractUnstructuredGrid->GetOutput();
+}
+
+
+vtkMergeFilter* SMESH_DeviceActor::GetMergeFilter(){
+ return myMergeFilter;
+}
+
+
+vtkPolyData* SMESH_DeviceActor::GetPolyDataInput(){
+ return myPassFilter.back()->GetPolyDataOutput();
+}
+
+
+unsigned long int SMESH_DeviceActor::GetMTime(){
+ unsigned long mTime = this->Superclass::GetMTime();
+ mTime = max(mTime,myExtractUnstructuredGrid->GetMTime());
+ mTime = max(mTime,myMergeFilter->GetMTime());
+ mTime = max(mTime,myGeomFilter->GetMTime());
+ mTime = max(mTime,myTransformFilter->GetMTime());
+ return mTime;
+}
+
+
+void SMESH_DeviceActor::SetTransform(SALOME_Transform* theTransform){
+ myTransformFilter->SetTransform(theTransform);
+}
+
+
+void SMESH_DeviceActor::SetShrink()
+{
+ if ( !myIsShrinkable ) return;
+ if ( vtkDataSet* aDataSet = myPassFilter.at( 0 )->GetOutput() )
+ {
+ myShrinkFilter->SetInput( aDataSet );
+ myPassFilter.at( 1 )->SetInput( myShrinkFilter->GetOutput() );
+ myIsShrunk = true;
+ }
+}
+
+void SMESH_DeviceActor::UnShrink()
+{
+ if ( !myIsShrunk ) return;
+ if ( vtkDataSet* aDataSet = myPassFilter.at( 0 )->GetOutput() )
+ {
+ myPassFilter.at( 1 )->SetInput( aDataSet );
+ myPassFilter.at( 1 )->Modified();
+ myIsShrunk = false;
+ Modified();
+ }
+}
+
+
+void SMESH_DeviceActor::SetRepresentation(EReperesent theMode){
+ switch(theMode){
+ case ePoint:
+ myGeomFilter->SetInside(true);
+ GetProperty()->SetRepresentation(0);
+ break;
+ case eInsideframe:
+ myGeomFilter->SetInside(true);
+ GetProperty()->SetRepresentation(1);
+ break;
+ default :
+ GetProperty()->SetRepresentation(theMode);
+ myGeomFilter->SetInside(false);
+ }
+ myRepresentation = theMode;
+ myMapper->Modified();
+ Modified();
+}
+
+
+void SMESH_DeviceActor::SetVisibility(int theMode){
+ if(!myExtractUnstructuredGrid->GetInput() || GetUnstructuredGrid()->GetNumberOfCells()){
+ vtkLODActor::SetVisibility(theMode);
+ }else{
+ vtkLODActor::SetVisibility(false);
+ }
+}
+
+
+int SMESH_DeviceActor::GetVisibility(){
+ if(!GetUnstructuredGrid()->GetNumberOfCells()){
+ vtkLODActor::SetVisibility(false);
+ }
+ return vtkLODActor::GetVisibility();
+}
+
+
+int SMESH_DeviceActor::GetObjId(int theVtkID){
+ if (GetRepresentation() == ePoint){
+ return GetNodeObjId(theVtkID);
+ }else{
+ return GetElemObjId(theVtkID);
+ }
+}
+
+
+SMESH_DeviceActor::TVectorId SMESH_DeviceActor::GetVtkId(int theObjID){
+ if (GetRepresentation() == ePoint){
+ return GetNodeVtkId(theObjID);
+ }else{
+ return GetElemVtkId(theObjID);
+ }
+}
+
+
+int SMESH_DeviceActor::GetNodeObjId(int theVtkID){
+ vtkIdType aRetID = myVisualObj->GetNodeObjId(theVtkID);
+ if(MYDEBUG) MESSAGE("GetNodeObjId - theVtkID = "<<theVtkID<<"; aRetID = "<<aRetID);
+ return aRetID;
+}
+
+SMESH_DeviceActor::TVectorId SMESH_DeviceActor::GetNodeVtkId(int theObjID){
+ SMESH_DeviceActor::TVectorId aVecId;
+ vtkIdType anID = myVisualObj->GetNodeVTKId(theObjID);
+ if(anID < 0)
+ return aVecId;
+ aVecId.push_back(anID);
+ return aVecId;
+}
+
+
+int SMESH_DeviceActor::GetElemObjId(int theVtkID){
+ vtkIdType aGridID = myGeomFilter->GetObjId(theVtkID);
+ if(aGridID < 0)
+ return -1;
+ vtkIdType anExtractID = myExtractUnstructuredGrid->GetOutId(aGridID);
+ if(anExtractID < 0)
+ return -1;
+ vtkIdType aRetID = myVisualObj->GetElemObjId(anExtractID);
+ if(MYDEBUG)
+ MESSAGE("GetElemObjId - theVtkID = "<<theVtkID<<"; anExtractID = "<<anExtractID<<"; aGridID = "<<aGridID<<"; aRetID = "<<aRetID);
+ return aRetID;
+}
+
+SMESH_DeviceActor::TVectorId SMESH_DeviceActor::GetElemVtkId(int theObjID){
+ TVectorId aVecId;
+ vtkIdType aGridID = myVisualObj->GetElemVTKId(theObjID);
+ if(aGridID < 0)
+ return aVecId;
+ aVecId = myGeomFilter->GetVtkId(aGridID);
+ if(MYDEBUG)
+ MESSAGE("GetElemVtkId - theObjID = "<<theObjID<<"; aGridID = "<<aGridID<<"; aGridID = "<<aGridID<<"; aVecId[0] = "<<aVecId[0]);
+ return aVecId;
+}
+
+
+float SMESH_DeviceActor::GetShrinkFactor(){
+ return myShrinkFilter->GetShrinkFactor();
+}
+
+void SMESH_DeviceActor::SetShrinkFactor(float theValue){
+ theValue = theValue > 0.1? theValue: 0.8;
+ myShrinkFilter->SetShrinkFactor(theValue);
+ Modified();
+}
+
+
+void SMESH_DeviceActor::Render(vtkRenderer *ren, vtkMapper* m){
+ int aResolveCoincidentTopology = vtkMapper::GetResolveCoincidentTopology();
+ float aFactor, aUnit;
+ vtkMapper::GetResolveCoincidentTopologyPolygonOffsetParameters(aFactor,aUnit);
+
+ vtkMapper::SetResolveCoincidentTopologyToPolygonOffset();
+ vtkMapper::SetResolveCoincidentTopologyPolygonOffsetParameters(myPolygonOffsetFactor,
+ myPolygonOffsetUnits);
+ vtkLODActor::Render(ren,m);
+
+ vtkMapper::SetResolveCoincidentTopologyPolygonOffsetParameters(aFactor,aUnit);
+ vtkMapper::SetResolveCoincidentTopology(aResolveCoincidentTopology);
+}
+
+
+void SMESH_DeviceActor::SetPolygonOffsetParameters(float factor, float units){
+ myPolygonOffsetFactor = factor;
+ myPolygonOffsetUnits = units;
+}
+
--- /dev/null
+// SMESH OBJECT : interactive object for SMESH visualization
+//
+// Copyright (C) 2003 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
+// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
+//
+// This library 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.
+//
+// This library 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 this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+//
+// See http://www.opencascade.org/SALOME/ or email : webmaster.salome@opencascade.org
+//
+//
+//
+// File : SMESH_Actor.h
+// Author : Nicolas REJNERI
+// Module : SMESH
+// $Header$
+
+#ifndef SMESH_DEVICE_ACTOR_H
+#define SMESH_DEVICE_ACTOR_H
+
+#include "SALOME_GeometryFilter.h"
+#include "SMESH_Object.h"
+
+#include <vtkLODActor.h>
+
+class vtkProperty;
+class vtkMergeFilter;
+class vtkShrinkFilter;
+class vtkPolyDataMapper;
+class vtkUnstructuredGrid;
+
+class SALOME_Transform;
+class SALOME_TransformFilter;
+class SALOME_PassThroughFilter;
+class SALOME_ExtractUnstructuredGrid;
+
+
+class SMESH_DeviceActor: public vtkLODActor{
+ friend class SMESH_Actor;
+
+ public:
+ vtkTypeMacro(SMESH_DeviceActor,vtkLODActor);
+ static SMESH_DeviceActor* New();
+
+ void SetStoreMapping(int theStoreMapping);
+ int GetStoreMapping(){ return myStoreMapping;}
+
+ typedef SALOME_GeometryFilter::TVectorId TVectorId;
+ int GetObjId(int theVtkID);
+ TVectorId GetVtkId(int theObjID);
+
+ int GetNodeObjId(int theVtkID);
+ TVectorId GetNodeVtkId(int theObjID);
+
+ int GetElemObjId(int theVtkID);
+ TVectorId GetElemVtkId(int theObjID);
+
+ vtkPolyData* GetPolyDataInput();
+
+ virtual void SetTransform(SALOME_Transform* theTransform);
+ virtual unsigned long int GetMTime();
+
+ float GetShrinkFactor();
+ void SetShrinkFactor(float value);
+
+ bool IsShrunkable() { return myIsShrinkable;}
+ bool IsShrunk() { return myIsShrunk;}
+ void SetShrink();
+ void UnShrink();
+
+ enum EReperesent { ePoint, eWireframe, eSurface, eInsideframe};
+ EReperesent GetRepresentation(){ return myRepresentation;}
+ void SetRepresentation(EReperesent theMode);
+
+ virtual void SetVisibility(int theMode);
+ virtual int GetVisibility();
+
+ SALOME_ExtractUnstructuredGrid* GetExtractUnstructuredGrid();
+ vtkUnstructuredGrid* GetUnstructuredGrid();
+ vtkMergeFilter* GetMergeFilter();
+
+ virtual void Render(vtkRenderer *, vtkMapper *);
+
+ protected:
+ void SetUnstructuredGrid(vtkUnstructuredGrid* theGrid);
+
+ vtkPolyDataMapper *myMapper;
+ TVisualObjPtr myVisualObj;
+
+ vtkProperty *myProperty;
+ EReperesent myRepresentation;
+
+ vtkMergeFilter* myMergeFilter;
+ SALOME_ExtractUnstructuredGrid* myExtractUnstructuredGrid;
+
+ bool myStoreMapping;
+ SALOME_GeometryFilter *myGeomFilter;
+ SALOME_TransformFilter *myTransformFilter;
+ std::vector<SALOME_PassThroughFilter*> myPassFilter;
+
+ vtkShrinkFilter* myShrinkFilter;
+ bool myIsShrinkable;
+ bool myIsShrunk;
+
+ float myPolygonOffsetFactor;
+ float myPolygonOffsetUnits;
+
+ void SetPolygonOffsetParameters(float factor, float units);
+ void GetPolygonOffsetParameters(float& factor, float& units){
+ factor = myPolygonOffsetFactor;
+ units = myPolygonOffsetUnits;
+ }
+
+ SMESH_DeviceActor();
+ ~SMESH_DeviceActor();
+ SMESH_DeviceActor(const SMESH_DeviceActor&) {};
+ void operator=(const SMESH_DeviceActor&) {};
+
+};
+
+
+#endif //SMESH_ACTOR_H
--- /dev/null
+// SMESH OBJECT : interactive object for SMESH visualization
+//
+// Copyright (C) 2003 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
+// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
+//
+// This library 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.
+//
+// This library 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 this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+//
+// See http://www.opencascade.org/SALOME/ or email : webmaster.salome@opencascade.org
+//
+//
+//
+// File : SMESH_Grid.cxx
+// Author : Nicolas REJNERI
+// Module : SMESH
+
+#include "SMESH_Object.h"
+#include "SMDS_Mesh.hxx"
+#include "SALOME_ExtractUnstructuredGrid.h"
+#include "SMESH_Actor.h"
+
+#include CORBA_SERVER_HEADER(SALOME_Exception)
+
+#include <vtkUnstructuredGrid.h>
+#include <vtkUnstructuredGridWriter.h>
+#include <vtkUnstructuredGridReader.h>
+
+#include <memory>
+#include <sstream>
+#include <stdexcept>
+#include <set>
+
+#include "utilities.h"
+
+using namespace std;
+
+#ifndef EXCEPTION
+#define EXCEPTION(TYPE, MSG) {\
+ std::ostringstream aStream;\
+ aStream<<__FILE__<<"["<<__LINE__<<"]::"<<MSG;\
+ throw TYPE(aStream.str());\
+}
+#endif
+
+#ifdef _DEBUG_
+static int MYDEBUG = 1;
+static int MYDEBUGWITHFILES = 0;
+#else
+static int MYDEBUG = 0;
+static int MYDEBUGWITHFILES = 0;
+#endif
+
+
+void WriteUnstructuredGrid(vtkUnstructuredGrid* theGrid, const char* theFileName){
+ vtkUnstructuredGridWriter* aWriter = vtkUnstructuredGridWriter::New();
+ aWriter->SetFileName(theFileName);
+ aWriter->SetInput(theGrid);
+ aWriter->Write();
+ aWriter->Delete();
+}
+
+
+namespace{
+
+ inline const SMDS_MeshNode* FindNode(const SMDS_Mesh* theMesh, int theId){
+ if(const SMDS_MeshNode* anElem = theMesh->FindNode(theId)) return anElem;
+ EXCEPTION(runtime_error,"SMDS_Mesh::FindNode - cannot find a SMDS_MeshNode for ID = "<<theId);
+ }
+
+
+ inline const SMDS_MeshElement* FindElement(const SMDS_Mesh* theMesh, int theId){
+ if(const SMDS_MeshElement* anElem = theMesh->FindElement(theId)) return anElem;
+ EXCEPTION(runtime_error,"SMDS_Mesh::FindElement - cannot find a SMDS_MeshElement for ID = "<<theId);
+ }
+
+
+ inline void AddNodesWithID(SMDS_Mesh* theMesh,
+ SMESH::log_array_var& theSeq,
+ CORBA::Long theId)
+ {
+ const SMESH::double_array& aCoords = theSeq[theId].coords;
+ const SMESH::long_array& anIndexes = theSeq[theId].indexes;
+ CORBA::Long anElemId = 0, aNbElems = theSeq[theId].number;
+ if(3*aNbElems != aCoords.length())
+ EXCEPTION(runtime_error,"AddNodesWithID - 3*aNbElems != aCoords.length()");
+ for(CORBA::Long aCoordId = 0; anElemId < aNbElems; anElemId++, aCoordId+=3){
+ SMDS_MeshElement* anElem = theMesh->AddNodeWithID(aCoords[aCoordId],
+ aCoords[aCoordId+1],
+ aCoords[aCoordId+2],
+ anIndexes[anElemId]);
+ if(!anElem)
+ EXCEPTION(runtime_error,"SMDS_Mesh::FindElement - cannot AddNodeWithID for ID = "<<anElemId);
+ }
+ }
+
+
+ inline void AddEdgesWithID(SMDS_Mesh* theMesh,
+ SMESH::log_array_var& theSeq,
+ CORBA::Long theId)
+ {
+ const SMESH::double_array& aCoords = theSeq[theId].coords;
+ const SMESH::long_array& anIndexes = theSeq[theId].indexes;
+ CORBA::Long anElemId = 0, aNbElems = theSeq[theId].number;
+ if(3*aNbElems != anIndexes.length())
+ EXCEPTION(runtime_error,"AddEdgeWithID - 3*aNbElems != aCoords.length()");
+ for(CORBA::Long anIndexId = 0; anElemId < aNbElems; anElemId++, anIndexId+=3){
+ SMDS_MeshElement* anElem = theMesh->AddEdgeWithID(anIndexes[anIndexId+1],
+ anIndexes[anIndexId+2],
+ anIndexes[anIndexId]);
+ if(!anElem)
+ EXCEPTION(runtime_error,"SMDS_Mesh::FindElement - cannot AddEdgeWithID for ID = "<<anElemId);
+ }
+ }
+
+
+ inline void AddTriasWithID(SMDS_Mesh* theMesh,
+ SMESH::log_array_var& theSeq,
+ CORBA::Long theId)
+ {
+ const SMESH::double_array& aCoords = theSeq[theId].coords;
+ const SMESH::long_array& anIndexes = theSeq[theId].indexes;
+ CORBA::Long anElemId = 0, aNbElems = theSeq[theId].number;
+ if(4*aNbElems != anIndexes.length())
+ EXCEPTION(runtime_error,"AddEdgeWithID - 4*aNbElems != anIndexes.length()");
+ for(CORBA::Long anIndexId = 0; anElemId < aNbElems; anElemId++, anIndexId+=4){
+ SMDS_MeshElement* anElem = theMesh->AddFaceWithID(anIndexes[anIndexId+1],
+ anIndexes[anIndexId+2],
+ anIndexes[anIndexId+3],
+ anIndexes[anIndexId]);
+ if(!anElem)
+ EXCEPTION(runtime_error,"SMDS_Mesh::FindElement - cannot AddFaceWithID for ID = "<<anElemId);
+ }
+ }
+
+
+ inline void AddQuadsWithID(SMDS_Mesh* theMesh,
+ SMESH::log_array_var theSeq,
+ CORBA::Long theId)
+ {
+ const SMESH::double_array& aCoords = theSeq[theId].coords;
+ const SMESH::long_array& anIndexes = theSeq[theId].indexes;
+ CORBA::Long anElemId = 0, aNbElems = theSeq[theId].number;
+ if(5*aNbElems != anIndexes.length())
+ EXCEPTION(runtime_error,"AddEdgeWithID - 4*aNbElems != anIndexes.length()");
+ for(CORBA::Long anIndexId = 0; anElemId < aNbElems; anElemId++, anIndexId+=5){
+ SMDS_MeshElement* anElem = theMesh->AddFaceWithID(anIndexes[anIndexId+1],
+ anIndexes[anIndexId+2],
+ anIndexes[anIndexId+3],
+ anIndexes[anIndexId+4],
+ anIndexes[anIndexId]);
+ if(!anElem)
+ EXCEPTION(runtime_error,"SMDS_Mesh::FindElement - cannot AddFaceWithID for ID = "<<anElemId);
+ }
+ }
+
+
+ inline void AddTetrasWithID(SMDS_Mesh* theMesh,
+ SMESH::log_array_var& theSeq,
+ CORBA::Long theId)
+ {
+ const SMESH::double_array& aCoords = theSeq[theId].coords;
+ const SMESH::long_array& anIndexes = theSeq[theId].indexes;
+ CORBA::Long anElemId = 0, aNbElems = theSeq[theId].number;
+ if(5*aNbElems != anIndexes.length())
+ EXCEPTION(runtime_error,"AddEdgeWithID - 5*aNbElems != anIndexes.length()");
+ for(CORBA::Long anIndexId = 0; anElemId < aNbElems; anElemId++, anIndexId+=5){
+ SMDS_MeshElement* anElem = theMesh->AddVolumeWithID(anIndexes[anIndexId+1],
+ anIndexes[anIndexId+2],
+ anIndexes[anIndexId+3],
+ anIndexes[anIndexId+4],
+ anIndexes[anIndexId]);
+ if(!anElem)
+ EXCEPTION(runtime_error,"SMDS_Mesh::FindElement - cannot AddFaceWithID for ID = "<<anElemId);
+ }
+ }
+
+
+ inline void AddPiramidsWithID(SMDS_Mesh* theMesh,
+ SMESH::log_array_var& theSeq,
+ CORBA::Long theId)
+ {
+ const SMESH::double_array& aCoords = theSeq[theId].coords;
+ const SMESH::long_array& anIndexes = theSeq[theId].indexes;
+ CORBA::Long anElemId = 0, aNbElems = theSeq[theId].number;
+ if(6*aNbElems != anIndexes.length())
+ EXCEPTION(runtime_error,"AddEdgeWithID - 6*aNbElems != anIndexes.length()");
+ for(CORBA::Long anIndexId = 0; anElemId < aNbElems; anElemId++, anIndexId+=6){
+ SMDS_MeshElement* anElem = theMesh->AddVolumeWithID(anIndexes[anIndexId+1],
+ anIndexes[anIndexId+2],
+ anIndexes[anIndexId+3],
+ anIndexes[anIndexId+4],
+ anIndexes[anIndexId+5],
+ anIndexes[anIndexId]);
+ if(!anElem)
+ EXCEPTION(runtime_error,"SMDS_Mesh::FindElement - cannot AddFaceWithID for ID = "<<anElemId);
+ }
+ }
+
+
+ inline void AddPrismsWithID(SMDS_Mesh* theMesh,
+ SMESH::log_array_var& theSeq,
+ CORBA::Long theId)
+ {
+ const SMESH::double_array& aCoords = theSeq[theId].coords;
+ const SMESH::long_array& anIndexes = theSeq[theId].indexes;
+ CORBA::Long anElemId = 0, aNbElems = theSeq[theId].number;
+ if(7*aNbElems != anIndexes.length())
+ EXCEPTION(runtime_error,"AddEdgeWithID - 7*aNbElems != anIndexes.length()");
+ for(CORBA::Long anIndexId = 0; anElemId < aNbElems; anElemId++, anIndexId+=7){
+ SMDS_MeshElement* anElem = theMesh->AddVolumeWithID(anIndexes[anIndexId+1],
+ anIndexes[anIndexId+2],
+ anIndexes[anIndexId+3],
+ anIndexes[anIndexId+4],
+ anIndexes[anIndexId+5],
+ anIndexes[anIndexId+6],
+ anIndexes[anIndexId]);
+ if(!anElem)
+ EXCEPTION(runtime_error,"SMDS_Mesh::FindElement - cannot AddFaceWithID for ID = "<<anElemId);
+ }
+ }
+
+
+ inline void AddHexasWithID(SMDS_Mesh* theMesh,
+ SMESH::log_array_var& theSeq,
+ CORBA::Long theId)
+ {
+ const SMESH::double_array& aCoords = theSeq[theId].coords;
+ const SMESH::long_array& anIndexes = theSeq[theId].indexes;
+ CORBA::Long anElemId = 0, aNbElems = theSeq[theId].number;
+ if(9*aNbElems != anIndexes.length())
+ EXCEPTION(runtime_error,"AddEdgeWithID - 9*aNbElems != anIndexes.length()");
+ for(CORBA::Long anIndexId = 0; anElemId < aNbElems; anElemId++, anIndexId+=9){
+ SMDS_MeshElement* anElem = theMesh->AddVolumeWithID(anIndexes[anIndexId+1],
+ anIndexes[anIndexId+2],
+ anIndexes[anIndexId+3],
+ anIndexes[anIndexId+4],
+ anIndexes[anIndexId+5],
+ anIndexes[anIndexId+6],
+ anIndexes[anIndexId+7],
+ anIndexes[anIndexId+8],
+ anIndexes[anIndexId]);
+ if(!anElem)
+ EXCEPTION(runtime_error,"SMDS_Mesh::FindElement - cannot AddFaceWithID for ID = "<<anElemId);
+ }
+ }
+
+
+}
+/*
+ Class : SMESH_VisualObj
+ Description : Base class for all mesh objects to be visuilised
+*/
+
+//=================================================================================
+// function : getCellType
+// purpose : Get type of VTK cell
+//=================================================================================
+static inline vtkIdType getCellType( const SMESH::ElementType theType,
+ const int theNbNodes )
+{
+ switch( theType )
+ {
+ case SMESH::EDGE: return theNbNodes == 2 ? VTK_LINE : VTK_EMPTY_CELL;
+
+ case SMESH::FACE : if ( theNbNodes == 3 ) return VTK_TRIANGLE;
+ else if ( theNbNodes == 4 ) return VTK_QUAD;
+ else return VTK_EMPTY_CELL;
+
+ case SMESH::VOLUME: if ( theNbNodes == 4 ) return VTK_TETRA;
+ else if ( theNbNodes == 5 ) return VTK_PYRAMID;
+ else if ( theNbNodes == 6 ) return VTK_WEDGE;
+ else if ( theNbNodes == 8 ) return VTK_HEXAHEDRON;
+ else return VTK_EMPTY_CELL;
+
+ default: return VTK_EMPTY_CELL;
+ }
+}
+
+//=================================================================================
+// functions : SMESH_VisualObj
+// purpose : Constructor
+//=================================================================================
+SMESH_VisualObj::SMESH_VisualObj()
+{
+ myGrid = vtkUnstructuredGrid::New();
+}
+SMESH_VisualObj::~SMESH_VisualObj()
+{
+ if ( MYDEBUG )
+ MESSAGE( "~SMESH_MeshObj - myGrid->GetReferenceCount() = " << myGrid->GetReferenceCount() );
+ myGrid->Delete();
+}
+
+//=================================================================================
+// functions : GetNodeObjId, GetNodeVTKId, GetElemObjId, GetElemVTKId
+// purpose : Methods for retrieving VTK IDs by SMDS IDs and vice versa
+//=================================================================================
+vtkIdType SMESH_VisualObj::GetNodeObjId( int theVTKID )
+{
+ return myVTK2SMDSNodes.find(theVTKID) == myVTK2SMDSNodes.end() ? -1 : myVTK2SMDSNodes[theVTKID];
+}
+
+vtkIdType SMESH_VisualObj::GetNodeVTKId( int theObjID )
+{
+ return mySMDS2VTKNodes.find(theObjID) == mySMDS2VTKNodes.end() ? -1 : mySMDS2VTKNodes[theObjID];
+}
+
+vtkIdType SMESH_VisualObj::GetElemObjId( int theVTKID )
+{
+ return myVTK2SMDSElems.find(theVTKID) == myVTK2SMDSElems.end() ? -1 : myVTK2SMDSElems[theVTKID];
+}
+
+vtkIdType SMESH_VisualObj::GetElemVTKId( int theObjID )
+{
+ return mySMDS2VTKElems.find(theObjID) == mySMDS2VTKElems.end() ? -1 : mySMDS2VTKElems[theObjID];
+}
+
+//=================================================================================
+// function : SMESH_VisualObj::createPoints
+// purpose : Create points from nodes
+//=================================================================================
+void SMESH_VisualObj::createPoints( vtkPoints* thePoints )
+{
+ if ( thePoints == 0 )
+ return;
+
+ TEntityList aNodes;
+ vtkIdType nbNodes = GetEntities( SMESH::NODE, aNodes );
+ thePoints->SetNumberOfPoints( nbNodes );
+
+ int nbPoints = 0;
+
+ TEntityList::const_iterator anIter;
+ for ( anIter = aNodes.begin(); anIter != aNodes.end(); ++anIter )
+ {
+ const SMDS_MeshNode* aNode = ( const SMDS_MeshNode* )(*anIter);
+ if ( aNode != 0 )
+ {
+ thePoints->SetPoint( nbPoints, aNode->X(), aNode->Y(), aNode->Z() );
+ int anId = aNode->GetID();
+ mySMDS2VTKNodes.insert( TMapOfIds::value_type( anId, nbPoints ) );
+ myVTK2SMDSNodes.insert( TMapOfIds::value_type( nbPoints, anId ) );
+ nbPoints++;
+ }
+ }
+
+ if ( nbPoints != nbNodes )
+ thePoints->SetNumberOfPoints( nbPoints );
+}
+
+//=================================================================================
+// function : buildPrs
+// purpose : create VTK cells( fill unstructured grid )
+//=================================================================================
+void SMESH_VisualObj::buildPrs()
+{
+ try
+ {
+ mySMDS2VTKNodes.clear();
+ myVTK2SMDSNodes.clear();
+ mySMDS2VTKElems.clear();
+ myVTK2SMDSElems.clear();
+
+ if ( IsNodePrs() )
+ buildNodePrs();
+ else
+ buildElemPrs();
+ }
+ catch( const std::exception& exc )
+ {
+ INFOS("Follow exception was cought:\n\t"<<exc.what());
+ }
+ catch(...)
+ {
+ INFOS("Unknown exception was cought !!!");
+ }
+
+ if( MYDEBUG ) MESSAGE( "Update - myGrid->GetNumberOfCells() = "<<myGrid->GetNumberOfCells() );
+ if( MYDEBUGWITHFILES ) WriteUnstructuredGrid( myGrid,"/tmp/buildPrs" );
+}
+
+//=================================================================================
+// function : buildNodePrs
+// purpose : create VTK cells for nodes
+//=================================================================================
+void SMESH_VisualObj::buildNodePrs()
+{
+ vtkPoints* aPoints = vtkPoints::New();
+ createPoints( aPoints );
+ int nbPoints = aPoints->GetNumberOfPoints();
+ myGrid->SetPoints( aPoints );
+ aPoints->Delete();
+
+ myGrid->SetCells( 0, 0, 0 );
+
+ // Create cells
+
+ /*vtkIdList *anIdList = vtkIdList::New();
+ anIdList->SetNumberOfIds( 1 );
+
+ vtkCellArray *aCells = vtkCellArray::New();
+ aCells->Allocate( 2 * nbPoints, 0 );
+
+ vtkUnsignedCharArray* aCellTypesArray = vtkUnsignedCharArray::New();
+ aCellTypesArray->SetNumberOfComponents( 1 );
+ aCellTypesArray->Allocate( nbPoints );
+
+ for( vtkIdType aCellId = 0; aCellId < nbPoints; aCellId++ )
+ {
+ anIdList->SetId( 0, aCellId );
+ aCells->InsertNextCell( anIdList );
+ aCellTypesArray->InsertNextValue( VTK_VERTEX );
+ }
+
+ vtkIntArray* aCellLocationsArray = vtkIntArray::New();
+ aCellLocationsArray->SetNumberOfComponents( 1 );
+ aCellLocationsArray->SetNumberOfTuples( nbPoints );
+
+ aCells->InitTraversal();
+ for( vtkIdType i = 0, *pts, npts; aCells->GetNextCell( npts, pts ); i++ )
+ aCellLocationsArray->SetValue( i, aCells->GetTraversalLocation( npts ) );
+
+ myGrid->SetCells( aCellTypesArray, aCellLocationsArray, aCells );
+
+ aCellLocationsArray->Delete();
+ aCellTypesArray->Delete();
+ aCells->Delete();
+ anIdList->Delete(); */
+}
+
+//=================================================================================
+// function : buildElemPrs
+// purpose : Create VTK cells for elements
+//=================================================================================
+void SMESH_VisualObj::buildElemPrs()
+{
+ // Create points
+
+ vtkPoints* aPoints = vtkPoints::New();
+ createPoints( aPoints );
+ myGrid->SetPoints( aPoints );
+ aPoints->Delete();
+
+ if ( MYDEBUG )
+ MESSAGE("Update - myGrid->GetNumberOfPoints() = "<<myGrid->GetNumberOfPoints());
+
+ // Calculate cells size
+
+ static SMESH::ElementType aTypes[ 3 ] = { SMESH::EDGE, SMESH::FACE, SMESH::VOLUME };
+
+ // get entity data
+ map< int, int > nbEnts;
+ map< int, TEntityList > anEnts;
+
+ for ( int i = 0; i <= 2; i++ )
+ nbEnts[ aTypes[ i ] ] = GetEntities( aTypes[ i ], anEnts[ aTypes[ i ] ] );
+
+ vtkIdType aCellsSize = 3 * nbEnts[ SMESH::EDGE ];
+
+ for ( int i = 1; i <= 2; i++ ) // iterate through faces and volumes
+ {
+ if ( nbEnts[ aTypes[ i ] ] )
+ {
+ const TEntityList& aList = anEnts[ aTypes[ i ] ];
+ TEntityList::const_iterator anIter;
+ for ( anIter = aList.begin(); anIter != aList.end(); ++anIter )
+ aCellsSize += (*anIter)->NbNodes() + 1;
+ }
+ }
+
+ vtkIdType aNbCells = nbEnts[ SMESH::EDGE ] + nbEnts[ SMESH::FACE ] + nbEnts[ SMESH::VOLUME ];
+
+ if ( MYDEBUG )
+ MESSAGE( "Update - aNbCells = "<<aNbCells<<"; aCellsSize = "<<aCellsSize );
+
+ // Create cells
+
+ vtkCellArray* aConnectivity = vtkCellArray::New();
+ aConnectivity->Allocate( aCellsSize, 0 );
+
+ vtkUnsignedCharArray* aCellTypesArray = vtkUnsignedCharArray::New();
+ aCellTypesArray->SetNumberOfComponents( 1 );
+ aCellTypesArray->Allocate( aNbCells * aCellTypesArray->GetNumberOfComponents() );
+
+ vtkIdList *anIdList = vtkIdList::New();
+ vtkIdType iElem = 0;
+
+ for ( int i = 0; i <= 2; i++ ) // iterate through edges, faces and volumes
+ {
+ if( nbEnts[ aTypes[ i ] ] > 0 )
+ {
+ const TEntityList& aList = anEnts[ aTypes[ i ] ];
+ TEntityList::const_iterator anIter;
+ for ( anIter = aList.begin(); anIter != aList.end(); ++anIter )
+ {
+ const SMDS_MeshElement* anElem = *anIter;
+
+ vtkIdType aNbNodes = anElem->NbNodes();
+ anIdList->SetNumberOfIds( aNbNodes );
+
+ int anId = anElem->GetID();
+
+ mySMDS2VTKElems.insert( TMapOfIds::value_type( anId, iElem ) );
+ myVTK2SMDSElems.insert( TMapOfIds::value_type( iElem, anId ) );
+
+ SMDS_ElemIteratorPtr aNodesIter = anElem->nodesIterator();
+ for( vtkIdType aNodeId = 0; aNodesIter->more(); aNodeId++ )
+ {
+ const SMDS_MeshElement* aNode = aNodesIter->next();
+ anIdList->SetId( aNodeId, mySMDS2VTKNodes[aNode->GetID()] );
+ }
+
+ aConnectivity->InsertNextCell( anIdList );
+ aCellTypesArray->InsertNextValue( getCellType( aTypes[ i ], aNbNodes ) );
+
+ iElem++;
+ }
+ }
+ }
+
+ // Insert cells in grid
+
+ vtkIntArray* aCellLocationsArray = vtkIntArray::New();
+ aCellLocationsArray->SetNumberOfComponents( 1 );
+ aCellLocationsArray->SetNumberOfTuples( aNbCells );
+
+ aConnectivity->InitTraversal();
+ for( vtkIdType idType = 0, *pts, npts; aConnectivity->GetNextCell( npts, pts ); idType++ )
+ aCellLocationsArray->SetValue( idType, aConnectivity->GetTraversalLocation( npts ) );
+
+ myGrid->SetCells( aCellTypesArray, aCellLocationsArray,aConnectivity );
+
+ aCellLocationsArray->Delete();
+ aCellTypesArray->Delete();
+ aConnectivity->Delete();
+ anIdList->Delete();
+}
+
+/*
+ Class : SMESH_MeshObj
+ Description : Class for visualisation of mesh
+*/
+
+//=================================================================================
+// function : SMESH_MeshObj
+// purpose : Constructor
+//=================================================================================
+SMESH_MeshObj::SMESH_MeshObj(SMESH::SMESH_Mesh_ptr theMesh)
+{
+ if ( MYDEBUG )
+ MESSAGE("SMESH_MeshObj - theMesh->_is_nil() = "<<theMesh->_is_nil());
+
+ myMeshServer = SMESH::SMESH_Mesh::_duplicate( theMesh );
+ myMeshServer->Register();
+ myMesh = new SMDS_Mesh();
+}
+
+//=================================================================================
+// function : ~SMESH_MeshObj
+// purpose : Destructor
+//=================================================================================
+SMESH_MeshObj::~SMESH_MeshObj()
+{
+ myMeshServer->Destroy();
+ delete myMesh;
+}
+
+//=================================================================================
+// function : Update
+// purpose : Update mesh and fill grid with new values if necessary
+//=================================================================================
+void SMESH_MeshObj::Update( int theIsClear )
+{
+ // Update SMDS_Mesh on client part
+
+ try
+ {
+ SMESH::log_array_var aSeq = myMeshServer->GetLog( theIsClear );
+ CORBA::Long aLength = aSeq->length();
+
+ if( MYDEBUG ) MESSAGE( "Update: length of the script is "<<aLength );
+
+ if( !aLength )
+ return;
+
+ for ( CORBA::Long anId = 0; anId < aLength; anId++)
+ {
+ const SMESH::double_array& aCoords = aSeq[anId].coords;
+ const SMESH::long_array& anIndexes = aSeq[anId].indexes;
+ CORBA::Long anElemId = 0, aNbElems = aSeq[anId].number;
+ SMDS_MeshElement* anElem = NULL;
+ CORBA::Long aCommand = aSeq[anId].commandType;
+
+ switch(aCommand)
+ {
+ case SMESH::ADD_NODE : AddNodesWithID ( myMesh, aSeq, anId ); break;
+ case SMESH::ADD_EDGE : AddEdgesWithID ( myMesh, aSeq, anId ); break;
+ case SMESH::ADD_TRIANGLE : AddTriasWithID ( myMesh, aSeq, anId ); break;
+ case SMESH::ADD_QUADRANGLE : AddQuadsWithID ( myMesh, aSeq, anId ); break;
+ case SMESH::ADD_TETRAHEDRON: AddTetrasWithID ( myMesh, aSeq, anId ); break;
+ case SMESH::ADD_PYRAMID : AddPiramidsWithID( myMesh, aSeq, anId ); break;
+ case SMESH::ADD_PRISM : AddPrismsWithID ( myMesh, aSeq, anId ); break;
+ case SMESH::ADD_HEXAHEDRON : AddHexasWithID ( myMesh, aSeq, anId ); break;
+
+ case SMESH::REMOVE_NODE:
+ for( ; anElemId < aNbElems; anElemId++ )
+ myMesh->RemoveNode( FindNode( myMesh, anIndexes[anElemId] ) );
+ break;
+
+ case SMESH::REMOVE_ELEMENT:
+ for( ; anElemId < aNbElems; anElemId++ )
+ myMesh->RemoveElement( FindElement( myMesh, anIndexes[anElemId] ) );
+ break;
+ }
+ }
+ }
+ catch ( SALOME::SALOME_Exception& exc )
+ {
+ INFOS("Follow exception was cought:\n\t"<<exc.details.text);
+ }
+ catch( const std::exception& exc)
+ {
+ INFOS("Follow exception was cought:\n\t"<<exc.what());
+ }
+ catch(...)
+ {
+ INFOS("Unknown exception was cought !!!");
+ }
+
+ if ( MYDEBUG )
+ {
+ MESSAGE("Update - myMesh->NbNodes() = "<<myMesh->NbNodes());
+ MESSAGE("Update - myMesh->NbEdges() = "<<myMesh->NbEdges());
+ MESSAGE("Update - myMesh->NbFaces() = "<<myMesh->NbFaces());
+ MESSAGE("Update - myMesh->NbVolumes() = "<<myMesh->NbVolumes());
+ }
+
+ // Fill unstructured grid
+ buildPrs();
+}
+
+//=================================================================================
+// function : GetElemDimension
+// purpose : Get dimension of element
+//=================================================================================
+int SMESH_MeshObj::GetElemDimension( const int theObjId )
+{
+ const SMDS_MeshElement* anElem = myMesh->FindElement( theObjId );
+ if ( anElem == 0 )
+ return 0;
+
+ int aType = anElem->GetType();
+ switch ( aType )
+ {
+ case SMDSAbs_Edge : return 1;
+ case SMDSAbs_Face : return 2;
+ case SMDSAbs_Volume: return 3;
+ default : return 0;
+ }
+}
+
+//=================================================================================
+// function : GetEntities
+// purpose : Get entities of specified type. Return number of entities
+//=================================================================================
+int SMESH_MeshObj::GetNbEntities( const SMESH::ElementType theType) const
+{
+ switch ( theType )
+ {
+ case SMESH::NODE:
+ {
+ return myMesh->NbNodes();
+ }
+ break;
+ case SMESH::EDGE:
+ {
+ return myMesh->NbEdges();
+ }
+ break;
+ case SMESH::FACE:
+ {
+ return myMesh->NbFaces();
+ }
+ break;
+ case SMESH::VOLUME:
+ {
+ return myMesh->NbVolumes();
+ }
+ break;
+ default:
+ return 0;
+ break;
+ }
+}
+
+int SMESH_MeshObj::GetEntities( const SMESH::ElementType theType, TEntityList& theObjs ) const
+{
+ theObjs.clear();
+
+ switch ( theType )
+ {
+ case SMESH::NODE:
+ {
+ SMDS_NodeIteratorPtr anIter = myMesh->nodesIterator();
+ while ( anIter->more() ) theObjs.push_back( anIter->next() );
+ }
+ break;
+ case SMESH::EDGE:
+ {
+ SMDS_EdgeIteratorPtr anIter = myMesh->edgesIterator();
+ while ( anIter->more() ) theObjs.push_back( anIter->next() );
+ }
+ break;
+ case SMESH::FACE:
+ {
+ SMDS_FaceIteratorPtr anIter = myMesh->facesIterator();
+ while ( anIter->more() ) theObjs.push_back( anIter->next() );
+ }
+ break;
+ case SMESH::VOLUME:
+ {
+ SMDS_VolumeIteratorPtr anIter = myMesh->volumesIterator();
+ while ( anIter->more() ) theObjs.push_back( anIter->next() );
+ }
+ break;
+ default:
+ break;
+ }
+
+ return theObjs.size();
+}
+
+//=================================================================================
+// function : UpdateFunctor
+// purpose : Update functor in accordance with current mesh
+//=================================================================================
+void SMESH_MeshObj::UpdateFunctor( SMESH::Functor_ptr f )
+{
+ f->SetMesh( myMeshServer );
+}
+
+//=================================================================================
+// function : IsNodePrs
+// purpose : Return true if node presentation is used
+//=================================================================================
+bool SMESH_MeshObj::IsNodePrs() const
+{
+ return myMesh->NbEdges() == 0 &&myMesh->NbFaces() == 0 &&myMesh->NbVolumes() == 0 ;
+}
+
+
+/*
+ Class : SMESH_SubMeshObj
+ Description : Base class for visualisation of submeshes and groups
+*/
+
+//=================================================================================
+// function : SMESH_SubMeshObj
+// purpose : Constructor
+//=================================================================================
+SMESH_SubMeshObj::SMESH_SubMeshObj( SMESH_MeshObj* theMeshObj )
+{
+ if ( MYDEBUG ) MESSAGE( "SMESH_SubMeshObj - theMeshObj = " << theMeshObj );
+
+ myMeshObj = theMeshObj;
+}
+
+SMESH_SubMeshObj::~SMESH_SubMeshObj()
+{
+}
+
+//=================================================================================
+// function : GetElemDimension
+// purpose : Get dimension of element
+//=================================================================================
+int SMESH_SubMeshObj::GetElemDimension( const int theObjId )
+{
+ return myMeshObj == 0 ? 0 : myMeshObj->GetElemDimension( theObjId );
+}
+
+//=================================================================================
+// function : UpdateFunctor
+// purpose : Update functor in accordance with current mesh
+//=================================================================================
+void SMESH_SubMeshObj::UpdateFunctor( SMESH::Functor_ptr f )
+{
+ f->SetMesh( myMeshObj->GetMeshServer() );
+}
+
+//=================================================================================
+// function : UpdateFunctor
+// purpose : Update mesh object and fill grid with new values
+//=================================================================================
+void SMESH_SubMeshObj::Update( int theIsClear )
+{
+ myMeshObj->Update( theIsClear );
+ buildPrs();
+}
+
+
+/*
+ Class : SMESH_GroupObj
+ Description : Class for visualisation of groups
+*/
+
+//=================================================================================
+// function : SMESH_GroupObj
+// purpose : Constructor
+//=================================================================================
+SMESH_GroupObj::SMESH_GroupObj( SMESH::SMESH_Group_ptr theGroup,
+ SMESH_MeshObj* theMeshObj )
+: SMESH_SubMeshObj( theMeshObj ),
+ myGroupServer( SMESH::SMESH_Group::_duplicate(theGroup) )
+{
+ if ( MYDEBUG ) MESSAGE("SMESH_GroupObj - theGroup->_is_nil() = "<<theGroup->_is_nil());
+ myGroupServer->Register();
+}
+
+SMESH_GroupObj::~SMESH_GroupObj()
+{
+ if ( MYDEBUG ) MESSAGE("~SMESH_GroupObj");
+ myGroupServer->Destroy();
+}
+
+//=================================================================================
+// function : IsNodePrs
+// purpose : Return true if node presentation is used
+//=================================================================================
+bool SMESH_GroupObj::IsNodePrs() const
+{
+ return myGroupServer->GetType() == SMESH::NODE;
+}
+
+//=================================================================================
+// function : getNodesFromElems
+// purpose : Retrieve nodes from elements
+//=================================================================================
+static int getNodesFromElems( SMESH::long_array_var& theElemIds,
+ const SMDS_Mesh* theMesh,
+ std::list<const SMDS_MeshElement*>& theResList )
+{
+ set<const SMDS_MeshElement*> aNodeSet;
+
+ for ( CORBA::Long i = 0, n = theElemIds->length(); i < n; i++ )
+ {
+ const SMDS_MeshElement* anElem = theMesh->FindElement( theElemIds[ i ] );
+ if ( anElem != 0 )
+ {
+ SMDS_ElemIteratorPtr anIter = anElem->nodesIterator();
+ while ( anIter->more() )
+ {
+ const SMDS_MeshElement* aNode = anIter->next();
+ if ( aNode != 0 )
+ aNodeSet.insert( aNode );
+ }
+ }
+ }
+
+ set<const SMDS_MeshElement*>::const_iterator anIter;
+ for ( anIter = aNodeSet.begin(); anIter != aNodeSet.end(); ++anIter )
+ theResList.push_back( *anIter );
+
+ return theResList.size();
+}
+
+//=================================================================================
+// function : getPointers
+// purpose : Get std::list<const SMDS_MeshElement*> from list of IDs
+//=================================================================================
+static int getPointers( const SMESH::ElementType theRequestType,
+ SMESH::long_array_var& theElemIds,
+ const SMDS_Mesh* theMesh,
+ std::list<const SMDS_MeshElement*>& theResList )
+{
+ for ( CORBA::Long i = 0, n = theElemIds->length(); i < n; i++ )
+ {
+ const SMDS_MeshElement* anElem = theRequestType == SMESH::NODE
+ ? theMesh->FindNode( theElemIds[ i ] ) : theMesh->FindElement( theElemIds[ i ] );
+
+ if ( anElem != 0 )
+ theResList.push_back( anElem );
+ }
+
+ return theResList.size();
+}
+
+
+//=================================================================================
+// function : GetEntities
+// purpose : Get entities of specified type. Return number of entities
+//=================================================================================
+int SMESH_GroupObj::GetNbEntities( const SMESH::ElementType theType) const
+{
+ if(myGroupServer->GetType() == theType){
+ return myGroupServer->Size();
+ }
+ return 0;
+}
+
+int SMESH_GroupObj::GetEntities( const SMESH::ElementType theType, TEntityList& theResList ) const
+{
+ theResList.clear();
+ SMDS_Mesh* aMesh = myMeshObj->GetMesh();
+
+ if ( myGroupServer->Size() == 0 || aMesh == 0 )
+ return 0;
+
+ SMESH::ElementType aGrpType = myGroupServer->GetType();
+ SMESH::long_array_var anIds = myGroupServer->GetListOfID();
+
+ if ( aGrpType == theType )
+ return getPointers( theType, anIds, aMesh, theResList );
+ else if ( theType == SMESH::NODE )
+ return getNodesFromElems( anIds, aMesh, theResList );
+ else
+ return 0;
+}
+
+
+
+/*
+ Class : SMESH_subMeshObj
+ Description : Class for visualisation of submeshes
+*/
+
+//=================================================================================
+// function : SMESH_subMeshObj
+// purpose : Constructor
+//=================================================================================
+SMESH_subMeshObj::SMESH_subMeshObj( SMESH::SMESH_subMesh_ptr theSubMesh,
+ SMESH_MeshObj* theMeshObj )
+: SMESH_SubMeshObj( theMeshObj ),
+ mySubMeshServer( SMESH::SMESH_subMesh::_duplicate( theSubMesh ) )
+{
+ if ( MYDEBUG ) MESSAGE( "SMESH_subMeshObj - theSubMesh->_is_nil() = " << theSubMesh->_is_nil() );
+
+ mySubMeshServer->Register();
+}
+
+SMESH_subMeshObj::~SMESH_subMeshObj()
+{
+ if ( MYDEBUG ) MESSAGE( "~SMESH_subMeshObj" );
+ mySubMeshServer->Destroy();
+}
+
+//=================================================================================
+// function : GetEntities
+// purpose : Get entities of specified type. Return number of entities
+//=================================================================================
+int SMESH_subMeshObj::GetNbEntities( const SMESH::ElementType theType) const
+{
+ switch ( theType )
+ {
+ case SMESH::NODE:
+ {
+ return mySubMeshServer->GetNumberOfNodes();
+ }
+ break;
+ case SMESH::EDGE:
+ case SMESH::FACE:
+ case SMESH::VOLUME:
+ {
+ SMESH::long_array_var anIds = mySubMeshServer->GetElementsByType( theType );
+ return anIds->length();
+ }
+ default:
+ return 0;
+ break;
+ }
+}
+
+int SMESH_subMeshObj::GetEntities( const SMESH::ElementType theType, TEntityList& theResList ) const
+{
+ theResList.clear();
+
+ SMDS_Mesh* aMesh = myMeshObj->GetMesh();
+ if ( aMesh == 0 )
+ return 0;
+
+ bool isNodal = IsNodePrs();
+
+ if ( isNodal )
+ {
+ if ( theType == SMESH::NODE )
+ {
+ SMESH::long_array_var anIds = mySubMeshServer->GetNodesId();
+ return getPointers( SMESH::NODE, anIds, aMesh, theResList );
+ }
+ }
+ else
+ {
+ if ( theType == SMESH::NODE )
+ {
+ SMESH::long_array_var anIds = mySubMeshServer->GetElementsId();
+ return getNodesFromElems( anIds, aMesh, theResList );
+ }
+ else
+ {
+ SMESH::long_array_var anIds = mySubMeshServer->GetElementsByType( theType );
+ return getPointers( theType, anIds, aMesh, theResList );
+ }
+ }
+
+ return 0;
+}
+
+//=================================================================================
+// function : IsNodePrs
+// purpose : Return true if node presentation is used
+//=================================================================================
+bool SMESH_subMeshObj::IsNodePrs() const
+{
+ return mySubMeshServer->GetNumberOfElements() == 0;
+}
+
+
+
+
+
+
+
+
+
+
+
+
--- /dev/null
+// SMESH OBJECT : interactive object for SMESH visualization
+//
+// Copyright (C) 2003 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
+// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
+//
+// This library 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.
+//
+// This library 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 this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+//
+// See http://www.opencascade.org/SALOME/ or email : webmaster.salome@opencascade.org
+//
+//
+//
+// File : SMESH_Object.h
+// Author : Nicolas REJNERI
+// Module : SMESH
+// $Header$
+
+#ifndef SMESH_OBJECT_H
+#define SMESH_OBJECT_H
+
+// IDL Headers
+#include <SALOMEconfig.h>
+#include CORBA_SERVER_HEADER(SMESH_Mesh)
+#include CORBA_SERVER_HEADER(SMESH_Group)
+#include CORBA_SERVER_HEADER(SMESH_Filter)
+
+#include <map>
+#include <list>
+#include <boost/shared_ptr.hpp>
+#include <vtkSystemIncludes.h>
+
+class vtkUnstructuredGrid;
+class vtkPoints;
+class SALOME_ExtractUnstructuredGrid;
+
+class SMESH_Actor;
+class SMDS_Mesh;
+class SMDS_MeshNode;
+class SMDS_MeshElement;
+
+class SMESH_VisualObj;
+typedef boost::shared_ptr<SMESH_VisualObj> TVisualObjPtr;
+
+
+/*
+ Class : SMESH_VisualObj
+ Description : Base class for all mesh objects to be visuilised
+*/
+
+class SMESH_VisualObj
+{
+protected:
+
+ typedef std::list<const SMDS_MeshElement*> TEntityList;
+ typedef std::map<vtkIdType,vtkIdType> TMapOfIds;
+
+public:
+ SMESH_VisualObj();
+ virtual ~SMESH_VisualObj();
+
+ virtual void Update( int theIsClear = true ) = 0;
+ virtual void UpdateFunctor( SMESH::Functor_ptr theFunctor ) = 0;
+ virtual int GetElemDimension( const int theObjId ) = 0;
+
+ virtual int GetNbEntities( const SMESH::ElementType) const = 0;
+ virtual int GetEntities( const SMESH::ElementType, TEntityList& ) const = 0;
+ virtual bool IsNodePrs() const = 0;
+
+ vtkUnstructuredGrid* GetUnstructuredGrid() { return myGrid; }
+
+ vtkIdType GetNodeObjId( int theVTKID );
+ vtkIdType GetNodeVTKId( int theObjID );
+ vtkIdType GetElemObjId( int theVTKID );
+ vtkIdType GetElemVTKId( int theObjID );
+
+protected:
+
+ void createPoints( vtkPoints* );
+ void buildPrs();
+ void buildNodePrs();
+ void buildElemPrs();
+
+private:
+
+ TMapOfIds mySMDS2VTKNodes;
+ TMapOfIds myVTK2SMDSNodes;
+ TMapOfIds mySMDS2VTKElems;
+ TMapOfIds myVTK2SMDSElems;
+
+ vtkUnstructuredGrid* myGrid;
+};
+
+
+/*
+ Class : SMESH_MeshObj
+ Description : Class for visualisation of mesh
+*/
+
+class SMESH_MeshObj: public SMESH_VisualObj
+{
+public:
+
+ SMESH_MeshObj( SMESH::SMESH_Mesh_ptr );
+ virtual ~SMESH_MeshObj();
+
+ virtual void Update( int theIsClear = true );
+
+ virtual int GetNbEntities( const SMESH::ElementType) const;
+ virtual int GetEntities( const SMESH::ElementType, TEntityList& ) const;
+ virtual bool IsNodePrs() const;
+
+ virtual int GetElemDimension( const int theObjId );
+
+ virtual void UpdateFunctor( SMESH::Functor_ptr f );
+
+ SMESH::SMESH_Mesh_ptr GetMeshServer() { return myMeshServer.in(); }
+ SMDS_Mesh* GetMesh() { return myMesh; }
+
+protected:
+
+ SMESH::SMESH_Mesh_var myMeshServer;
+ SMDS_Mesh* myMesh;
+};
+
+
+/*
+ Class : SMESH_SubMeshObj
+ Description : Base class for visualisation of submeshes and groups
+*/
+
+class SMESH_SubMeshObj: public SMESH_VisualObj
+{
+public:
+
+ SMESH_SubMeshObj(SMESH_MeshObj* theMeshObj);
+ virtual ~SMESH_SubMeshObj();
+
+ virtual void Update( int theIsClear = true );
+
+ virtual void UpdateFunctor( SMESH::Functor_ptr );
+ virtual int GetElemDimension( const int theObjId );
+
+protected:
+
+ SMESH_MeshObj* myMeshObj;
+};
+
+
+/*
+ Class : SMESH_GroupObj
+ Description : Class for visualisation of groups
+*/
+
+class SMESH_GroupObj: public SMESH_SubMeshObj
+{
+public:
+ SMESH_GroupObj( SMESH::SMESH_Group_ptr, SMESH_MeshObj* );
+ virtual ~SMESH_GroupObj();
+
+ virtual int GetNbEntities( const SMESH::ElementType) const;
+ virtual int GetEntities( const SMESH::ElementType, TEntityList& ) const;
+ virtual bool IsNodePrs() const;
+
+private:
+
+ SMESH::SMESH_Group_var myGroupServer;
+};
+
+
+/*
+ Class : SMESH_subMeshObj
+ Description : Class for visualisation of submeshes
+*/
+
+class SMESH_subMeshObj : public SMESH_SubMeshObj
+{
+public:
+
+ SMESH_subMeshObj( SMESH::SMESH_subMesh_ptr,
+ SMESH_MeshObj* );
+ virtual ~SMESH_subMeshObj();
+
+ virtual int GetNbEntities( const SMESH::ElementType) const;
+ virtual int GetEntities( const SMESH::ElementType, TEntityList& ) const;
+ virtual bool IsNodePrs() const;
+
+protected:
+
+ SMESH::SMESH_subMesh_var mySubMeshServer;
+};
+
+
+extern void WriteUnstructuredGrid(vtkUnstructuredGrid* theGrid, const char* theFileName);
+
+
+#endif
#SMDS_MeshNodeIDFactory.hxx
# additionnal information to compil and link file
-CPPFLAGS += -I${KERNEL_ROOT_DIR}/include/salome
+CPPFLAGS += -I${KERNEL_ROOT_DIR}/include/salome $(BOOST_CPPFLAGS)
CXXFLAGS += -I${KERNEL_ROOT_DIR}/include/salome
LDFLAGS += -L${KERNEL_ROOT_DIR}/lib/salome
SMDS_TypeOfPosition GetTypeOfPosition() const;
void SetUParameter(double aUparam);
double GetUParameter() const;
- ~SMDS_EdgePosition();
private:
return SMDSAbs_Face;
}
-SMDS_Iterator<const SMDS_MeshElement *> * SMDS_FaceOfEdges::
+class SMDS_FaceOfEdges_MyIterator:public SMDS_ElemIterator
+{
+ const vector<const SMDS_MeshEdge*>& mySet;
+ int index;
+ public:
+ SMDS_FaceOfEdges_MyIterator(const vector<const SMDS_MeshEdge*>& s):
+ mySet(s),index(0) {}
+
+ bool more()
+ {
+ return index<mySet.size();
+ }
+
+ const SMDS_MeshElement* next()
+ {
+ index++;
+ return mySet[index-1];
+ }
+};
+SMDS_ElemIteratorPtr SMDS_FaceOfEdges::
elementsIterator(SMDSAbs_ElementType type) const
{
- class MyIterator:public SMDS_Iterator<const SMDS_MeshElement*>
- {
- const vector<const SMDS_MeshEdge*>& mySet;
- int index;
- public:
- MyIterator(const vector<const SMDS_MeshEdge*>& s):mySet(s),index(0)
- {}
-
- bool more()
- {
- return index<mySet.size();
- }
-
- const SMDS_MeshElement* next()
- {
- index++;
- return mySet[index-1];
- }
- };
-
switch(type)
{
- case SMDSAbs_Face:return SMDS_MeshElement::elementsIterator(SMDSAbs_Face);
- case SMDSAbs_Edge:return new MyIterator(myEdges);
- default:return new SMDS_IteratorOfElements(this,type,new MyIterator(myEdges));
+ case SMDSAbs_Face:
+ return SMDS_MeshElement::elementsIterator(SMDSAbs_Face);
+ case SMDSAbs_Edge:
+ return SMDS_ElemIteratorPtr(new SMDS_FaceOfEdges_MyIterator(myEdges));
+ default:
+ return SMDS_ElemIteratorPtr
+ (new SMDS_IteratorOfElements
+ (this,type, SMDS_ElemIteratorPtr(new SMDS_FaceOfEdges_MyIterator(myEdges))));
}
}
-SMDS_FaceOfEdges::SMDS_FaceOfEdges(SMDS_MeshEdge* edge1, SMDS_MeshEdge* edge2,
- SMDS_MeshEdge* edge3)
+SMDS_FaceOfEdges::SMDS_FaceOfEdges(const SMDS_MeshEdge* edge1,
+ const SMDS_MeshEdge* edge2,
+ const SMDS_MeshEdge* edge3)
{
myEdges.resize(3);
myEdges[0]=edge1;
myEdges[2]=edge3;
}
-SMDS_FaceOfEdges::SMDS_FaceOfEdges(SMDS_MeshEdge* edge1, SMDS_MeshEdge* edge2,
- SMDS_MeshEdge* edge3, SMDS_MeshEdge* edge4)
+SMDS_FaceOfEdges::SMDS_FaceOfEdges(const SMDS_MeshEdge* edge1,
+ const SMDS_MeshEdge* edge2,
+ const SMDS_MeshEdge* edge3,
+ const SMDS_MeshEdge* edge4)
{
myEdges.resize(4);
myEdges[0]=edge1;
/*bool operator<(const SMDS_FaceOfEdges& f1, const SMDS_FaceOfEdges& f2)
{
set<SMDS_MeshNode> set1,set2;
- SMDS_Iterator<const SMDS_MeshElement*> * it;
+ SMDS_ElemIteratorPtr it;
const SMDS_MeshNode * n;
it=f1.nodesIterator();
{
public:
void Print(ostream & OS) const;
- SMDS_FaceOfEdges(SMDS_MeshEdge* edge1, SMDS_MeshEdge* edge2,
- SMDS_MeshEdge* edge3);
- SMDS_FaceOfEdges(SMDS_MeshEdge* edge1, SMDS_MeshEdge* edge2,
- SMDS_MeshEdge* edge3, SMDS_MeshEdge* edge4);
+ SMDS_FaceOfEdges(const SMDS_MeshEdge* edge1,
+ const SMDS_MeshEdge* edge2,
+ const SMDS_MeshEdge* edge3);
+ SMDS_FaceOfEdges(const SMDS_MeshEdge* edge1,
+ const SMDS_MeshEdge* edge2,
+ const SMDS_MeshEdge* edge3,
+ const SMDS_MeshEdge* edge4);
SMDSAbs_ElementType GetType() const;
int NbEdges() const;
// friend bool operator<(const SMDS_FaceOfEdges& e1, const SMDS_FaceOfEdges& e2);
protected:
- SMDS_Iterator<const SMDS_MeshElement *> *
+ SMDS_ElemIteratorPtr
elementsIterator(SMDSAbs_ElementType type) const;
private:
OS << myNodes[i] << ") " << endl;
}
-SMDS_Iterator<const SMDS_MeshElement *> * SMDS_FaceOfNodes::
+class SMDS_FaceOfNodes_MyIterator:public SMDS_ElemIterator
+{
+ const vector<const SMDS_MeshNode*>& mySet;
+ int index;
+ public:
+ SMDS_FaceOfNodes_MyIterator(const vector<const SMDS_MeshNode*>& s):
+ mySet(s),index(0) {}
+
+ bool more()
+ {
+ return index<mySet.size();
+ }
+
+ const SMDS_MeshElement* next()
+ {
+ index++;
+ return mySet[index-1];
+ }
+};
+SMDS_ElemIteratorPtr SMDS_FaceOfNodes::
elementsIterator(SMDSAbs_ElementType type) const
{
- class MyIterator:public SMDS_Iterator<const SMDS_MeshElement*>
- {
- const vector<const SMDS_MeshNode*>& mySet;
- int index;
- public:
- MyIterator(const vector<const SMDS_MeshNode*>& s):mySet(s),index(0)
- {}
-
- bool more()
- {
- return index<mySet.size();
- }
-
- const SMDS_MeshElement* next()
- {
- index++;
- return mySet[index-1];
- }
- };
-
- switch(type)
- {
- case SMDSAbs_Face:return SMDS_MeshElement::elementsIterator(SMDSAbs_Face);
- case SMDSAbs_Node:return new MyIterator(myNodes);
- case SMDSAbs_Edge:
- MESSAGE("Error : edge iterator for SMDS_FaceOfNodes not implemented");
- break;
- default:return new SMDS_IteratorOfElements(this,type,new MyIterator(myNodes));
- }
+ switch(type)
+ {
+ case SMDSAbs_Face:
+ return SMDS_MeshElement::elementsIterator(SMDSAbs_Face);
+ case SMDSAbs_Node:
+ return SMDS_ElemIteratorPtr(new SMDS_FaceOfNodes_MyIterator(myNodes));
+ case SMDSAbs_Edge:
+ MESSAGE("Error : edge iterator for SMDS_FaceOfNodes not implemented");
+ break;
+ default:
+ return SMDS_ElemIteratorPtr
+ (new SMDS_IteratorOfElements
+ (this,type,SMDS_ElemIteratorPtr(new SMDS_FaceOfNodes_MyIterator(myNodes))));
+ }
}
-SMDS_FaceOfNodes::SMDS_FaceOfNodes(SMDS_MeshNode* node1, SMDS_MeshNode* node2,
- SMDS_MeshNode* node3)
+SMDS_FaceOfNodes::SMDS_FaceOfNodes(const SMDS_MeshNode* node1,
+ const SMDS_MeshNode* node2,
+ const SMDS_MeshNode* node3)
{
myNodes.resize(3);
myNodes[0]=node1;
myNodes[2]=node3;
}
-SMDS_FaceOfNodes::SMDS_FaceOfNodes(SMDS_MeshNode* node1, SMDS_MeshNode* node2,
- SMDS_MeshNode* node3, SMDS_MeshNode* node4)
+SMDS_FaceOfNodes::SMDS_FaceOfNodes(const SMDS_MeshNode* node1,
+ const SMDS_MeshNode* node2,
+ const SMDS_MeshNode* node3,
+ const SMDS_MeshNode* node4)
{
myNodes.resize(4);
myNodes[0]=node1;
/*bool operator<(const SMDS_FaceOfNodes& f1, const SMDS_FaceOfNodes& f2)
{
set<SMDS_MeshNode> set1,set2;
- SMDS_Iterator<const SMDS_MeshElement*> * it;
+ SMDS_ElemIteratorPtr it;
const SMDS_MeshNode * n;
it=f1.nodesIterator();
{
public:
void Print(ostream & OS) const;
- SMDS_FaceOfNodes(SMDS_MeshNode* node1, SMDS_MeshNode* node2,
- SMDS_MeshNode* node3);
- SMDS_FaceOfNodes(SMDS_MeshNode* node1, SMDS_MeshNode* node2,
- SMDS_MeshNode* node3, SMDS_MeshNode* node4);
+ SMDS_FaceOfNodes(const SMDS_MeshNode* node1,
+ const SMDS_MeshNode* node2,
+ const SMDS_MeshNode* node3);
+ SMDS_FaceOfNodes(const SMDS_MeshNode* node1,
+ const SMDS_MeshNode* node2,
+ const SMDS_MeshNode* node3,
+ const SMDS_MeshNode* node4);
int NbEdges() const;
int NbFaces() const;
int NbNodes() const;
protected:
- SMDS_Iterator<const SMDS_MeshElement *> *
+ SMDS_ElemIteratorPtr
elementsIterator(SMDSAbs_ElementType type) const;
private:
/// 5,1 and 7,3 are an edges.
///////////////////////////////////////////////////////////////////////////////
SMDS_HexahedronOfNodes::SMDS_HexahedronOfNodes(
- SMDS_MeshNode * node1,
- SMDS_MeshNode * node2,
- SMDS_MeshNode * node3,
- SMDS_MeshNode * node4,
- SMDS_MeshNode * node5,
- SMDS_MeshNode * node6,
- SMDS_MeshNode * node7,
- SMDS_MeshNode * node8)
+ const SMDS_MeshNode * node1,
+ const SMDS_MeshNode * node2,
+ const SMDS_MeshNode * node3,
+ const SMDS_MeshNode * node4,
+ const SMDS_MeshNode * node5,
+ const SMDS_MeshNode * node6,
+ const SMDS_MeshNode * node7,
+ const SMDS_MeshNode * node8)
{
myNodes[0]=node1;
myNodes[1]=node2;
return 12;
}
-SMDS_Iterator<const SMDS_MeshElement *> * SMDS_HexahedronOfNodes::
+SMDS_ElemIteratorPtr SMDS_HexahedronOfNodes::
elementsIterator(SMDSAbs_ElementType type) const
{
- switch(type)
- {
- case SMDSAbs_Volume:
- return SMDS_MeshElement::elementsIterator(SMDSAbs_Volume);
- case SMDSAbs_Node:
- return new SMDS_IteratorOfArray<const SMDS_MeshElement *, 8,
- const SMDS_MeshNode*>(myNodes);
- default: MESSAGE("ERROR : Iterator not implemented");
- }
+ switch(type)
+ {
+ case SMDSAbs_Volume:
+ return SMDS_MeshElement::elementsIterator(SMDSAbs_Volume);
+ case SMDSAbs_Node:
+ return SMDS_ElemIteratorPtr (new SMDS_IteratorOfArray<const SMDS_MeshElement *, 8,
+ const SMDS_MeshNode*>(myNodes));
+ default: MESSAGE("ERROR : Iterator not implemented");
+ }
}
SMDSAbs_ElementType SMDS_HexahedronOfNodes::GetType() const
public:
SMDS_HexahedronOfNodes(
- SMDS_MeshNode * node1,
- SMDS_MeshNode * node2,
- SMDS_MeshNode * node3,
- SMDS_MeshNode * node4,
- SMDS_MeshNode * node5,
- SMDS_MeshNode * node6,
- SMDS_MeshNode * node7,
- SMDS_MeshNode * node8);
+ const SMDS_MeshNode * node1,
+ const SMDS_MeshNode * node2,
+ const SMDS_MeshNode * node3,
+ const SMDS_MeshNode * node4,
+ const SMDS_MeshNode * node5,
+ const SMDS_MeshNode * node6,
+ const SMDS_MeshNode * node7,
+ const SMDS_MeshNode * node8);
void Print(ostream & OS) const;
int NbFaces() const;
int NbEdges() const;
SMDSAbs_ElementType GetType() const;
protected:
- SMDS_Iterator<const SMDS_MeshElement *> *
+ SMDS_ElemIteratorPtr
elementsIterator(SMDSAbs_ElementType type) const;
const SMDS_MeshNode * myNodes[8];
};
virtual VALUE next()=0;
/// Delete the current element and step to the next one
- virtual void remove(){};
+ virtual void remove(){}
+
+ /// Provide virtual destructor just for case if some derived iterator
+ /// must have a destructor
+ virtual ~SMDS_Iterator(){}
};
#endif
{
if(t1Iterator->more())
{
- if(t2Iterator!=NULL) delete t2Iterator;
t2Iterator=t1Iterator->next()->elementsIterator(myType);
return subMore();
}
const SMDS_MeshElement * SMDS_IteratorOfElements::subNext()
{
if((t2Iterator==NULL)||(!t2Iterator->more()))
- {
if(t1Iterator->more())
- {
- if(t2Iterator!=NULL) delete t2Iterator;
t2Iterator=t1Iterator->next()->elementsIterator(myType);
- }
- }
return t2Iterator->next();
}
/// to the element element. it is the iterator to get connectivity of element
//////////////////////////////////////////////////////////////////////////////
SMDS_IteratorOfElements::SMDS_IteratorOfElements(const SMDS_MeshElement * element,
- SMDSAbs_ElementType type, SMDS_Iterator<const SMDS_MeshElement *>* it)
- :t1Iterator(it), t2Iterator(NULL), myType(type), myElement(element),
- myProxyElement(NULL)
+ SMDSAbs_ElementType type,
+ const SMDS_ElemIteratorPtr& it)
+ : t1Iterator(it),
+ t2Iterator(SMDS_ElemIteratorPtr((SMDS_ElemIterator*)NULL)),
+ myType(type), myElement(element),
+ myProxyElement(NULL)
{
while(subMore())
alreadyReturnedElements.insert(subNext());
if(myReverseIteration)
{
- SMDS_Iterator<const SMDS_MeshElement*> * it=
+ SMDS_ElemIteratorPtr it=
myProxyElement->elementsIterator(myElement->GetType());
while(it->more())
{
myProxyElement=NULL;
return e;
}
-
-SMDS_IteratorOfElements::~SMDS_IteratorOfElements()
-{
- delete t1Iterator;
- if(t2Iterator!=NULL) delete t2Iterator;
-}
using namespace std;
-class SMDS_IteratorOfElements:public SMDS_Iterator<const SMDS_MeshElement *>
+class SMDS_IteratorOfElements:public SMDS_ElemIterator
{
public:
/////////////////////////////////////////////////////////////////////////////
/// to the element element. it is the iterator to get connectivity of element
//////////////////////////////////////////////////////////////////////////////
SMDS_IteratorOfElements(const SMDS_MeshElement * element,
- SMDSAbs_ElementType type, SMDS_Iterator<const SMDS_MeshElement *>* it);
+ SMDSAbs_ElementType type,
+ const SMDS_ElemIteratorPtr& it);
bool more();
const SMDS_MeshElement * next();
- ~SMDS_IteratorOfElements();
private:
- SMDS_Iterator<const SMDS_MeshElement *> * t2Iterator;
- SMDS_Iterator<const SMDS_MeshElement *> * t1Iterator;
+ SMDS_ElemIteratorPtr t2Iterator;
+ SMDS_ElemIteratorPtr t1Iterator;
SMDSAbs_ElementType myType;
const SMDS_MeshElement * myProxyElement;
const SMDS_MeshElement * myElement;
SMDS_MeshNode * SMDS_Mesh::AddNode(double x, double y, double z)
{
- return AddNodeWithID(x,y,z,myNodeIDFactory->GetFreeID());
+ return SMDS_Mesh::AddNodeWithID(x,y,z,myNodeIDFactory->GetFreeID());
}
///////////////////////////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////////////////////
SMDS_MeshNode * SMDS_Mesh::AddNodeWithID(double x, double y, double z, int ID)
{
- // find the MeshNode corresponding to ID
- const SMDS_MeshElement *node = myNodeIDFactory->MeshElement(ID);
-
- if (node == NULL)
- {
- SMDS_MeshNode * node=new SMDS_MeshNode(x, y, z);
- myNodes.insert(node);
- myNodeIDFactory->BindID(ID,node);
- return node;
- }
- else
- return NULL;
+ // find the MeshNode corresponding to ID
+ const SMDS_MeshElement *node = myNodeIDFactory->MeshElement(ID);
+ if(!node){
+ SMDS_MeshNode * node=new SMDS_MeshNode(x, y, z);
+ myNodes.insert(node);
+ myNodeIDFactory->BindID(ID,node);
+ return node;
+ }else
+ return NULL;
}
///////////////////////////////////////////////////////////////////////////////
SMDS_MeshEdge* SMDS_Mesh::AddEdgeWithID(int idnode1, int idnode2, int ID)
{
- SMDS_MeshNode * node1 = (SMDS_MeshNode *)myNodeIDFactory->MeshElement(idnode1);
- SMDS_MeshNode * node2 = (SMDS_MeshNode *)myNodeIDFactory->MeshElement(idnode2);
- if((node1==NULL)||(node2==NULL)) return NULL;
- return AddEdgeWithID(node1, node2, ID);
+ SMDS_MeshNode * node1 = (SMDS_MeshNode *)myNodeIDFactory->MeshElement(idnode1);
+ SMDS_MeshNode * node2 = (SMDS_MeshNode *)myNodeIDFactory->MeshElement(idnode2);
+ if(!node1 || !node2) return NULL;
+ return SMDS_Mesh::AddEdgeWithID(node1, node2, ID);
}
///////////////////////////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////////////////////
SMDS_MeshEdge* SMDS_Mesh::AddEdge(const SMDS_MeshNode * node1,
- const SMDS_MeshNode * node2)
+ const SMDS_MeshNode * node2)
{
- return AddEdgeWithID(node1, node2, myElementIDFactory->GetFreeID());
+ return SMDS_Mesh::AddEdgeWithID(node1, node2, myElementIDFactory->GetFreeID());
}
///////////////////////////////////////////////////////////////////////////////
/// @param idnode1 ID of the first node
/// @param idnode2 ID of the second node
/// @param ID ID of the edge to create
-/// @return The created edge or NULL if an edge with this ID already exists or
+/// @return The created edge or NULL if an element with this ID already exists or
/// if input nodes are not found.
///////////////////////////////////////////////////////////////////////////////
SMDS_MeshEdge* SMDS_Mesh::AddEdgeWithID(const SMDS_MeshNode * n1,
- const SMDS_MeshNode * n2, int ID)
-{
- SMDS_MeshNode *node1,*node2;
- node1=const_cast<SMDS_MeshNode*>(n1);
- node2=const_cast<SMDS_MeshNode*>(n2);
-
- SMDS_MeshEdge * edge=new SMDS_MeshEdge(node1,node2);
- if(myElementIDFactory->BindID(ID, edge))
- {
- node1->AddInverseElement(edge);
- node2->AddInverseElement(edge);
- myEdges.insert(edge);
- return edge;
- }
- else
- {
- delete edge;
- return NULL;
- }
+ const SMDS_MeshNode * n2,
+ int ID)
+{
+ SMDS_MeshEdge * edge=new SMDS_MeshEdge(n1,n2);
+ if(myElementIDFactory->BindID(ID, edge)) {
+ SMDS_MeshNode *node1,*node2;
+ node1=const_cast<SMDS_MeshNode*>(n1);
+ node2=const_cast<SMDS_MeshNode*>(n2);
+ node1->AddInverseElement(edge);
+ node2->AddInverseElement(edge);
+ myEdges.insert(edge);
+ return edge;
+ }
+ else {
+ delete edge;
+ return NULL;
+ }
}
///////////////////////////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////////////////////
SMDS_MeshFace* SMDS_Mesh::AddFace(const SMDS_MeshNode * n1,
- const SMDS_MeshNode * n2,
- const SMDS_MeshNode * n3)
+ const SMDS_MeshNode * n2,
+ const SMDS_MeshNode * n3)
{
- return AddFaceWithID(n1,n2,n3, myElementIDFactory->GetFreeID());
+ return SMDS_Mesh::AddFaceWithID(n1,n2,n3, myElementIDFactory->GetFreeID());
}
///////////////////////////////////////////////////////////////////////////////
-/// Add a quadrangle defined by its nodes IDs
+/// Add a triangle defined by its nodes IDs
///////////////////////////////////////////////////////////////////////////////
SMDS_MeshFace* SMDS_Mesh::AddFaceWithID(int idnode1, int idnode2, int idnode3, int ID)
{
- SMDS_MeshNode * node1 = (SMDS_MeshNode *)myNodeIDFactory->MeshElement(idnode1);
- SMDS_MeshNode * node2 = (SMDS_MeshNode *)myNodeIDFactory->MeshElement(idnode2);
- SMDS_MeshNode * node3 = (SMDS_MeshNode *)myNodeIDFactory->MeshElement(idnode3);
- if((node1==NULL)||(node2==NULL)||(node3==NULL)) return NULL;
- return AddFaceWithID(node1, node2, node3, ID);
+ SMDS_MeshNode * node1 = (SMDS_MeshNode *)myNodeIDFactory->MeshElement(idnode1);
+ SMDS_MeshNode * node2 = (SMDS_MeshNode *)myNodeIDFactory->MeshElement(idnode2);
+ SMDS_MeshNode * node3 = (SMDS_MeshNode *)myNodeIDFactory->MeshElement(idnode3);
+ if(!node1 || !node2 || !node3) return NULL;
+ return SMDS_Mesh::AddFaceWithID(node1, node2, node3, ID);
}
///////////////////////////////////////////////////////////////////////////////
-/// Add a quadrangle defined by its nodes
+/// Add a triangle defined by its nodes
///////////////////////////////////////////////////////////////////////////////
-SMDS_MeshFace* SMDS_Mesh::AddFaceWithID(
- const SMDS_MeshNode * n1,
- const SMDS_MeshNode * n2,
- const SMDS_MeshNode * n3, int ID)
+SMDS_MeshFace* SMDS_Mesh::AddFaceWithID(const SMDS_MeshNode * n1,
+ const SMDS_MeshNode * n2,
+ const SMDS_MeshNode * n3,
+ int ID)
{
- SMDS_MeshNode *node1, *node2, *node3;
- node1=const_cast<SMDS_MeshNode*>(n1),
- node2=const_cast<SMDS_MeshNode*>(n2),
- node3=const_cast<SMDS_MeshNode*>(n3);
- SMDS_MeshFace * face=createTriangle(node1, node2, node3);
+ SMDS_MeshFace * face=createTriangle(n1, n2, n3);
- if(myElementIDFactory->BindID(ID, face))
- {
- node1->AddInverseElement(face);
- node2->AddInverseElement(face);
- node3->AddInverseElement(face);
- return face;
- }
- else
- {
- RemoveFace(face);
- return NULL;
- }
+ if (!registerElement(ID, face)) {
+ RemoveElement(face, false);
+ face = NULL;
+ }
+ return face;
}
///////////////////////////////////////////////////////////////////////////////
-/// Add a triangle defined by its nodes. An ID is automatically affected to the
+/// Add a quadrangle defined by its nodes. An ID is automatically affected to the
/// created face
///////////////////////////////////////////////////////////////////////////////
SMDS_MeshFace* SMDS_Mesh::AddFace(const SMDS_MeshNode * n1,
- const SMDS_MeshNode * n2,
- const SMDS_MeshNode * n3,
- const SMDS_MeshNode * n4)
+ const SMDS_MeshNode * n2,
+ const SMDS_MeshNode * n3,
+ const SMDS_MeshNode * n4)
{
- return AddFaceWithID(n1,n2,n3, n4, myElementIDFactory->GetFreeID());
+ return SMDS_Mesh::AddFaceWithID(n1,n2,n3, n4, myElementIDFactory->GetFreeID());
}
///////////////////////////////////////////////////////////////////////////////
/// Add a quadrangle defined by its nodes IDs
///////////////////////////////////////////////////////////////////////////////
-SMDS_MeshFace* SMDS_Mesh::AddFaceWithID(int idnode1, int idnode2, int idnode3,
- int idnode4, int ID)
+SMDS_MeshFace* SMDS_Mesh::AddFaceWithID(int idnode1,
+ int idnode2,
+ int idnode3,
+ int idnode4,
+ int ID)
{
- SMDS_MeshNode *node1, *node2, *node3, *node4;
- node1 = (SMDS_MeshNode *)myNodeIDFactory->MeshElement(idnode1);
- node2 = (SMDS_MeshNode *)myNodeIDFactory->MeshElement(idnode2);
- node3 = (SMDS_MeshNode *)myNodeIDFactory->MeshElement(idnode3);
- node4 = (SMDS_MeshNode *)myNodeIDFactory->MeshElement(idnode4);
- if((node1==NULL)||(node2==NULL)||(node3==NULL)) return NULL;
- return AddFaceWithID(node1, node2, node3, node4, ID);
+ SMDS_MeshNode *node1, *node2, *node3, *node4;
+ node1 = (SMDS_MeshNode *)myNodeIDFactory->MeshElement(idnode1);
+ node2 = (SMDS_MeshNode *)myNodeIDFactory->MeshElement(idnode2);
+ node3 = (SMDS_MeshNode *)myNodeIDFactory->MeshElement(idnode3);
+ node4 = (SMDS_MeshNode *)myNodeIDFactory->MeshElement(idnode4);
+ if(!node1 || !node2 || !node3 || !node4) return NULL;
+ return SMDS_Mesh::AddFaceWithID(node1, node2, node3, node4, ID);
}
///////////////////////////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////////////////////
SMDS_MeshFace* SMDS_Mesh::AddFaceWithID(const SMDS_MeshNode * n1,
- const SMDS_MeshNode * n2, const SMDS_MeshNode * n3,
- const SMDS_MeshNode * n4, int ID)
+ const SMDS_MeshNode * n2,
+ const SMDS_MeshNode * n3,
+ const SMDS_MeshNode * n4,
+ int ID)
{
- SMDS_MeshNode *node1, *node2, *node3, *node4;
- node1=const_cast<SMDS_MeshNode*>(n1),
- node2=const_cast<SMDS_MeshNode*>(n2),
- node3=const_cast<SMDS_MeshNode*>(n3);
- node4=const_cast<SMDS_MeshNode*>(n4);
- SMDS_MeshFace * face=createQuadrangle(node1, node2, node3, node4);
+ SMDS_MeshFace * face=createQuadrangle(n1, n2, n3, n4);
- if(myElementIDFactory->BindID(ID, face))
- {
- node1->AddInverseElement(face);
- node2->AddInverseElement(face);
- node3->AddInverseElement(face);
- node4->AddInverseElement(face);
- return face;
- }
- else
- {
- RemoveFace(face);
- return NULL;
- }
+ if (!registerElement(ID, face)) {
+ RemoveElement(face, false);
+ face = NULL;
+ }
+ return face;
+}
+
+///////////////////////////////////////////////////////////////////////////////
+/// Add a triangle defined by its edges. An ID is automatically assigned to the
+/// Created face
+///////////////////////////////////////////////////////////////////////////////
+
+SMDS_MeshFace* SMDS_Mesh::AddFace(const SMDS_MeshEdge * e1,
+ const SMDS_MeshEdge * e2,
+ const SMDS_MeshEdge * e3)
+{
+ if (!hasConstructionEdges())
+ return NULL;
+ return AddFaceWithID(e1,e2,e3, myElementIDFactory->GetFreeID());
+}
+
+///////////////////////////////////////////////////////////////////////////////
+/// Add a triangle defined by its edges
+///////////////////////////////////////////////////////////////////////////////
+
+SMDS_MeshFace* SMDS_Mesh::AddFaceWithID(const SMDS_MeshEdge * e1,
+ const SMDS_MeshEdge * e2,
+ const SMDS_MeshEdge * e3,
+ int ID)
+{
+ if (!hasConstructionEdges())
+ return NULL;
+ SMDS_MeshFace * face = new SMDS_FaceOfEdges(e1,e2,e3);
+ myFaces.insert(face);
+
+ if (!registerElement(ID, face)) {
+ RemoveElement(face, false);
+ face = NULL;
+ }
+ return face;
+}
+
+///////////////////////////////////////////////////////////////////////////////
+/// Add a quadrangle defined by its edges. An ID is automatically assigned to the
+/// Created face
+///////////////////////////////////////////////////////////////////////////////
+
+SMDS_MeshFace* SMDS_Mesh::AddFace(const SMDS_MeshEdge * e1,
+ const SMDS_MeshEdge * e2,
+ const SMDS_MeshEdge * e3,
+ const SMDS_MeshEdge * e4)
+{
+ if (!hasConstructionEdges())
+ return NULL;
+ return AddFaceWithID(e1,e2,e3,e4, myElementIDFactory->GetFreeID());
+}
+
+///////////////////////////////////////////////////////////////////////////////
+/// Add a quadrangle defined by its edges
+///////////////////////////////////////////////////////////////////////////////
+
+SMDS_MeshFace* SMDS_Mesh::AddFaceWithID(const SMDS_MeshEdge * e1,
+ const SMDS_MeshEdge * e2,
+ const SMDS_MeshEdge * e3,
+ const SMDS_MeshEdge * e4,
+ int ID)
+{
+ if (!hasConstructionEdges())
+ return NULL;
+ SMDS_MeshFace * face = new SMDS_FaceOfEdges(e1,e2,e3,e4);
+ myFaces.insert(face);
+
+ if (!registerElement(ID, face))
+ {
+ RemoveElement(face, false);
+ face = NULL;
+ }
+ return face;
}
///////////////////////////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////////////////////
SMDS_MeshVolume* SMDS_Mesh::AddVolume(const SMDS_MeshNode * n1,
- const SMDS_MeshNode * n2, const SMDS_MeshNode * n3,
- const SMDS_MeshNode * n4)
+ const SMDS_MeshNode * n2,
+ const SMDS_MeshNode * n3,
+ const SMDS_MeshNode * n4)
{
- int ID = myElementIDFactory->GetFreeID();
- SMDS_MeshVolume * v = AddVolumeWithID(n1, n2, n3, n4, ID);
- if(v==NULL) myElementIDFactory->ReleaseID(ID);
- return v;
+ int ID = myElementIDFactory->GetFreeID();
+ SMDS_MeshVolume * v = SMDS_Mesh::AddVolumeWithID(n1, n2, n3, n4, ID);
+ if(v==NULL) myElementIDFactory->ReleaseID(ID);
+ return v;
}
///////////////////////////////////////////////////////////////////////////////
///Create a new tetrahedron and add it to the mesh.
///@param ID The ID of the new volume
-///@return The created tetrahedron or NULL if an edge with this ID already exists
+///@return The created tetrahedron or NULL if an element with this ID already exists
///or if input nodes are not found.
///////////////////////////////////////////////////////////////////////////////
-SMDS_MeshVolume * SMDS_Mesh::AddVolumeWithID(int idnode1, int idnode2,
- int idnode3, int idnode4, int ID)
+SMDS_MeshVolume * SMDS_Mesh::AddVolumeWithID(int idnode1,
+ int idnode2,
+ int idnode3,
+ int idnode4,
+ int ID)
{
- SMDS_MeshNode *node1, *node2, *node3, *node4;
- node1 = (SMDS_MeshNode *)myNodeIDFactory->MeshElement(idnode1);
- node2 = (SMDS_MeshNode *)myNodeIDFactory->MeshElement(idnode2);
- node3 = (SMDS_MeshNode *)myNodeIDFactory->MeshElement(idnode3);
- node4 = (SMDS_MeshNode *)myNodeIDFactory->MeshElement(idnode4);
- if((node1==NULL)||(node2==NULL)||(node3==NULL)||(node4=NULL)) return NULL;
- return AddVolumeWithID(node1, node2, node3, node4, ID);
+ SMDS_MeshNode *node1, *node2, *node3, *node4;
+ node1 = (SMDS_MeshNode *)myNodeIDFactory->MeshElement(idnode1);
+ node2 = (SMDS_MeshNode *)myNodeIDFactory->MeshElement(idnode2);
+ node3 = (SMDS_MeshNode *)myNodeIDFactory->MeshElement(idnode3);
+ node4 = (SMDS_MeshNode *)myNodeIDFactory->MeshElement(idnode4);
+ if(!node1 || !node2 || !node3 || !node4) return NULL;
+ return SMDS_Mesh::AddVolumeWithID(node1, node2, node3, node4, ID);
}
///////////////////////////////////////////////////////////////////////////////
///@return The created tetrahedron
///////////////////////////////////////////////////////////////////////////////
-SMDS_MeshVolume* SMDS_Mesh::AddVolumeWithID(
- const SMDS_MeshNode * n1,
- const SMDS_MeshNode * n2,
- const SMDS_MeshNode * n3,
- const SMDS_MeshNode * n4, int ID)
-{
- SMDS_MeshNode *node1, *node2, *node3, *node4;
- node1=const_cast<SMDS_MeshNode*>(n1),
- node2=const_cast<SMDS_MeshNode*>(n2),
- node3=const_cast<SMDS_MeshNode*>(n3);
- node4=const_cast<SMDS_MeshNode*>(n4);
- SMDS_MeshVolume* volume;
- if(hasConstructionFaces())
- {
- SMDS_MeshFace * f1=createTriangle(node1,node2,node3);
- SMDS_MeshFace * f2=createTriangle(node1,node2,node4);
- SMDS_MeshFace * f3=createTriangle(node1,node3,node4);
- SMDS_MeshFace * f4=createTriangle(node2,node3,node4);
- volume=new SMDS_VolumeOfFaces(f1,f2,f3,f4);
- myVolumes.insert(volume);
- }
- else if(hasConstructionEdges())
- {
- MESSAGE("Error : Not implemented");
- return NULL;
- }
- else
- {
- volume=new SMDS_VolumeOfNodes(node1,node2,node3,node4);
- myVolumes.insert(volume);
- }
-
- if(myElementIDFactory->BindID(ID, volume))
- {
- node1->AddInverseElement(volume);
- node2->AddInverseElement(volume);
- node3->AddInverseElement(volume);
- node4->AddInverseElement(volume);
- return volume;
- }
- else
- {
- RemoveVolume(volume);
- return NULL;
- }
+SMDS_MeshVolume* SMDS_Mesh::AddVolumeWithID(const SMDS_MeshNode * n1,
+ const SMDS_MeshNode * n2,
+ const SMDS_MeshNode * n3,
+ const SMDS_MeshNode * n4,
+ int ID)
+{
+ SMDS_MeshVolume* volume;
+ if(hasConstructionFaces()) {
+ SMDS_MeshFace * f1=FindFaceOrCreate(n1,n2,n3);
+ SMDS_MeshFace * f2=FindFaceOrCreate(n1,n2,n4);
+ SMDS_MeshFace * f3=FindFaceOrCreate(n1,n3,n4);
+ SMDS_MeshFace * f4=FindFaceOrCreate(n2,n3,n4);
+ volume=new SMDS_VolumeOfFaces(f1,f2,f3,f4);
+ myVolumes.insert(volume);
+ }
+ else if(hasConstructionEdges()) {
+ MESSAGE("Error : Not implemented");
+ return NULL;
+ }
+ else {
+ volume=new SMDS_VolumeOfNodes(n1,n2,n3,n4);
+ myVolumes.insert(volume);
+ }
+
+ if (!registerElement(ID, volume)) {
+ RemoveElement(volume, false);
+ volume = NULL;
+ }
+ return volume;
}
///////////////////////////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////////////////////
SMDS_MeshVolume* SMDS_Mesh::AddVolume(const SMDS_MeshNode * n1,
- const SMDS_MeshNode * n2, const SMDS_MeshNode * n3,
- const SMDS_MeshNode * n4, const SMDS_MeshNode * n5)
+ const SMDS_MeshNode * n2,
+ const SMDS_MeshNode * n3,
+ const SMDS_MeshNode * n4,
+ const SMDS_MeshNode * n5)
{
- int ID = myElementIDFactory->GetFreeID();
- SMDS_MeshVolume * v = AddVolumeWithID(n1, n2, n3, n4, n5, ID);
- if(v==NULL) myElementIDFactory->ReleaseID(ID);
- return v;
+ int ID = myElementIDFactory->GetFreeID();
+ SMDS_MeshVolume * v = SMDS_Mesh::AddVolumeWithID(n1, n2, n3, n4, n5, ID);
+ if(v==NULL) myElementIDFactory->ReleaseID(ID);
+ return v;
}
///////////////////////////////////////////////////////////////////////////////
///Create a new pyramid and add it to the mesh.
///Nodes 1,2,3 and 4 define the base of the pyramid
///@param ID The ID of the new volume
-///@return The created pyramid or NULL if a pyramid with this ID already exists
+///@return The created pyramid or NULL if an element with this ID already exists
///or if input nodes are not found.
///////////////////////////////////////////////////////////////////////////////
-SMDS_MeshVolume * SMDS_Mesh::AddVolumeWithID(int idnode1, int idnode2,
- int idnode3, int idnode4, int idnode5, int ID)
+SMDS_MeshVolume * SMDS_Mesh::AddVolumeWithID(int idnode1,
+ int idnode2,
+ int idnode3,
+ int idnode4,
+ int idnode5,
+ int ID)
{
- SMDS_MeshNode *node1, *node2, *node3, *node4, *node5;
- node1 = (SMDS_MeshNode *)myNodeIDFactory->MeshElement(idnode1);
- node2 = (SMDS_MeshNode *)myNodeIDFactory->MeshElement(idnode2);
- node3 = (SMDS_MeshNode *)myNodeIDFactory->MeshElement(idnode3);
- node4 = (SMDS_MeshNode *)myNodeIDFactory->MeshElement(idnode4);
- node5 = (SMDS_MeshNode *)myNodeIDFactory->MeshElement(idnode5);
- if((node1==NULL)||(node2==NULL)||(node3==NULL)||(node4=NULL)||
- (node5=NULL))
- return NULL;
- return AddVolumeWithID(node1, node2, node3, node4, node5, ID);
+ SMDS_MeshNode *node1, *node2, *node3, *node4, *node5;
+ node1 = (SMDS_MeshNode *)myNodeIDFactory->MeshElement(idnode1);
+ node2 = (SMDS_MeshNode *)myNodeIDFactory->MeshElement(idnode2);
+ node3 = (SMDS_MeshNode *)myNodeIDFactory->MeshElement(idnode3);
+ node4 = (SMDS_MeshNode *)myNodeIDFactory->MeshElement(idnode4);
+ node5 = (SMDS_MeshNode *)myNodeIDFactory->MeshElement(idnode5);
+ if(!node1 || !node2 || !node3 || !node4 || !node5) return NULL;
+ return SMDS_Mesh::AddVolumeWithID(node1, node2, node3, node4, node5, ID);
}
///////////////////////////////////////////////////////////////////////////////
///@return The created pyramid
///////////////////////////////////////////////////////////////////////////////
-SMDS_MeshVolume* SMDS_Mesh::AddVolumeWithID(
- const SMDS_MeshNode * n1,
- const SMDS_MeshNode * n2,
- const SMDS_MeshNode * n3,
- const SMDS_MeshNode * n4,
- const SMDS_MeshNode * n5, int ID)
-{
- SMDS_MeshNode *node1, *node2, *node3, *node4, *node5;
- node1=const_cast<SMDS_MeshNode*>(n1),
- node2=const_cast<SMDS_MeshNode*>(n2),
- node3=const_cast<SMDS_MeshNode*>(n3);
- node4=const_cast<SMDS_MeshNode*>(n4);
- node5=const_cast<SMDS_MeshNode*>(n5);
- SMDS_MeshVolume* volume;
- if(hasConstructionFaces())
- {
- SMDS_MeshFace * f1=createQuadrangle(node1,node2,node3,node4);
- SMDS_MeshFace * f2=createTriangle(node1,node2,node5);
- SMDS_MeshFace * f3=createTriangle(node2,node3,node5);
- SMDS_MeshFace * f4=createTriangle(node3,node4,node5);
- volume=new SMDS_VolumeOfFaces(f1,f2,f3,f4);
- myVolumes.insert(volume);
- }
- else if(hasConstructionEdges())
- {
- MESSAGE("Error : Not implemented");
- return NULL;
- }
- else
- {
- volume=new SMDS_VolumeOfNodes(node1,node2,node3,node4,node5);
- myVolumes.insert(volume);
- }
-
- if(myElementIDFactory->BindID(ID, volume))
- {
- node1->AddInverseElement(volume);
- node2->AddInverseElement(volume);
- node3->AddInverseElement(volume);
- node4->AddInverseElement(volume);
- node5->AddInverseElement(volume);
- return volume;
- }
- else
- {
- RemoveVolume(volume);
- return NULL;
- }
+SMDS_MeshVolume* SMDS_Mesh::AddVolumeWithID(const SMDS_MeshNode * n1,
+ const SMDS_MeshNode * n2,
+ const SMDS_MeshNode * n3,
+ const SMDS_MeshNode * n4,
+ const SMDS_MeshNode * n5,
+ int ID)
+{
+ SMDS_MeshVolume* volume;
+ if(hasConstructionFaces()) {
+ SMDS_MeshFace * f1=FindFaceOrCreate(n1,n2,n3,n4);
+ SMDS_MeshFace * f2=FindFaceOrCreate(n1,n2,n5);
+ SMDS_MeshFace * f3=FindFaceOrCreate(n2,n3,n5);
+ SMDS_MeshFace * f4=FindFaceOrCreate(n3,n4,n5);
+ volume=new SMDS_VolumeOfFaces(f1,f2,f3,f4);
+ myVolumes.insert(volume);
+ }
+ else if(hasConstructionEdges()) {
+ MESSAGE("Error : Not implemented");
+ return NULL;
+ }
+ else {
+ volume=new SMDS_VolumeOfNodes(n1,n2,n3,n4,n5);
+ myVolumes.insert(volume);
+ }
+
+ if (!registerElement(ID, volume)) {
+ RemoveElement(volume, false);
+ volume = NULL;
+ }
+ return volume;
}
///////////////////////////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////////////////////
SMDS_MeshVolume* SMDS_Mesh::AddVolume(const SMDS_MeshNode * n1,
- const SMDS_MeshNode * n2, const SMDS_MeshNode * n3,
- const SMDS_MeshNode * n4, const SMDS_MeshNode * n5,
- const SMDS_MeshNode * n6)
+ const SMDS_MeshNode * n2,
+ const SMDS_MeshNode * n3,
+ const SMDS_MeshNode * n4,
+ const SMDS_MeshNode * n5,
+ const SMDS_MeshNode * n6)
{
- int ID = myElementIDFactory->GetFreeID();
- SMDS_MeshVolume * v = AddVolumeWithID(n1, n2, n3, n4, n5, n6, ID);
- if(v==NULL) myElementIDFactory->ReleaseID(ID);
- return v;
+ int ID = myElementIDFactory->GetFreeID();
+ SMDS_MeshVolume * v = SMDS_Mesh::AddVolumeWithID(n1, n2, n3, n4, n5, n6, ID);
+ if(v==NULL) myElementIDFactory->ReleaseID(ID);
+ return v;
}
///////////////////////////////////////////////////////////////////////////////
///Create a new prism and add it to the mesh.
///Nodes 1,2,3 is a triangle and 1,2,5,4 a quadrangle.
///@param ID The ID of the new volume
-///@return The created prism or NULL if a prism with this ID already exists
+///@return The created prism or NULL if an element with this ID already exists
///or if input nodes are not found.
///////////////////////////////////////////////////////////////////////////////
-SMDS_MeshVolume * SMDS_Mesh::AddVolumeWithID(int idnode1, int idnode2,
- int idnode3, int idnode4, int idnode5, int idnode6, int ID)
-{
- SMDS_MeshNode *node1, *node2, *node3, *node4, *node5, *node6;
- node1 = (SMDS_MeshNode *)myNodeIDFactory->MeshElement(idnode1);
- node2 = (SMDS_MeshNode *)myNodeIDFactory->MeshElement(idnode2);
- node3 = (SMDS_MeshNode *)myNodeIDFactory->MeshElement(idnode3);
- node4 = (SMDS_MeshNode *)myNodeIDFactory->MeshElement(idnode4);
- node5 = (SMDS_MeshNode *)myNodeIDFactory->MeshElement(idnode5);
- node6 = (SMDS_MeshNode *)myNodeIDFactory->MeshElement(idnode6);
- if((node1==NULL)||(node2==NULL)||(node3==NULL)||(node4=NULL)||
- (node5==NULL)||(node6=NULL))
- return NULL;
- return AddVolumeWithID(node1, node2, node3, node4, node5, node6, ID);
+SMDS_MeshVolume * SMDS_Mesh::AddVolumeWithID(int idnode1,
+ int idnode2,
+ int idnode3,
+ int idnode4,
+ int idnode5,
+ int idnode6,
+ int ID)
+{
+ SMDS_MeshNode *node1, *node2, *node3, *node4, *node5, *node6;
+ node1 = (SMDS_MeshNode *)myNodeIDFactory->MeshElement(idnode1);
+ node2 = (SMDS_MeshNode *)myNodeIDFactory->MeshElement(idnode2);
+ node3 = (SMDS_MeshNode *)myNodeIDFactory->MeshElement(idnode3);
+ node4 = (SMDS_MeshNode *)myNodeIDFactory->MeshElement(idnode4);
+ node5 = (SMDS_MeshNode *)myNodeIDFactory->MeshElement(idnode5);
+ node6 = (SMDS_MeshNode *)myNodeIDFactory->MeshElement(idnode6);
+ if(!node1 || !node2 || !node3 || !node4 || !node5 || !node6) return NULL;
+ return SMDS_Mesh::AddVolumeWithID(node1, node2, node3, node4, node5, node6, ID);
}
///////////////////////////////////////////////////////////////////////////////
///@return The created prism
///////////////////////////////////////////////////////////////////////////////
-SMDS_MeshVolume* SMDS_Mesh::AddVolumeWithID(
- const SMDS_MeshNode * n1,
- const SMDS_MeshNode * n2,
- const SMDS_MeshNode * n3,
- const SMDS_MeshNode * n4,
- const SMDS_MeshNode * n5,
- const SMDS_MeshNode * n6, int ID)
-{
- SMDS_MeshNode *node1, *node2, *node3, *node4, *node5, *node6;
- node1=const_cast<SMDS_MeshNode*>(n1),
- node2=const_cast<SMDS_MeshNode*>(n2),
- node3=const_cast<SMDS_MeshNode*>(n3);
- node4=const_cast<SMDS_MeshNode*>(n4);
- node5=const_cast<SMDS_MeshNode*>(n5);
- node6=const_cast<SMDS_MeshNode*>(n6);
- SMDS_MeshVolume* volume;
- if(hasConstructionFaces())
- {
- SMDS_MeshFace * f1=createTriangle(node1,node2,node3);
- SMDS_MeshFace * f2=createTriangle(node4,node5,node6);
- SMDS_MeshFace * f3=createQuadrangle(node1,node4,node5,node2);
- SMDS_MeshFace * f4=createQuadrangle(node2,node5,node6,node3);
- SMDS_MeshFace * f5=createQuadrangle(node3,node6,node4,node1);
- volume=new SMDS_VolumeOfFaces(f1,f2,f3,f4,f5);
- myVolumes.insert(volume);
- }
- else if(hasConstructionEdges())
- {
- MESSAGE("Error : Not implemented");
- return NULL;
- }
- else
- {
- volume=new SMDS_VolumeOfNodes(node1,node2,node3,node4,node5,node6);
- myVolumes.insert(volume);
- }
-
- if(myElementIDFactory->BindID(ID, volume))
- {
- node1->AddInverseElement(volume);
- node2->AddInverseElement(volume);
- node3->AddInverseElement(volume);
- node4->AddInverseElement(volume);
- node5->AddInverseElement(volume);
- node6->AddInverseElement(volume);
- return volume;
- }
- else
- {
- RemoveVolume(volume);
- return NULL;
- }
+SMDS_MeshVolume* SMDS_Mesh::AddVolumeWithID(const SMDS_MeshNode * n1,
+ const SMDS_MeshNode * n2,
+ const SMDS_MeshNode * n3,
+ const SMDS_MeshNode * n4,
+ const SMDS_MeshNode * n5,
+ const SMDS_MeshNode * n6,
+ int ID)
+{
+ SMDS_MeshVolume* volume;
+ if(hasConstructionFaces()) {
+ SMDS_MeshFace * f1=FindFaceOrCreate(n1,n2,n3);
+ SMDS_MeshFace * f2=FindFaceOrCreate(n4,n5,n6);
+ SMDS_MeshFace * f3=FindFaceOrCreate(n1,n4,n5,n2);
+ SMDS_MeshFace * f4=FindFaceOrCreate(n2,n5,n6,n3);
+ SMDS_MeshFace * f5=FindFaceOrCreate(n3,n6,n4,n1);
+ volume=new SMDS_VolumeOfFaces(f1,f2,f3,f4,f5);
+ myVolumes.insert(volume);
+ }
+ else if(hasConstructionEdges()) {
+ MESSAGE("Error : Not implemented");
+ return NULL;
+ }
+ else {
+ volume=new SMDS_VolumeOfNodes(n1,n2,n3,n4,n5,n6);
+ myVolumes.insert(volume);
+ }
+
+ if (!registerElement(ID, volume)) {
+ RemoveElement(volume, false);
+ volume = NULL;
+ }
+ return volume;
}
///////////////////////////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////////////////////
SMDS_MeshVolume* SMDS_Mesh::AddVolume(const SMDS_MeshNode * n1,
- const SMDS_MeshNode * n2, const SMDS_MeshNode * n3,
- const SMDS_MeshNode * n4, const SMDS_MeshNode * n5,
- const SMDS_MeshNode * n6, const SMDS_MeshNode * n7,
- const SMDS_MeshNode * n8)
+ const SMDS_MeshNode * n2,
+ const SMDS_MeshNode * n3,
+ const SMDS_MeshNode * n4,
+ const SMDS_MeshNode * n5,
+ const SMDS_MeshNode * n6,
+ const SMDS_MeshNode * n7,
+ const SMDS_MeshNode * n8)
{
- int ID = myElementIDFactory->GetFreeID();
- SMDS_MeshVolume * v = AddVolumeWithID(n1, n2, n3, n4, n5, n6, n7, n8, ID);
- if(v==NULL) myElementIDFactory->ReleaseID(ID);
- return v;
+ int ID = myElementIDFactory->GetFreeID();
+ SMDS_MeshVolume * v = SMDS_Mesh::AddVolumeWithID(n1, n2, n3, n4, n5, n6, n7, n8, ID);
+ if(v==NULL) myElementIDFactory->ReleaseID(ID);
+ return v;
}
///////////////////////////////////////////////////////////////////////////////
///Create a new hexahedron and add it to the mesh.
///Nodes 1,2,3,4 and 5,6,7,8 are quadrangle and 5,1 and 7,3 are an edges.
///@param ID The ID of the new volume
-///@return The created hexahedron or NULL if an hexahedron with this ID already
+///@return The created hexahedron or NULL if an element with this ID already
///exists or if input nodes are not found.
///////////////////////////////////////////////////////////////////////////////
-SMDS_MeshVolume * SMDS_Mesh::AddVolumeWithID(int idnode1, int idnode2,
- int idnode3, int idnode4, int idnode5, int idnode6, int idnode7,
- int idnode8, int ID)
-{
- SMDS_MeshNode *node1, *node2, *node3, *node4, *node5, *node6, *node7, *node8;
- node1 = (SMDS_MeshNode *)myNodeIDFactory->MeshElement(idnode1);
- node2 = (SMDS_MeshNode *)myNodeIDFactory->MeshElement(idnode2);
- node3 = (SMDS_MeshNode *)myNodeIDFactory->MeshElement(idnode3);
- node4 = (SMDS_MeshNode *)myNodeIDFactory->MeshElement(idnode4);
- node5 = (SMDS_MeshNode *)myNodeIDFactory->MeshElement(idnode5);
- node6 = (SMDS_MeshNode *)myNodeIDFactory->MeshElement(idnode6);
- node7 = (SMDS_MeshNode *)myNodeIDFactory->MeshElement(idnode7);
- node8 = (SMDS_MeshNode *)myNodeIDFactory->MeshElement(idnode8);
- if((node1==NULL)||(node2==NULL)||(node3==NULL)||(node4==NULL)||
- (node5==NULL)||(node6==NULL)||(node7==NULL)||(node8==NULL))
- return NULL;
- return AddVolumeWithID(node1, node2, node3, node4, node5, node6, node7,
- node8, ID);
+SMDS_MeshVolume * SMDS_Mesh::AddVolumeWithID(int idnode1,
+ int idnode2,
+ int idnode3,
+ int idnode4,
+ int idnode5,
+ int idnode6,
+ int idnode7,
+ int idnode8,
+ int ID)
+{
+ SMDS_MeshNode *node1, *node2, *node3, *node4, *node5, *node6, *node7, *node8;
+ node1 = (SMDS_MeshNode *)myNodeIDFactory->MeshElement(idnode1);
+ node2 = (SMDS_MeshNode *)myNodeIDFactory->MeshElement(idnode2);
+ node3 = (SMDS_MeshNode *)myNodeIDFactory->MeshElement(idnode3);
+ node4 = (SMDS_MeshNode *)myNodeIDFactory->MeshElement(idnode4);
+ node5 = (SMDS_MeshNode *)myNodeIDFactory->MeshElement(idnode5);
+ node6 = (SMDS_MeshNode *)myNodeIDFactory->MeshElement(idnode6);
+ node7 = (SMDS_MeshNode *)myNodeIDFactory->MeshElement(idnode7);
+ node8 = (SMDS_MeshNode *)myNodeIDFactory->MeshElement(idnode8);
+ if(!node1 || !node2 || !node3 || !node4 || !node5 || !node6 || !node7 || !node8)
+ return NULL;
+ return SMDS_Mesh::AddVolumeWithID(node1, node2, node3, node4, node5, node6,
+ node7, node8, ID);
}
///////////////////////////////////////////////////////////////////////////////
///Create a new hexahedron and add it to the mesh.
///Nodes 1,2,3,4 and 5,6,7,8 are quadrangle and 5,1 and 7,3 are an edges.
///@param ID The ID of the new volume
-///@return The created prism or NULL if an hexadron with this ID already exists
+///@return The created prism or NULL if an element with this ID already exists
///or if input nodes are not found.
///////////////////////////////////////////////////////////////////////////////
-SMDS_MeshVolume* SMDS_Mesh::AddVolumeWithID(
- const SMDS_MeshNode * n1,
- const SMDS_MeshNode * n2,
- const SMDS_MeshNode * n3,
- const SMDS_MeshNode * n4,
- const SMDS_MeshNode * n5,
- const SMDS_MeshNode * n6,
- const SMDS_MeshNode * n7,
- const SMDS_MeshNode * n8, int ID)
-{
- SMDS_MeshNode *node1, *node2, *node3, *node4, *node5, *node6, *node7, *node8;
- node1=const_cast<SMDS_MeshNode*>(n1),
- node2=const_cast<SMDS_MeshNode*>(n2),
- node3=const_cast<SMDS_MeshNode*>(n3);
- node4=const_cast<SMDS_MeshNode*>(n4);
- node5=const_cast<SMDS_MeshNode*>(n5);
- node6=const_cast<SMDS_MeshNode*>(n6);
- node7=const_cast<SMDS_MeshNode*>(n7);
- node8=const_cast<SMDS_MeshNode*>(n8);
- SMDS_MeshVolume* volume;
- if(hasConstructionFaces())
- {
- SMDS_MeshFace * f1=FindFaceOrCreate(node1,node2,node3,node4);
- SMDS_MeshFace * f2=FindFaceOrCreate(node5,node6,node7,node8);
- SMDS_MeshFace * f3=FindFaceOrCreate(node1,node4,node8,node5);
- SMDS_MeshFace * f4=FindFaceOrCreate(node1,node2,node6,node5);
- SMDS_MeshFace * f5=FindFaceOrCreate(node2,node3,node7,node6);
- SMDS_MeshFace * f6=FindFaceOrCreate(node3,node4,node8,node7);
- volume=new SMDS_VolumeOfFaces(f1,f2,f3,f4,f5,f6);
- myVolumes.insert(volume);
- }
- else if(hasConstructionEdges())
- {
- MESSAGE("Error : Not implemented");
- return NULL;
- }
- else
- {
- volume=new SMDS_HexahedronOfNodes(node1,node2,node3,node4,node5,node6,
- node7,node8);
- myVolumes.insert(volume);
- }
+SMDS_MeshVolume* SMDS_Mesh::AddVolumeWithID(const SMDS_MeshNode * n1,
+ const SMDS_MeshNode * n2,
+ const SMDS_MeshNode * n3,
+ const SMDS_MeshNode * n4,
+ const SMDS_MeshNode * n5,
+ const SMDS_MeshNode * n6,
+ const SMDS_MeshNode * n7,
+ const SMDS_MeshNode * n8,
+ int ID)
+{
+ SMDS_MeshVolume* volume;
+ if(hasConstructionFaces()) {
+ SMDS_MeshFace * f1=FindFaceOrCreate(n1,n2,n3,n4);
+ SMDS_MeshFace * f2=FindFaceOrCreate(n5,n6,n7,n8);
+ SMDS_MeshFace * f3=FindFaceOrCreate(n1,n4,n8,n5);
+ SMDS_MeshFace * f4=FindFaceOrCreate(n1,n2,n6,n5);
+ SMDS_MeshFace * f5=FindFaceOrCreate(n2,n3,n7,n6);
+ SMDS_MeshFace * f6=FindFaceOrCreate(n3,n4,n8,n7);
+ volume=new SMDS_VolumeOfFaces(f1,f2,f3,f4,f5,f6);
+ myVolumes.insert(volume);
+ }
+ else if(hasConstructionEdges()) {
+ MESSAGE("Error : Not implemented");
+ return NULL;
+ }
+ else {
+ volume=new SMDS_HexahedronOfNodes(n1,n2,n3,n4,n5,n6,n7,n8);
+ myVolumes.insert(volume);
+ }
+
+ if (!registerElement(ID, volume)) {
+ RemoveElement(volume, false);
+ volume = NULL;
+ }
+ return volume;
+}
+
+///////////////////////////////////////////////////////////////////////////////
+///Create a new tetrahedron defined by its faces and add it to the mesh.
+///@return The created tetrahedron
+///////////////////////////////////////////////////////////////////////////////
+
+SMDS_MeshVolume* SMDS_Mesh::AddVolume(const SMDS_MeshFace * f1,
+ const SMDS_MeshFace * f2,
+ const SMDS_MeshFace * f3,
+ const SMDS_MeshFace * f4)
+{
+ if (!hasConstructionFaces())
+ return NULL;
+ return AddVolumeWithID(f1,f2,f3,f4, myElementIDFactory->GetFreeID());
+}
+
+///////////////////////////////////////////////////////////////////////////////
+///Create a new tetrahedron defined by its faces and add it to the mesh.
+///@param ID The ID of the new volume
+///@return The created tetrahedron
+///////////////////////////////////////////////////////////////////////////////
- if(myElementIDFactory->BindID(ID, volume))
- {
- node1->AddInverseElement(volume);
- node2->AddInverseElement(volume);
- node3->AddInverseElement(volume);
- node4->AddInverseElement(volume);
- node5->AddInverseElement(volume);
- node6->AddInverseElement(volume);
- node7->AddInverseElement(volume);
- node8->AddInverseElement(volume);
- return volume;
- }
- else
- {
- RemoveVolume(volume);
- return NULL;
- }
+SMDS_MeshVolume* SMDS_Mesh::AddVolumeWithID(const SMDS_MeshFace * f1,
+ const SMDS_MeshFace * f2,
+ const SMDS_MeshFace * f3,
+ const SMDS_MeshFace * f4,
+ int ID)
+{
+ if (!hasConstructionFaces())
+ return NULL;
+ SMDS_MeshVolume * volume = new SMDS_VolumeOfFaces(f1,f2,f3,f4);
+ myVolumes.insert(volume);
+
+ if (!registerElement(ID, volume)) {
+ RemoveElement(volume, false);
+ volume = NULL;
+ }
+ return volume;
+}
+
+///////////////////////////////////////////////////////////////////////////////
+///Create a new pyramid defined by its faces and add it to the mesh.
+///@return The created pyramid
+///////////////////////////////////////////////////////////////////////////////
+
+SMDS_MeshVolume* SMDS_Mesh::AddVolume(const SMDS_MeshFace * f1,
+ const SMDS_MeshFace * f2,
+ const SMDS_MeshFace * f3,
+ const SMDS_MeshFace * f4,
+ const SMDS_MeshFace * f5)
+{
+ if (!hasConstructionFaces())
+ return NULL;
+ return AddVolumeWithID(f1,f2,f3,f4,f5, myElementIDFactory->GetFreeID());
+}
+
+///////////////////////////////////////////////////////////////////////////////
+///Create a new pyramid defined by its faces and add it to the mesh.
+///@param ID The ID of the new volume
+///@return The created pyramid
+///////////////////////////////////////////////////////////////////////////////
+
+SMDS_MeshVolume* SMDS_Mesh::AddVolumeWithID(const SMDS_MeshFace * f1,
+ const SMDS_MeshFace * f2,
+ const SMDS_MeshFace * f3,
+ const SMDS_MeshFace * f4,
+ const SMDS_MeshFace * f5,
+ int ID)
+{
+ if (!hasConstructionFaces())
+ return NULL;
+ SMDS_MeshVolume * volume = new SMDS_VolumeOfFaces(f1,f2,f3,f4,f5);
+ myVolumes.insert(volume);
+
+ if (!registerElement(ID, volume)) {
+ RemoveElement(volume, false);
+ volume = NULL;
+ }
+ return volume;
+}
+
+///////////////////////////////////////////////////////////////////////////////
+///Create a new prism defined by its faces and add it to the mesh.
+///@return The created prism
+///////////////////////////////////////////////////////////////////////////////
+
+SMDS_MeshVolume* SMDS_Mesh::AddVolume(const SMDS_MeshFace * f1,
+ const SMDS_MeshFace * f2,
+ const SMDS_MeshFace * f3,
+ const SMDS_MeshFace * f4,
+ const SMDS_MeshFace * f5,
+ const SMDS_MeshFace * f6)
+{
+ if (!hasConstructionFaces())
+ return NULL;
+ return AddVolumeWithID(f1,f2,f3,f4,f5,f6, myElementIDFactory->GetFreeID());
+}
+
+///////////////////////////////////////////////////////////////////////////////
+///Create a new prism defined by its faces and add it to the mesh.
+///@param ID The ID of the new volume
+///@return The created prism
+///////////////////////////////////////////////////////////////////////////////
+
+SMDS_MeshVolume* SMDS_Mesh::AddVolumeWithID(const SMDS_MeshFace * f1,
+ const SMDS_MeshFace * f2,
+ const SMDS_MeshFace * f3,
+ const SMDS_MeshFace * f4,
+ const SMDS_MeshFace * f5,
+ const SMDS_MeshFace * f6,
+ int ID)
+{
+ if (!hasConstructionFaces())
+ return NULL;
+ SMDS_MeshVolume * volume = new SMDS_VolumeOfFaces(f1,f2,f3,f4,f5,f6);
+ myVolumes.insert(volume);
+
+ if (!registerElement(ID, volume)) {
+ RemoveElement(volume, false);
+ volume = NULL;
+ }
+ return volume;
+}
+
+///////////////////////////////////////////////////////////////////////////////
+/// Registers element with the given ID, maintains inverse connections
+///////////////////////////////////////////////////////////////////////////////
+bool SMDS_Mesh::registerElement(int ID, SMDS_MeshElement * element)
+{
+ if (myElementIDFactory->BindID(ID, element)) {
+ SMDS_ElemIteratorPtr it = element->nodesIterator();
+ while (it->more()) {
+ SMDS_MeshNode *node = static_cast<SMDS_MeshNode*>
+ (const_cast<SMDS_MeshElement*>(it->next()));
+ node->AddInverseElement(element);
+ }
+ return true;
+ }
+ return false;
}
///////////////////////////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////////////////////
const SMDS_MeshNode * SMDS_Mesh::FindNode(int ID) const
{
- return (const SMDS_MeshNode *)myNodeIDFactory->MeshElement(ID);
+ return (const SMDS_MeshNode *)myNodeIDFactory->MeshElement(ID);
}
///////////////////////////////////////////////////////////////////////////////
///Create a triangle and add it to the current mesh. This methode do not bind a
///ID to the create triangle.
///////////////////////////////////////////////////////////////////////////////
-SMDS_MeshFace * SMDS_Mesh::createTriangle(SMDS_MeshNode * node1,
- SMDS_MeshNode * node2, SMDS_MeshNode * node3)
+SMDS_MeshFace * SMDS_Mesh::createTriangle(const SMDS_MeshNode * node1,
+ const SMDS_MeshNode * node2,
+ const SMDS_MeshNode * node3)
{
if(hasConstructionEdges())
{
///Create a quadrangle and add it to the current mesh. This methode do not bind
///a ID to the create triangle.
///////////////////////////////////////////////////////////////////////////////
-SMDS_MeshFace * SMDS_Mesh::createQuadrangle(SMDS_MeshNode * node1,
- SMDS_MeshNode * node2, SMDS_MeshNode * node3, SMDS_MeshNode * node4)
+SMDS_MeshFace * SMDS_Mesh::createQuadrangle(const SMDS_MeshNode * node1,
+ const SMDS_MeshNode * node2,
+ const SMDS_MeshNode * node3,
+ const SMDS_MeshNode * node4)
{
if(hasConstructionEdges())
{
return FindEdge(node1,node2);
}
-///////////////////////////////////////////////////////////////////////////////
-///
-///////////////////////////////////////////////////////////////////////////////
//#include "Profiler.h"
const SMDS_MeshEdge* SMDS_Mesh::FindEdge(const SMDS_MeshNode * node1,
const SMDS_MeshNode * node2) const
const SMDS_MeshEdge * toReturn=NULL;
//PROFILER_Init();
//PROFILER_Set();
- SMDS_Iterator<const SMDS_MeshElement *>* it1=node1->edgesIterator();
+ SMDS_ElemIteratorPtr it1=node1->edgesIterator();
//PROFILER_Get(0);
//PROFILER_Set();
while(it1->more())
{
const SMDS_MeshEdge * e=static_cast<const SMDS_MeshEdge *>
(it1->next());
- SMDS_Iterator<const SMDS_MeshElement *>* it2=e->nodesIterator();
+ SMDS_ElemIteratorPtr it2=e->nodesIterator();
while(it2->more())
{
if(it2->next()->GetID()==node2->GetID())
break;
}
}
- delete it2;
}
//PROFILER_Get(1);
- delete it1;
return toReturn;
}
toReturn=const_cast<SMDS_MeshEdge*>(FindEdge(node1,node2));
if(toReturn==NULL)
{
- toReturn=new SMDS_MeshEdge(const_cast<SMDS_MeshNode*>(node1),
- const_cast<SMDS_MeshNode*>(node2));
- myEdges.insert(toReturn);
+ toReturn=new SMDS_MeshEdge(node1,node2);
+ myEdges.insert(toReturn);
}
return toReturn;
}
const SMDS_MeshNode * node1=FindNode(idnode1);
const SMDS_MeshNode * node2=FindNode(idnode2);
const SMDS_MeshNode * node3=FindNode(idnode3);
+ if((node1==NULL)||(node2==NULL)||(node3==NULL)) return NULL;
+ return FindFace(node1, node2, node3);
+}
+
+const SMDS_MeshFace* SMDS_Mesh::FindFace(
+ const SMDS_MeshNode *node1,
+ const SMDS_MeshNode *node2,
+ const SMDS_MeshNode *node3) const
+{
const SMDS_MeshFace * face;
const SMDS_MeshElement * node;
bool node2found, node3found;
- if((node1==NULL)||(node2==NULL)||(node3==NULL)) return NULL;
- SMDS_Iterator<const SMDS_MeshElement *>* it1=node1->facesIterator();
+ SMDS_ElemIteratorPtr it1=node1->facesIterator();
while(it1->more())
{
face=static_cast<const SMDS_MeshFace*>(it1->next());
if(face->NbNodes()!=3) continue;
- SMDS_Iterator<const SMDS_MeshElement *>* it2=face->nodesIterator();
+ SMDS_ElemIteratorPtr it2=face->nodesIterator();
node2found=false;
node3found=false;
while(it2->more())
{
node=it2->next();
- if(node->GetID()==idnode2) node2found=true;
- if(node->GetID()==idnode3) node3found=true;
+ if(node->GetID()==node2->GetID()) node2found=true;
+ if(node->GetID()==node3->GetID()) node3found=true;
}
- delete it2;
if(node2found&&node3found)
- {
- delete it1;
return face;
- }
}
- delete it1;
return NULL;
}
+SMDS_MeshFace* SMDS_Mesh::FindFaceOrCreate(
+ const SMDS_MeshNode *node1,
+ const SMDS_MeshNode *node2,
+ const SMDS_MeshNode *node3)
+{
+ SMDS_MeshFace * toReturn=NULL;
+ toReturn=const_cast<SMDS_MeshFace*>(FindFace(node1,node2,node3));
+ if(toReturn==NULL)
+ {
+ toReturn=createTriangle(node1,node2,node3);
+ }
+ return toReturn;
+}
+
//=======================================================================
//function : FindFace
//purpose :
const SMDS_MeshFace * face;
const SMDS_MeshElement * node;
bool node2found, node3found, node4found;
- SMDS_Iterator<const SMDS_MeshElement *>* it1=node1->facesIterator();
+ SMDS_ElemIteratorPtr it1=node1->facesIterator();
while(it1->more())
{
face=static_cast<const SMDS_MeshFace *>(it1->next());
if(face->NbNodes()!=4) continue;
- SMDS_Iterator<const SMDS_MeshElement *>* it2=face->nodesIterator();
+ SMDS_ElemIteratorPtr it2=face->nodesIterator();
node2found=false;
node3found=false;
node4found=false;
if(node->GetID()==node3->GetID()) node3found=true;
if(node->GetID()==node4->GetID()) node4found=true;
}
- delete it2;
if(node2found&&node3found&&node4found)
- {
- delete it1;
return face;
- }
}
- delete it1;
return NULL;
}
{
SMDS_MeshFace * toReturn=NULL;
toReturn=const_cast<SMDS_MeshFace*>(FindFace(node1,node2,node3,node4));
- if(toReturn==NULL)
+ if(toReturn==NULL)
{
- toReturn=createQuadrangle(
- const_cast<SMDS_MeshNode *>(node1),
- const_cast<SMDS_MeshNode *>(node2),
- const_cast<SMDS_MeshNode *>(node3),
- const_cast<SMDS_MeshNode *>(node4)
- );
- }
+ toReturn=createQuadrangle(node1,node2,node3,node4);
+ }
return toReturn;
}
void SMDS_Mesh::DumpNodes() const
{
MESSAGE("dump nodes of mesh : ");
- SMDS_Iterator<const SMDS_MeshNode *> * itnode=nodesIterator();
+ SMDS_NodeIteratorPtr itnode=nodesIterator();
while(itnode->more()) MESSAGE(itnode->next());
- delete itnode;
}
//=======================================================================
void SMDS_Mesh::DumpEdges() const
{
MESSAGE("dump edges of mesh : ");
- SMDS_Iterator<const SMDS_MeshEdge *> * itedge=edgesIterator();
+ SMDS_EdgeIteratorPtr itedge=edgesIterator();
while(itedge->more()) MESSAGE(itedge->next());
- delete itedge;
}
//=======================================================================
void SMDS_Mesh::DumpFaces() const
{
MESSAGE("dump faces of mesh : ");
- SMDS_Iterator<const SMDS_MeshFace *> * itface=facesIterator();
+ SMDS_FaceIteratorPtr itface=facesIterator();
while(itface->more()) MESSAGE(itface->next());
- delete itface;
}
//=======================================================================
void SMDS_Mesh::DumpVolumes() const
{
MESSAGE("dump volumes of mesh : ");
- SMDS_Iterator<const SMDS_MeshVolume *> * itvol=volumesIterator();
+ SMDS_VolumeIteratorPtr itvol=volumesIterator();
while(itvol->more()) MESSAGE(itvol->next());
- delete itvol;
}
//=======================================================================
//#ifdef DEB
- SMDS_Iterator<const SMDS_MeshNode *> * itnode=nodesIterator();
+ SMDS_NodeIteratorPtr itnode=nodesIterator();
int sizeofnodes = 0;
int sizeoffaces = 0;
sizeofnodes += sizeof(*node);
- SMDS_Iterator<const SMDS_MeshElement *> * it=
- node->GetInverseElementIterator();
+ SMDS_ElemIteratorPtr it = node->GetInverseElementIterator();
while(it->more())
{
const SMDS_MeshElement *me = it->next();
sizeofnodes += sizeof(me);
}
- delete it;
}
- delete itnode;
- SMDS_Iterator<const SMDS_MeshFace*>* itface=facesIterator();
-
+
+ SMDS_FaceIteratorPtr itface=facesIterator();
while(itface->more())
{
const SMDS_MeshElement *face = itface->next();
MESSAGE("total size of face elements = " << sizeoffaces);;
//#endif
-
}
///////////////////////////////////////////////////////////////////////////////
itc++;
}
- SMDS_Iterator<const SMDS_MeshNode*> * itn=nodesIterator();
+ SMDS_NodeIteratorPtr itn=nodesIterator();
while(itn->more())
{
delete itn->next();
}
- delete itn;
set<SMDS_MeshEdge*>::iterator ite=myEdges.begin();
while(ite!=myEdges.end())
delete *itv;
itv++;
}
-
}
///////////////////////////////////////////////////////////////////////////////
/// Return an iterator on nodes of the current mesh. Once used this iterator
/// must be free by the caller
///////////////////////////////////////////////////////////////////////////////
-SMDS_Iterator<const SMDS_MeshNode *> * SMDS_Mesh::nodesIterator() const
+class SMDS_Mesh_MyNodeIterator:public SMDS_NodeIterator
{
- class MyIterator:public SMDS_Iterator<const SMDS_MeshNode*>
- {
- const SetOfNodes& mySet;
- SetOfNodes::iterator myIterator;
- public:
- MyIterator(const SetOfNodes& s):mySet(s)
- {
- myIterator=mySet.begin();
- }
+ typedef SMDS_Mesh::SetOfNodes SetOfNodes;
+ const SetOfNodes& mySet;
+ SetOfNodes::iterator myIterator;
+ public:
+ SMDS_Mesh_MyNodeIterator(const SetOfNodes& s):mySet(s)
+ {
+ myIterator=mySet.begin();
+ }
- bool more()
- {
- return myIterator!=mySet.end();
- }
+ bool more()
+ {
+ return myIterator!=mySet.end();
+ }
- const SMDS_MeshNode* next()
- {
- const SMDS_MeshNode* current=*myIterator;
- myIterator++;
- return current;
- }
- };
- return new MyIterator(myNodes);
+ const SMDS_MeshNode* next()
+ {
+ const SMDS_MeshNode* current=*myIterator;
+ myIterator++;
+ return current;
+ }
+};
+
+SMDS_NodeIteratorPtr SMDS_Mesh::nodesIterator() const
+{
+ return SMDS_NodeIteratorPtr(new SMDS_Mesh_MyNodeIterator(myNodes));
}
///////////////////////////////////////////////////////////////////////////////
-///Return an iterator on egdes of the current mesh. Once used this iterator
+///Return an iterator on volumes of the current mesh. Once used this iterator
///must be free by the caller
///////////////////////////////////////////////////////////////////////////////
-SMDS_Iterator<const SMDS_MeshEdge *> * SMDS_Mesh::edgesIterator() const
+class SMDS_Mesh_MyEdgeIterator:public SMDS_EdgeIterator
{
- class MyIterator:public SMDS_Iterator<const SMDS_MeshEdge*>
- {
- const SetOfEdges& mySet;
- const SMDS_MeshEdge * myEdge;
- SetOfEdges::iterator myIterator;
- public:
- MyIterator(const SetOfEdges& s):mySet(s)
- {
- myIterator=mySet.begin();
- }
+ typedef SMDS_Mesh::SetOfEdges SetOfEdges;
+ const SetOfEdges& mySet;
+ const SMDS_MeshEdge * myEdge;
+ SetOfEdges::iterator myIterator;
+ public:
+ SMDS_Mesh_MyEdgeIterator(const SetOfEdges& s):mySet(s)
+ {
+ myIterator=mySet.begin();
+ }
- bool more()
- {
- while((myIterator!=mySet.end()))
- {
- if((*myIterator)->GetID()!=-1)
- return true;
- myIterator++;
- }
- return false;
- }
+ bool more()
+ {
+ while((myIterator!=mySet.end()))
+ {
+ if((*myIterator)->GetID()!=-1)
+ return true;
+ myIterator++;
+ }
+ return false;
+ }
- const SMDS_MeshEdge* next()
- {
- const SMDS_MeshEdge* current=*myIterator;
- myIterator++;
- return current;
- }
- };
- return new MyIterator(myEdges);
+ const SMDS_MeshEdge* next()
+ {
+ const SMDS_MeshEdge* current=*myIterator;
+ myIterator++;
+ return current;
+ }
+};
+
+SMDS_EdgeIteratorPtr SMDS_Mesh::edgesIterator() const
+{
+ return SMDS_EdgeIteratorPtr(new SMDS_Mesh_MyEdgeIterator(myEdges));
}
///////////////////////////////////////////////////////////////////////////////
///Return an iterator on faces of the current mesh. Once used this iterator
///must be free by the caller
///////////////////////////////////////////////////////////////////////////////
-SMDS_Iterator<const SMDS_MeshFace *> * SMDS_Mesh::facesIterator() const
+class SMDS_Mesh_MyFaceIterator:public SMDS_FaceIterator
{
- class MyIterator:public SMDS_Iterator<const SMDS_MeshFace*>
- {
- const SetOfFaces& mySet;
- set<SMDS_MeshFace*>::iterator myIterator;
- public:
- MyIterator(const SetOfFaces& s):mySet(s)
- {
- myIterator=mySet.begin();
- }
+ typedef SMDS_Mesh::SetOfFaces SetOfFaces;
+ const SetOfFaces& mySet;
+ SetOfFaces::iterator myIterator;
+ public:
+ SMDS_Mesh_MyFaceIterator(const SetOfFaces& s):mySet(s)
+ {
+ myIterator=mySet.begin();
+ }
- bool more()
- {
- while((myIterator!=mySet.end()))
- {
- if((*myIterator)->GetID()!=-1)
- return true;
- myIterator++;
- }
- return false;
- }
+ bool more()
+ {
+ while((myIterator!=mySet.end()))
+ {
+ if((*myIterator)->GetID()!=-1)
+ return true;
+ myIterator++;
+ }
+ return false;
+ }
- const SMDS_MeshFace* next()
- {
- const SMDS_MeshFace* current=*myIterator;
- myIterator++;
- return current;
- }
- };
- return new MyIterator(myFaces);
+ const SMDS_MeshFace* next()
+ {
+ const SMDS_MeshFace* current=*myIterator;
+ myIterator++;
+ return current;
+ }
+};
+
+SMDS_FaceIteratorPtr SMDS_Mesh::facesIterator() const
+{
+ return SMDS_FaceIteratorPtr(new SMDS_Mesh_MyFaceIterator(myFaces));
}
///////////////////////////////////////////////////////////////////////////////
///Return an iterator on volumes of the current mesh. Once used this iterator
///must be free by the caller
///////////////////////////////////////////////////////////////////////////////
-SMDS_Iterator<const SMDS_MeshVolume *> * SMDS_Mesh::volumesIterator() const
+class SMDS_Mesh_MyVolumeIterator:public SMDS_VolumeIterator
{
- class MyIterator:public SMDS_Iterator<const SMDS_MeshVolume*>
- {
- const SetOfVolumes& mySet;
- SetOfVolumes::iterator myIterator;
- public:
- MyIterator(const SetOfVolumes& s):mySet(s)
- {
- myIterator=mySet.begin();
- }
+ typedef SMDS_Mesh::SetOfVolumes SetOfVolumes;
+ const SetOfVolumes& mySet;
+ SetOfVolumes::iterator myIterator;
+ public:
+ SMDS_Mesh_MyVolumeIterator(const SetOfVolumes& s):mySet(s)
+ {
+ myIterator=mySet.begin();
+ }
- bool more()
- {
- return myIterator!=mySet.end();
- }
+ bool more()
+ {
+ return myIterator!=mySet.end();
+ }
- const SMDS_MeshVolume* next()
- {
- const SMDS_MeshVolume* current=*myIterator;
- myIterator++;
- return current;
- }
- };
- return new MyIterator(myVolumes);
+ const SMDS_MeshVolume* next()
+ {
+ const SMDS_MeshVolume* current=*myIterator;
+ myIterator++;
+ return current;
+ }
+};
+
+SMDS_VolumeIteratorPtr SMDS_Mesh::volumesIterator() const
+{
+ return SMDS_VolumeIteratorPtr(new SMDS_Mesh_MyVolumeIterator(myVolumes));
}
///////////////////////////////////////////////////////////////////////////////
/// Do intersection of sets (more than 2)
///////////////////////////////////////////////////////////////////////////////
-set<const SMDS_MeshElement*> * intersectionOfSets(
+static set<const SMDS_MeshElement*> * intersectionOfSets(
set<const SMDS_MeshElement*> vs[], int numberOfSets)
{
set<const SMDS_MeshElement*>* rsetA=new set<const SMDS_MeshElement*>(vs[0]);
///////////////////////////////////////////////////////////////////////////////
/// Return the list of finit elements owning the given element
///////////////////////////////////////////////////////////////////////////////
-set<const SMDS_MeshElement*> * getFinitElements(const SMDS_MeshElement * element)
+static set<const SMDS_MeshElement*> * getFinitElements(const SMDS_MeshElement * element)
{
int numberOfSets=element->NbNodes();
set<const SMDS_MeshElement*> initSet[numberOfSets];
- SMDS_Iterator<const SMDS_MeshElement*> * itNodes=element->nodesIterator();
+ SMDS_ElemIteratorPtr itNodes=element->nodesIterator();
int i=0;
while(itNodes->more())
{
const SMDS_MeshNode * n=static_cast<const SMDS_MeshNode*>(itNodes->next());
- SMDS_Iterator<const SMDS_MeshElement*> * itFe = n->GetInverseElementIterator();
+ SMDS_ElemIteratorPtr itFe = n->GetInverseElementIterator();
//initSet[i]=set<const SMDS_MeshElement*>();
- while(itFe->more()) initSet[i].insert(itFe->next());
+ while(itFe->more())
+ initSet[i].insert(itFe->next());
i++;
- delete itFe;
}
- delete itNodes;
return intersectionOfSets(initSet, numberOfSets);
}
///////////////////////////////////////////////////////////////////////////////
/// Return the list of nodes used only by the given elements
///////////////////////////////////////////////////////////////////////////////
-set<const SMDS_MeshElement*> * getExclusiveNodes(
+static set<const SMDS_MeshElement*> * getExclusiveNodes(
set<const SMDS_MeshElement*>& elements)
{
set<const SMDS_MeshElement*> * toReturn=new set<const SMDS_MeshElement*>();
while(itElements!=elements.end())
{
- SMDS_Iterator<const SMDS_MeshElement*> * itNodes=
- (*itElements)->nodesIterator();
+ SMDS_ElemIteratorPtr itNodes = (*itElements)->nodesIterator();
itElements++;
while(itNodes->more())
{
const SMDS_MeshNode * n=static_cast<const SMDS_MeshNode*>(itNodes->next());
- SMDS_Iterator<const SMDS_MeshElement*> * itFe = n->GetInverseElementIterator();
+ SMDS_ElemIteratorPtr itFe = n->GetInverseElementIterator();
set<const SMDS_MeshElement*> s;
- while(itFe->more()) s.insert(itFe->next());
- delete itFe;
+ while(itFe->more())
+ s.insert(itFe->next());
if(s==elements) toReturn->insert(n);
}
- delete itNodes;
}
return toReturn;
}
break;
case SMDSAbs_Edge:
{
- SMDS_Iterator<const SMDS_MeshElement*> * itn=element->nodesIterator();
+ SMDS_ElemIteratorPtr itn=element->nodesIterator();
while(itn->more())
{
const SMDS_MeshElement * e=itn->next();
- if(nodes.find(e)!=nodes.end()) setOfChildren.insert(element);
+ if(nodes.find(e)!=nodes.end())
+ {
+ setOfChildren.insert(element);
+ break;
+ }
}
- delete itn;
- } break;
+ } break;
case SMDSAbs_Face:
{
- SMDS_Iterator<const SMDS_MeshElement*> * itn=element->nodesIterator();
+ SMDS_ElemIteratorPtr itn=element->nodesIterator();
while(itn->more())
{
const SMDS_MeshElement * e=itn->next();
- if(nodes.find(e)!=nodes.end()) setOfChildren.insert(element);
+ if(nodes.find(e)!=nodes.end())
+ {
+ setOfChildren.insert(element);
+ break;
+ }
}
- delete itn;
if(hasConstructionEdges())
{
- SMDS_Iterator<const SMDS_MeshElement*>* ite=element->edgesIterator();
+ SMDS_ElemIteratorPtr ite=element->edgesIterator();
while(ite->more())
addChildrenWithNodes(setOfChildren, ite->next(), nodes);
- delete ite;
}
} break;
case SMDSAbs_Volume:
{
if(hasConstructionFaces())
{
- SMDS_Iterator<const SMDS_MeshElement*> * ite=element->facesIterator();
+ SMDS_ElemIteratorPtr ite=element->facesIterator();
while(ite->more())
addChildrenWithNodes(setOfChildren, ite->next(), nodes);
- delete ite;
}
else if(hasConstructionEdges())
{
- SMDS_Iterator<const SMDS_MeshElement*> * ite=element->edgesIterator();
+ SMDS_ElemIteratorPtr ite=element->edgesIterator();
while(ite->more())
addChildrenWithNodes(setOfChildren, ite->next(), nodes);
- delete ite;
}
}
}
void SMDS_Mesh::RemoveElement(const SMDS_MeshElement * elem,
const bool removenodes)
{
- set<const SMDS_MeshElement*> * s1=getFinitElements(elem);
-
- set<const SMDS_MeshElement*> * s2=getExclusiveNodes(*s1);
- set<const SMDS_MeshElement*> s3;
- set<const SMDS_MeshElement*>::iterator it=s1->begin();
- while(it!=s1->end())
- {
- addChildrenWithNodes(s3, *it ,*s2);
- s3.insert(*it);
- it++;
- }
- if(elem->GetType()!=SMDSAbs_Node) s3.insert(elem);
- it=s3.begin();
- while(it!=s3.end())
- {
- switch((*it)->GetType())
- {
- case SMDSAbs_Node:
- MESSAGE("Internal Error: This should not happen");
- break;
- case SMDSAbs_Edge:
- myEdges.erase(static_cast<SMDS_MeshEdge*>(
- const_cast<SMDS_MeshElement*>(*it)));
- break;
- case SMDSAbs_Face:
- myFaces.erase(static_cast<SMDS_MeshFace*>(
- const_cast<SMDS_MeshElement*>(*it)));
- break;
- case SMDSAbs_Volume:
- myVolumes.erase(static_cast<SMDS_MeshVolume*>(
- const_cast<SMDS_MeshElement*>(*it)));
- break;
- }
- delete (*it);
- it++;
- }
- if(removenodes)
- {
- it=s2->begin();
- while(it!=s2->end())
- {
- myNodes.erase(static_cast<SMDS_MeshNode*>(
- const_cast<SMDS_MeshElement*>(*it)));
- delete *it;
- it++;
- }
- }
-
- delete s2;
- delete s1;
-}
-
-/**
- * Concat the coordinates of all nodes in an array.
- * Its used to display the mesh.
- * @return A array of size 3*NbNodes() containing the coordinates of nodes.
- */
-double * SMDS_Mesh::getNodesCoordinates()
-{
- double * toReturn=new double[3*NbNodes()];
- SMDS_Iterator<const SMDS_MeshNode*> * it=nodesIterator();
- int i=0;
- while(it->more())
- {
- const SMDS_MeshNode * n=it->next();
- toReturn[i]=n->X();
- i++;
- toReturn[i]=n->Y();
- i++;
- toReturn[i]=n->Z();
- i++;
- }
- delete it;
- return toReturn;
-}
-
-/**
- * Concat the id of all nodes in an array.
- * Its used to display the mesh.
- * @return A array of size NbNodes() containing the ids of nodes.
- */
-long * SMDS_Mesh::getNodesID()
-{
- long * toReturn=new long[NbNodes()];
- SMDS_Iterator<const SMDS_MeshNode*> * it=nodesIterator();
- int i=0;
- while(it->more())
- {
- const SMDS_MeshNode * n=it->next();
- toReturn[i]=n->GetID();
- i++;
- }
- delete it;
- return toReturn;
-}
-
-/**
- * Concat the id of nodes of edges in an array.
- * Array format is {edge_id, node1_id, node2_id}
- * Its used to display the mesh.
- * @return A array of size 3*NbEdges() containing the edges.
- */
-long * SMDS_Mesh::getEdgesIndices()
-{
- long * toReturn=new long[NbEdges()*3];
- SMDS_Iterator<const SMDS_MeshEdge*> * it=edgesIterator();
- int i=0;
-
- while(it->more())
- {
- const SMDS_MeshEdge * e=it->next();
- toReturn[i]=e->GetID();
- i++;
- SMDS_Iterator<const SMDS_MeshElement*> * itn=e->nodesIterator();
- while(itn->more())
- {
- const SMDS_MeshElement * n=itn->next();
- toReturn[i]=n->GetID();
- i++;
- }
- delete itn;
- }
- delete it;
- return toReturn;
+ list<const SMDS_MeshElement *> removedElems;
+ list<const SMDS_MeshElement *> removedNodes;
+ RemoveElement( elem, removedElems, removedNodes, removenodes );
}
-
-/**
- * Concat the id of nodes of triangles in an array.
- * Array format is {tria_id, node1_id, node2_id, node3_id}
- * Its used to display the mesh.
- * @return A array of size 4*NbTriangles() containing the edges.
- */
-long * SMDS_Mesh::getTrianglesIndices()
-{
- long * toReturn=new long[NbTriangles()*4];
- SMDS_Iterator<const SMDS_MeshFace*> * it=facesIterator();
- int i=0;
- while(it->more())
- {
- const SMDS_MeshFace * f=it->next();
- if(f->NbNodes()==3)
- {
- toReturn[i]=f->GetID();
- i++;
- SMDS_Iterator<const SMDS_MeshElement*> * itn=f->nodesIterator();
- while(itn->more())
- {
- const SMDS_MeshElement * n=itn->next();
- toReturn[i]=n->GetID();
- i++;
- }
- delete itn;
- }
- }
- delete it;
- return toReturn;
-}
-
-/**
- * Return the number of 3 nodes faces in the mesh.
- * This method run in O(n).
- * @return The number of face whose number of nodes is 3
+
+///////////////////////////////////////////////////////////////////////////////
+///@param elem The element to delete
+///@param removedElems contains all removed elements
+///@param removedNodes contains all removed nodes
+///@param removenodes if true remaining nodes will be removed
+///////////////////////////////////////////////////////////////////////////////
+void SMDS_Mesh::RemoveElement(const SMDS_MeshElement * elem,
+ list<const SMDS_MeshElement *>& removedElems,
+ list<const SMDS_MeshElement *>& removedNodes,
+ const bool removenodes)
+{
+ // get finite elements built on elem
+ set<const SMDS_MeshElement*> * s1;
+ if (!hasConstructionEdges() && elem->GetType() == SMDSAbs_Edge ||
+ !hasConstructionFaces() && elem->GetType() == SMDSAbs_Face)
+ {
+ s1 = new set<const SMDS_MeshElement*>();
+ s1->insert(elem);
+ }
+ else
+ s1 = getFinitElements(elem);
+
+ // get exclusive nodes (which would become free afterwards)
+ set<const SMDS_MeshElement*> * s2;
+ if (s1->empty() && elem->GetType() == SMDSAbs_Node)
+ {
+ s2 = new set<const SMDS_MeshElement*>();
+ s2->insert(elem);
+ }
+ else
+ s2 = getExclusiveNodes(*s1);
+
+ // form the set of finite and construction elements to remove
+ set<const SMDS_MeshElement*> s3;
+ set<const SMDS_MeshElement*>::iterator it=s1->begin();
+ while(it!=s1->end())
+ {
+ addChildrenWithNodes(s3, *it ,*s2);
+ s3.insert(*it);
+ it++;
+ }
+ if(elem->GetType()!=SMDSAbs_Node) s3.insert(elem);
+
+ // remove finite and construction elements
+ it=s3.begin();
+ while(it!=s3.end())
+ {
+ // Remove element from <InverseElements> of its nodes
+ SMDS_ElemIteratorPtr itn=(*it)->nodesIterator();
+ while(itn->more())
+ {
+ SMDS_MeshNode * n = static_cast<SMDS_MeshNode *>
+ (const_cast<SMDS_MeshElement *>(itn->next()));
+ n->RemoveInverseElement( (*it) );
+ }
+
+ switch((*it)->GetType())
+ {
+ case SMDSAbs_Node:
+ MESSAGE("Internal Error: This should not happen");
+ break;
+ case SMDSAbs_Edge:
+ myEdges.erase(static_cast<SMDS_MeshEdge*>
+ (const_cast<SMDS_MeshElement*>(*it)));
+ break;
+ case SMDSAbs_Face:
+ myFaces.erase(static_cast<SMDS_MeshFace*>
+ (const_cast<SMDS_MeshElement*>(*it)));
+ break;
+ case SMDSAbs_Volume:
+ myVolumes.erase(static_cast<SMDS_MeshVolume*>
+ (const_cast<SMDS_MeshElement*>(*it)));
+ break;
+ }
+ //MESSAGE( "SMDS: RM elem " << (*it)->GetID() );
+ removedElems.push_back( (*it) );
+ myElementIDFactory->ReleaseID((*it)->GetID());
+ delete (*it);
+ it++;
+ }
+
+ // remove exclusive (free) nodes
+ if(removenodes)
+ {
+ it=s2->begin();
+ while(it!=s2->end())
+ {
+ //MESSAGE( "SMDS: RM node " << (*it)->GetID() );
+ myNodes.erase(static_cast<SMDS_MeshNode*>
+ (const_cast<SMDS_MeshElement*>(*it)));
+ myNodeIDFactory->ReleaseID((*it)->GetID());
+ removedNodes.push_back( (*it) );
+ delete *it;
+ it++;
+ }
+ }
+
+ delete s2;
+ delete s1;
+}
+
+/*!
+ * Checks if the element is present in mesh.
+ * Useful to determine dead pointers.
*/
-int SMDS_Mesh::NbTriangles() const
-{
- SMDS_Iterator<const SMDS_MeshFace*> * it=facesIterator();
- int toReturn=0;
- while(it->more())
- {
- const SMDS_MeshFace * f=it->next();
- if(f->NbNodes()==3) toReturn++;
- }
- return toReturn;
+bool SMDS_Mesh::Contains (const SMDS_MeshElement* elem) const
+{
+ // we should not imply on validity of *elem, so iterate on containers
+ // of all types in the hope of finding <elem> somewhere there
+ SMDS_NodeIteratorPtr itn = nodesIterator();
+ while (itn->more())
+ if (elem == itn->next())
+ return true;
+ SMDS_EdgeIteratorPtr ite = edgesIterator();
+ while (ite->more())
+ if (elem == ite->next())
+ return true;
+ SMDS_FaceIteratorPtr itf = facesIterator();
+ while (itf->more())
+ if (elem == itf->next())
+ return true;
+ SMDS_VolumeIteratorPtr itv = volumesIterator();
+ while (itv->more())
+ if (elem == itv->next())
+ return true;
+ return false;
}
#include "SMDS_MeshElementIDFactory.hxx"
#include "SMDS_Iterator.hxx"
+#include <boost/shared_ptr.hpp>
#include <set>
#include <list>
class SMDSControl_BoundaryEdges;
-class SMDS_Mesh:public SMDS_MeshObject
-{
-
- public:
-
- SMDS_Mesh();
-
- SMDS_Iterator<const SMDS_MeshNode *> * nodesIterator() const;
- SMDS_Iterator<const SMDS_MeshEdge *> * edgesIterator() const;
- SMDS_Iterator<const SMDS_MeshFace *> * facesIterator() const;
- SMDS_Iterator<const SMDS_MeshVolume *> * volumesIterator() const;
-
- SMDS_Mesh *AddSubMesh();
- virtual SMDS_MeshNode* AddNode(double x, double y, double z);
- virtual SMDS_MeshNode* AddNodeWithID(double x, double y, double z, int ID);
-
- virtual SMDS_MeshEdge* AddEdge(
- const SMDS_MeshNode * n1,
- const SMDS_MeshNode * n2);
- virtual SMDS_MeshFace* AddFace(
- const SMDS_MeshNode * n1,
- const SMDS_MeshNode * n2,
- const SMDS_MeshNode * n3);
- virtual SMDS_MeshFace* AddFace(
- const SMDS_MeshNode * n1,
- const SMDS_MeshNode * n2,
- const SMDS_MeshNode * n3,
- const SMDS_MeshNode * n4);
- virtual SMDS_MeshVolume* AddVolume(
- const SMDS_MeshNode * n1,
- const SMDS_MeshNode * n2,
- const SMDS_MeshNode * n3,
- const SMDS_MeshNode * n4);
- virtual SMDS_MeshVolume* AddVolume(
- const SMDS_MeshNode * n1,
- const SMDS_MeshNode * n2,
- const SMDS_MeshNode * n3,
- const SMDS_MeshNode * n4,
- const SMDS_MeshNode * n5);
- virtual SMDS_MeshVolume* AddVolume(
- const SMDS_MeshNode * n1,
- const SMDS_MeshNode * n2,
- const SMDS_MeshNode * n3,
- const SMDS_MeshNode * n4,
- const SMDS_MeshNode * n5,
- const SMDS_MeshNode * n6);
- virtual SMDS_MeshVolume* AddVolume(
- const SMDS_MeshNode * n1,
- const SMDS_MeshNode * n2,
- const SMDS_MeshNode * n3,
- const SMDS_MeshNode * n4,
- const SMDS_MeshNode * n5,
- const SMDS_MeshNode * n6,
- const SMDS_MeshNode * n7,
- const SMDS_MeshNode * n8);
-
- SMDS_MeshEdge* AddEdgeWithID(int n1, int n2, int ID);
- SMDS_MeshFace* AddFaceWithID(int n1, int n2, int n3, int ID);
- SMDS_MeshFace* AddFaceWithID(int n1, int n2, int n3, int n4,
- int ID);
- SMDS_MeshVolume* AddVolumeWithID(int n1, int n2, int n3, int n4,
- int ID);
- SMDS_MeshVolume* AddVolumeWithID(int n1, int n2, int n3, int n4,
- int n5, int ID);
- SMDS_MeshVolume* AddVolumeWithID(int n1, int n2, int n3, int n4,
- int n5, int n6, int ID);
- SMDS_MeshVolume* AddVolumeWithID(int n1, int n2, int n3, int n4,
- int n5, int n6, int n7, int n8, int ID);
-
- SMDS_MeshEdge* AddEdgeWithID(
- const SMDS_MeshNode * n1,
- const SMDS_MeshNode * n2, int ID);
- SMDS_MeshFace* AddFaceWithID(
- const SMDS_MeshNode * n1,
- const SMDS_MeshNode * n2,
- const SMDS_MeshNode * n3, int ID);
- SMDS_MeshFace* AddFaceWithID(
- const SMDS_MeshNode * n1,
- const SMDS_MeshNode * n2,
- const SMDS_MeshNode * n3,
- const SMDS_MeshNode * n4, int ID);
- SMDS_MeshVolume* AddVolumeWithID(
- const SMDS_MeshNode * n1,
- const SMDS_MeshNode * n2,
- const SMDS_MeshNode * n3,
- const SMDS_MeshNode * n4, int ID);
- SMDS_MeshVolume* AddVolumeWithID(
- const SMDS_MeshNode * n1,
- const SMDS_MeshNode * n2,
- const SMDS_MeshNode * n3,
- const SMDS_MeshNode * n4,
- const SMDS_MeshNode * n5, int ID);
- SMDS_MeshVolume* AddVolumeWithID(
- const SMDS_MeshNode * n1,
- const SMDS_MeshNode * n2,
- const SMDS_MeshNode * n3,
- const SMDS_MeshNode * n4,
- const SMDS_MeshNode * n5,
- const SMDS_MeshNode * n6, int ID);
- SMDS_MeshVolume* AddVolumeWithID(
- const SMDS_MeshNode * n1,
- const SMDS_MeshNode * n2,
- const SMDS_MeshNode * n3,
- const SMDS_MeshNode * n4,
- const SMDS_MeshNode * n5,
- const SMDS_MeshNode * n6,
- const SMDS_MeshNode * n7,
- const SMDS_MeshNode * n8, int ID);
-
- virtual void RemoveElement(const SMDS_MeshElement * elem, const bool removenodes =
- false);
- virtual void RemoveNode(const SMDS_MeshNode * node);
- virtual void RemoveEdge(const SMDS_MeshEdge * edge);
- virtual void RemoveFace(const SMDS_MeshFace * face);
- virtual void RemoveVolume(const SMDS_MeshVolume * volume);
-
- virtual bool RemoveFromParent();
- virtual bool RemoveSubMesh(const SMDS_Mesh * aMesh);
-
- const SMDS_MeshNode *FindNode(int idnode) const;
- const SMDS_MeshEdge *FindEdge(int idnode1, int idnode2) const;
- const SMDS_MeshFace *FindFace(int idnode1, int idnode2, int idnode3) const;
- const SMDS_MeshFace *FindFace(int idnode1, int idnode2, int idnode3, int idnode4) const;
- const SMDS_MeshElement *FindElement(int IDelem) const;
+typedef SMDS_Iterator<const SMDS_MeshNode *> SMDS_NodeIterator;
+typedef boost::shared_ptr<SMDS_Iterator<const SMDS_MeshNode *> > SMDS_NodeIteratorPtr;
+typedef SMDS_Iterator<const SMDS_MeshEdge *> SMDS_EdgeIterator;
+typedef boost::shared_ptr<SMDS_Iterator<const SMDS_MeshEdge *> > SMDS_EdgeIteratorPtr;
+typedef SMDS_Iterator<const SMDS_MeshFace *> SMDS_FaceIterator;
+typedef boost::shared_ptr<SMDS_Iterator<const SMDS_MeshFace *> > SMDS_FaceIteratorPtr;
+typedef SMDS_Iterator<const SMDS_MeshVolume *> SMDS_VolumeIterator;
+typedef boost::shared_ptr<SMDS_Iterator<const SMDS_MeshVolume *> > SMDS_VolumeIteratorPtr;
+
+class SMDS_Mesh:public SMDS_MeshObject{
+public:
+
+ SMDS_Mesh();
+
+ SMDS_NodeIteratorPtr nodesIterator() const;
+ SMDS_EdgeIteratorPtr edgesIterator() const;
+ SMDS_FaceIteratorPtr facesIterator() const;
+ SMDS_VolumeIteratorPtr volumesIterator() const;
+
+ SMDS_Mesh *AddSubMesh();
+
+ virtual SMDS_MeshNode* AddNodeWithID(double x, double y, double z, int ID);
+ virtual SMDS_MeshNode* AddNode(double x, double y, double z);
+
+ virtual SMDS_MeshEdge* AddEdgeWithID(int n1, int n2, int ID);
+ virtual SMDS_MeshEdge* AddEdgeWithID(const SMDS_MeshNode * n1,
+ const SMDS_MeshNode * n2,
+ int ID);
+ virtual SMDS_MeshEdge* AddEdge(const SMDS_MeshNode * n1,
+ const SMDS_MeshNode * n2);
+
+ virtual SMDS_MeshFace* AddFaceWithID(int n1, int n2, int n3, int ID);
+ virtual SMDS_MeshFace* AddFaceWithID(const SMDS_MeshNode * n1,
+ const SMDS_MeshNode * n2,
+ const SMDS_MeshNode * n3,
+ int ID);
+ virtual SMDS_MeshFace* AddFace(const SMDS_MeshNode * n1,
+ const SMDS_MeshNode * n2,
+ const SMDS_MeshNode * n3);
+
+ virtual SMDS_MeshFace* AddFaceWithID(int n1, int n2, int n3, int n4, int ID);
+ virtual SMDS_MeshFace* AddFaceWithID(const SMDS_MeshNode * n1,
+ const SMDS_MeshNode * n2,
+ const SMDS_MeshNode * n3,
+ const SMDS_MeshNode * n4,
+ int ID);
+ virtual SMDS_MeshFace* AddFace(const SMDS_MeshNode * n1,
+ const SMDS_MeshNode * n2,
+ const SMDS_MeshNode * n3,
+ const SMDS_MeshNode * n4);
+
+ virtual SMDS_MeshFace* AddFaceWithID(const SMDS_MeshEdge * e1,
+ const SMDS_MeshEdge * e2,
+ const SMDS_MeshEdge * e3, int ID);
+ virtual SMDS_MeshFace* AddFace(const SMDS_MeshEdge * e1,
+ const SMDS_MeshEdge * e2,
+ const SMDS_MeshEdge * e3);
+
+ virtual SMDS_MeshFace* AddFaceWithID(const SMDS_MeshEdge * e1,
+ const SMDS_MeshEdge * e2,
+ const SMDS_MeshEdge * e3,
+ const SMDS_MeshEdge * e4, int ID);
+ virtual SMDS_MeshFace* AddFace(const SMDS_MeshEdge * e1,
+ const SMDS_MeshEdge * e2,
+ const SMDS_MeshEdge * e3,
+ const SMDS_MeshEdge * e4);
+
+ virtual SMDS_MeshVolume* AddVolumeWithID(int n1, int n2, int n3, int n4, int ID);
+ virtual SMDS_MeshVolume* AddVolumeWithID(const SMDS_MeshNode * n1,
+ const SMDS_MeshNode * n2,
+ const SMDS_MeshNode * n3,
+ const SMDS_MeshNode * n4,
+ int ID);
+ virtual SMDS_MeshVolume* AddVolume(const SMDS_MeshNode * n1,
+ const SMDS_MeshNode * n2,
+ const SMDS_MeshNode * n3,
+ const SMDS_MeshNode * n4);
+
+ virtual SMDS_MeshVolume* AddVolumeWithID(int n1, int n2, int n3, int n4,
+ int n5, int ID);
+ virtual SMDS_MeshVolume* AddVolumeWithID(const SMDS_MeshNode * n1,
+ const SMDS_MeshNode * n2,
+ const SMDS_MeshNode * n3,
+ const SMDS_MeshNode * n4,
+ const SMDS_MeshNode * n5,
+ int ID);
+ virtual SMDS_MeshVolume* AddVolume(const SMDS_MeshNode * n1,
+ const SMDS_MeshNode * n2,
+ const SMDS_MeshNode * n3,
+ const SMDS_MeshNode * n4,
+ const SMDS_MeshNode * n5);
+
+ virtual SMDS_MeshVolume* AddVolumeWithID(int n1, int n2, int n3, int n4,
+ int n5, int n6, int ID);
+ virtual SMDS_MeshVolume* AddVolumeWithID(const SMDS_MeshNode * n1,
+ const SMDS_MeshNode * n2,
+ const SMDS_MeshNode * n3,
+ const SMDS_MeshNode * n4,
+ const SMDS_MeshNode * n5,
+ const SMDS_MeshNode * n6,
+ int ID);
+ virtual SMDS_MeshVolume* AddVolume(const SMDS_MeshNode * n1,
+ const SMDS_MeshNode * n2,
+ const SMDS_MeshNode * n3,
+ const SMDS_MeshNode * n4,
+ const SMDS_MeshNode * n5,
+ const SMDS_MeshNode * n6);
+
+ virtual SMDS_MeshVolume* AddVolumeWithID(int n1, int n2, int n3, int n4,
+ int n5, int n6, int n7, int n8, int ID);
+ virtual SMDS_MeshVolume* AddVolumeWithID(const SMDS_MeshNode * n1,
+ const SMDS_MeshNode * n2,
+ const SMDS_MeshNode * n3,
+ const SMDS_MeshNode * n4,
+ const SMDS_MeshNode * n5,
+ const SMDS_MeshNode * n6,
+ const SMDS_MeshNode * n7,
+ const SMDS_MeshNode * n8,
+ int ID);
+ virtual SMDS_MeshVolume* AddVolume(const SMDS_MeshNode * n1,
+ const SMDS_MeshNode * n2,
+ const SMDS_MeshNode * n3,
+ const SMDS_MeshNode * n4,
+ const SMDS_MeshNode * n5,
+ const SMDS_MeshNode * n6,
+ const SMDS_MeshNode * n7,
+ const SMDS_MeshNode * n8);
+
+ virtual SMDS_MeshVolume* AddVolumeWithID(const SMDS_MeshFace * f1,
+ const SMDS_MeshFace * f2,
+ const SMDS_MeshFace * f3,
+ const SMDS_MeshFace * f4, int ID);
+ virtual SMDS_MeshVolume* AddVolume(const SMDS_MeshFace * f1,
+ const SMDS_MeshFace * f2,
+ const SMDS_MeshFace * f3,
+ const SMDS_MeshFace * f4);
+
+ virtual SMDS_MeshVolume* AddVolumeWithID(const SMDS_MeshFace * f1,
+ const SMDS_MeshFace * f2,
+ const SMDS_MeshFace * f3,
+ const SMDS_MeshFace * f4,
+ const SMDS_MeshFace * f5, int ID);
+ virtual SMDS_MeshVolume* AddVolume(const SMDS_MeshFace * f1,
+ const SMDS_MeshFace * f2,
+ const SMDS_MeshFace * f3,
+ const SMDS_MeshFace * f4,
+ const SMDS_MeshFace * f5);
+
+ virtual SMDS_MeshVolume* AddVolumeWithID(const SMDS_MeshFace * f1,
+ const SMDS_MeshFace * f2,
+ const SMDS_MeshFace * f3,
+ const SMDS_MeshFace * f4,
+ const SMDS_MeshFace * f5,
+ const SMDS_MeshFace * f6, int ID);
+ virtual SMDS_MeshVolume* AddVolume(const SMDS_MeshFace * f1,
+ const SMDS_MeshFace * f2,
+ const SMDS_MeshFace * f3,
+ const SMDS_MeshFace * f4,
+ const SMDS_MeshFace * f5,
+ const SMDS_MeshFace * f6);
+
+ virtual void RemoveElement(const SMDS_MeshElement * elem,
+ list<const SMDS_MeshElement *>& removedElems,
+ list<const SMDS_MeshElement *>& removedNodes,
+ const bool removenodes = false);
+ virtual void RemoveElement(const SMDS_MeshElement * elem, const bool removenodes = false);
+ virtual void RemoveNode(const SMDS_MeshNode * node);
+ virtual void RemoveEdge(const SMDS_MeshEdge * edge);
+ virtual void RemoveFace(const SMDS_MeshFace * face);
+ virtual void RemoveVolume(const SMDS_MeshVolume * volume);
+
+ virtual bool RemoveFromParent();
+ virtual bool RemoveSubMesh(const SMDS_Mesh * aMesh);
+
+ const SMDS_MeshNode *FindNode(int idnode) const;
+ const SMDS_MeshEdge *FindEdge(int idnode1, int idnode2) const;
+ const SMDS_MeshFace *FindFace(int idnode1, int idnode2, int idnode3) const;
+ const SMDS_MeshFace *FindFace(int idnode1, int idnode2, int idnode3, int idnode4) const;
+ const SMDS_MeshElement *FindElement(int IDelem) const;
- int NbNodes() const;
- int NbEdges() const;
- int NbFaces() const;
- int NbTriangles() const;
- int NbVolumes() const;
- int NbSubMesh() const;
- void DumpNodes() const;
- void DumpEdges() const;
- void DumpFaces() const;
- void DumpVolumes() const;
- void DebugStats() const;
- SMDS_Mesh *boundaryFaces();
- SMDS_Mesh *boundaryEdges();
- virtual ~SMDS_Mesh();
- bool hasConstructionEdges();
- bool hasConstructionFaces();
- bool hasInverseElements();
- void setConstructionEdges(bool);
- void setConstructionFaces(bool);
- void setInverseElements(bool);
-
- double * getNodesCoordinates();
- long * getNodesID();
- long * getEdgesIndices();
- long * getTrianglesIndices();
-
- private:
- SMDS_Mesh(SMDS_Mesh * parent);
- SMDS_MeshFace * createTriangle(SMDS_MeshNode * node1,
- SMDS_MeshNode * node2, SMDS_MeshNode * node3);
- SMDS_MeshFace * createQuadrangle(SMDS_MeshNode * node1,
- SMDS_MeshNode * node2, SMDS_MeshNode * node3, SMDS_MeshNode * node4);
- const SMDS_MeshEdge* FindEdge(const SMDS_MeshNode * n1,
- const SMDS_MeshNode * n2) const;
- SMDS_MeshEdge* FindEdgeOrCreate(const SMDS_MeshNode * n1,
- const SMDS_MeshNode * n2);
- SMDS_MeshFace* FindFaceOrCreate(
- const SMDS_MeshNode *n1,
- const SMDS_MeshNode *n2,
- const SMDS_MeshNode *n3);
- const SMDS_MeshFace* FindFace(
- const SMDS_MeshNode *n1,
- const SMDS_MeshNode *n2,
- const SMDS_MeshNode *n3,
- const SMDS_MeshNode *n4) const;
- SMDS_MeshFace* FindFaceOrCreate(
- const SMDS_MeshNode *n1,
- const SMDS_MeshNode *n2,
- const SMDS_MeshNode *n3,
- const SMDS_MeshNode *n4);
- void addChildrenWithNodes(set<const SMDS_MeshElement*>& setOfChildren,
- const SMDS_MeshElement * element, set<const SMDS_MeshElement*>& nodes);
-
- // Fields PRIVATE
- typedef set<SMDS_MeshNode *> SetOfNodes;
- typedef set<SMDS_MeshEdge *> SetOfEdges;
- typedef set<SMDS_MeshFace *> SetOfFaces;
- typedef set<SMDS_MeshVolume *> SetOfVolumes;
-
- SetOfNodes myNodes;
- SetOfEdges myEdges;
- SetOfFaces myFaces;
- SetOfVolumes myVolumes;
- SMDS_Mesh *myParent;
- list<SMDS_Mesh *> myChildren;
- SMDS_MeshElementIDFactory *myNodeIDFactory;
- SMDS_MeshElementIDFactory *myElementIDFactory;
-
- bool myHasConstructionEdges;
- bool myHasConstructionFaces;
- bool myHasInverseElements;
+ int NbNodes() const;
+ int NbEdges() const;
+ int NbFaces() const;
+ int NbVolumes() const;
+ int NbSubMesh() const;
+ void DumpNodes() const;
+ void DumpEdges() const;
+ void DumpFaces() const;
+ void DumpVolumes() const;
+ void DebugStats() const;
+ SMDS_Mesh *boundaryFaces();
+ SMDS_Mesh *boundaryEdges();
+ virtual ~SMDS_Mesh();
+ bool hasConstructionEdges();
+ bool hasConstructionFaces();
+ bool hasInverseElements();
+ void setConstructionEdges(bool);
+ void setConstructionFaces(bool);
+ void setInverseElements(bool);
+
+ /*!
+ * Checks if the element is present in mesh.
+ * Useful to determine dead pointers.
+ * Use this function for debug purpose only! Do not check in the code
+ * using it even in _DEBUG_ mode
+ */
+ bool Contains (const SMDS_MeshElement* elem) const;
+
+ typedef set<SMDS_MeshNode *> SetOfNodes;
+ typedef set<SMDS_MeshEdge *> SetOfEdges;
+ typedef set<SMDS_MeshFace *> SetOfFaces;
+ typedef set<SMDS_MeshVolume *> SetOfVolumes;
+
+private:
+ SMDS_Mesh(SMDS_Mesh * parent);
+
+ SMDS_MeshFace * createTriangle(const SMDS_MeshNode * node1,
+ const SMDS_MeshNode * node2,
+ const SMDS_MeshNode * node3);
+
+ SMDS_MeshFace * createQuadrangle(const SMDS_MeshNode * node1,
+ const SMDS_MeshNode * node2,
+ const SMDS_MeshNode * node3,
+ const SMDS_MeshNode * node4);
+
+ bool registerElement(int ID, SMDS_MeshElement * element);
+
+ const SMDS_MeshEdge* FindEdge(const SMDS_MeshNode * n1,
+ const SMDS_MeshNode * n2) const;
+
+ SMDS_MeshEdge* FindEdgeOrCreate(const SMDS_MeshNode * n1,
+ const SMDS_MeshNode * n2);
+
+ const SMDS_MeshFace* FindFace(const SMDS_MeshNode *n1,
+ const SMDS_MeshNode *n2,
+ const SMDS_MeshNode *n3) const;
+
+ SMDS_MeshFace* FindFaceOrCreate(const SMDS_MeshNode *n1,
+ const SMDS_MeshNode *n2,
+ const SMDS_MeshNode *n3);
+
+ const SMDS_MeshFace* FindFace(const SMDS_MeshNode *n1,
+ const SMDS_MeshNode *n2,
+ const SMDS_MeshNode *n3,
+ const SMDS_MeshNode *n4) const;
+
+ SMDS_MeshFace* FindFaceOrCreate(const SMDS_MeshNode *n1,
+ const SMDS_MeshNode *n2,
+ const SMDS_MeshNode *n3,
+ const SMDS_MeshNode *n4);
+
+ void addChildrenWithNodes(set<const SMDS_MeshElement*>& setOfChildren,
+ const SMDS_MeshElement * element,
+ set<const SMDS_MeshElement*>& nodes);
+
+ // Fields PRIVATE
+
+ SetOfNodes myNodes;
+ SetOfEdges myEdges;
+ SetOfFaces myFaces;
+ SetOfVolumes myVolumes;
+ SMDS_Mesh *myParent;
+ list<SMDS_Mesh *> myChildren;
+ SMDS_MeshElementIDFactory *myNodeIDFactory;
+ SMDS_MeshElementIDFactory *myElementIDFactory;
+
+ bool myHasConstructionEdges;
+ bool myHasConstructionFaces;
+ bool myHasInverseElements;
};
#endif
//purpose :
//=======================================================================
-SMDS_MeshEdge::SMDS_MeshEdge(SMDS_MeshNode * node1, SMDS_MeshNode * node2)
+SMDS_MeshEdge::SMDS_MeshEdge(const SMDS_MeshNode * node1,
+ const SMDS_MeshNode * node2)
{
myNodes[0]=node1;
myNodes[1]=node2;
return SMDSAbs_Edge;
}
-SMDS_Iterator<const SMDS_MeshElement *> * SMDS_MeshEdge::
+class SMDS_MeshEdge_MyNodeIterator:public SMDS_ElemIterator
+{
+ const SMDS_MeshNode *const* myNodes;
+ int myIndex;
+ public:
+ SMDS_MeshEdge_MyNodeIterator(const SMDS_MeshNode * const* nodes):
+ myNodes(nodes),myIndex(0) {}
+
+ bool more()
+ {
+ return myIndex<2;
+ }
+
+ const SMDS_MeshElement* next()
+ {
+ myIndex++;
+ return myNodes[myIndex-1];
+ }
+};
+
+SMDS_ElemIteratorPtr SMDS_MeshEdge::
elementsIterator(SMDSAbs_ElementType type) const
{
- class MyNodeIterator:public SMDS_Iterator<const SMDS_MeshElement *>
- {
- SMDS_MeshNode *const* myNodes;
- int myIndex;
- public:
- MyNodeIterator(SMDS_MeshNode * const* nodes):myNodes(nodes),myIndex(0)
- {}
-
- bool more()
- {
- return myIndex<2;
- }
-
- const SMDS_MeshElement* next()
- {
- myIndex++;
- return myNodes[myIndex-1];
- }
- };
-
- switch(type)
- {
- case SMDSAbs_Edge:return SMDS_MeshElement::elementsIterator(SMDSAbs_Edge);
- case SMDSAbs_Node:return new MyNodeIterator(myNodes);
- default: return new SMDS_IteratorOfElements(this,type, nodesIterator());
- }
-
+ switch(type)
+ {
+ case SMDSAbs_Edge:
+ return SMDS_MeshElement::elementsIterator(SMDSAbs_Edge);
+ case SMDSAbs_Node:
+ return SMDS_ElemIteratorPtr(new SMDS_MeshEdge_MyNodeIterator(myNodes));
+ default:
+ return SMDS_ElemIteratorPtr
+ (new SMDS_IteratorOfElements
+ (this,type, SMDS_ElemIteratorPtr(new SMDS_MeshEdge_MyNodeIterator(myNodes))));
+ }
}
bool operator<(const SMDS_MeshEdge & e1, const SMDS_MeshEdge & e2)
{
public:
- SMDS_MeshEdge(SMDS_MeshNode * node1, SMDS_MeshNode * node2);
+ SMDS_MeshEdge(const SMDS_MeshNode * node1,
+ const SMDS_MeshNode * node2);
void Print(ostream & OS) const;
SMDSAbs_ElementType GetType() const;
int NbEdges() const;
friend bool operator<(const SMDS_MeshEdge& e1, const SMDS_MeshEdge& e2);
protected:
- SMDS_Iterator<const SMDS_MeshElement *> *
+ SMDS_ElemIteratorPtr
elementsIterator(SMDSAbs_ElementType type) const;
private:
- SMDS_MeshNode* myNodes[2];
+ const SMDS_MeshNode* myNodes[2];
};
#endif
/// Create an iterator which iterate on nodes owned by the element.
/// This method call elementsIterator().
///////////////////////////////////////////////////////////////////////////////
-SMDS_Iterator<const SMDS_MeshElement *> * SMDS_MeshElement::nodesIterator() const
+SMDS_ElemIteratorPtr SMDS_MeshElement::nodesIterator() const
{
return elementsIterator(SMDSAbs_Node);
}
/// Create an iterator which iterate on edges linked with or owned by the element.
/// This method call elementsIterator().
///////////////////////////////////////////////////////////////////////////////
-SMDS_Iterator<const SMDS_MeshElement *> * SMDS_MeshElement::edgesIterator() const
+SMDS_ElemIteratorPtr SMDS_MeshElement::edgesIterator() const
{
return elementsIterator(SMDSAbs_Edge);
}
/// Create an iterator which iterate on faces linked with or owned by the element.
/// This method call elementsIterator().
///////////////////////////////////////////////////////////////////////////////
-SMDS_Iterator<const SMDS_MeshElement *> * SMDS_MeshElement::facesIterator() const
+SMDS_ElemIteratorPtr SMDS_MeshElement::facesIterator() const
{
return elementsIterator(SMDSAbs_Face);
}
int SMDS_MeshElement::NbNodes() const
{
int nbnodes=0;
- SMDS_Iterator<const SMDS_MeshElement *> * it=nodesIterator();
+ SMDS_ElemIteratorPtr it=nodesIterator();
while(it->more())
{
it->next();
nbnodes++;
}
- delete it;
return nbnodes;
}
int SMDS_MeshElement::NbEdges() const
{
int nbedges=0;
- SMDS_Iterator<const SMDS_MeshElement *> * it=edgesIterator();
+ SMDS_ElemIteratorPtr it=edgesIterator();
while(it->more())
{
it->next();
nbedges++;
}
- delete it;
return nbedges;
}
int SMDS_MeshElement::NbFaces() const
{
int nbfaces=0;
- SMDS_Iterator<const SMDS_MeshElement *> * it=facesIterator();
+ SMDS_ElemIteratorPtr it=facesIterator();
while(it->more())
{
it->next();
nbfaces++;
}
- delete it;
return nbfaces;
}
///////////////////////////////////////////////////////////////////////////////
-///Create and iterator which iterate on elements linked with the current element.
-///The iterator must be free by the caller (call delete myIterator).
+///Create an iterator which iterate on elements linked with the current element.
///@param type The of elements on which you want to iterate
-///@return An iterator, that you must free when you no longer need it
+///@return A smart pointer to iterator, you are not to take care of freeing memory
///////////////////////////////////////////////////////////////////////////////
-SMDS_Iterator<const SMDS_MeshElement *> * SMDS_MeshElement::
+class SMDS_MeshElement_MyIterator:public SMDS_ElemIterator
+{
+ const SMDS_MeshElement * myElement;
+ bool myMore;
+ public:
+ SMDS_MeshElement_MyIterator(const SMDS_MeshElement * element):
+ myElement(element),myMore(true) {}
+
+ bool more()
+ {
+ return myMore;
+ }
+
+ const SMDS_MeshElement* next()
+ {
+ myMore=false;
+ return myElement;
+ }
+};
+SMDS_ElemIteratorPtr SMDS_MeshElement::
elementsIterator(SMDSAbs_ElementType type) const
{
/** @todo Check that iterator in the child classes return elements
in the same order for each different implementation (i.e: SMDS_VolumeOfNodes
and SMDS_VolumeOfFaces */
- class MyIterator:public SMDS_Iterator<const SMDS_MeshElement*>
- {
- const SMDS_MeshElement * myElement;
- bool myMore;
- public:
- MyIterator(const SMDS_MeshElement * element):
- myElement(element),myMore(true)
- {
- }
-
- bool more()
- {
- return myMore;
- }
-
- const SMDS_MeshElement* next()
- {
- myMore=false;
- return myElement;
- }
- };
- if(type==GetType()) return new MyIterator(this);
+ if(type==GetType())
+ return SMDS_ElemIteratorPtr(new SMDS_MeshElement_MyIterator(this));
else
{
- MESSAGE("Iterator not implemented");
- return NULL;
+ MESSAGE("Iterator not implemented");
+ return SMDS_ElemIteratorPtr((SMDS_ElemIterator*)NULL);
}
}
#include "SMDS_Iterator.hxx"
#include "SMDS_MeshElementIDFactory.hxx"
+#include <boost/shared_ptr.hpp>
#include <vector>
#include <iostream>
class SMDS_MeshNode;
class SMDS_MeshEdge;
class SMDS_MeshFace;
+class SMDS_MeshElement;
+
+typedef SMDS_Iterator<const SMDS_MeshElement *> SMDS_ElemIterator;
+typedef boost::shared_ptr<SMDS_Iterator<const SMDS_MeshElement *> > SMDS_ElemIteratorPtr;
///////////////////////////////////////////////////////////////////////////////
/// Base class for elements
{
public:
- SMDS_Iterator<const SMDS_MeshElement *> * nodesIterator() const;
- SMDS_Iterator<const SMDS_MeshElement *> * edgesIterator() const;
- SMDS_Iterator<const SMDS_MeshElement *> * facesIterator() const;
- virtual SMDS_Iterator<const SMDS_MeshElement *> *
+ SMDS_ElemIteratorPtr nodesIterator() const;
+ SMDS_ElemIteratorPtr edgesIterator() const;
+ SMDS_ElemIteratorPtr facesIterator() const;
+ virtual SMDS_ElemIteratorPtr
elementsIterator(SMDSAbs_ElementType type) const;
virtual int NbNodes() const;
map<int, SMDS_MeshElement*>::iterator it=myIDElements.find(ID);
if(it==myIDElements.end()) return NULL; else return (*it).second;
}
+
+
+//=======================================================================
+//function : GetFreeID
+//purpose :
+//=======================================================================
+int SMDS_MeshElementIDFactory::GetFreeID()
+{
+ int ID;
+ do {
+ ID = SMDS_MeshIDFactory::GetFreeID();
+ } while (myIDElements.find(ID) != myIDElements.end());
+ return ID;
+}
+
+//=======================================================================
+//function : ReleaseID
+//purpose :
+//=======================================================================
+void SMDS_MeshElementIDFactory::ReleaseID(const int ID)
+{
+ myIDElements.erase(ID);
+ SMDS_MeshIDFactory::ReleaseID(ID);
+}
#define _SMDS_MeshElementIDFactory_HeaderFile
#include "SMDS_MeshIDFactory.hxx"
-#include <SMDS_Iterator.hxx>
#include <map>
using namespace std;
SMDS_MeshElementIDFactory();
bool BindID(int ID, SMDS_MeshElement * elem);
SMDS_MeshElement * MeshElement(int ID);
+ virtual int GetFreeID();
+ virtual void ReleaseID(int ID);
private:
map<int, SMDS_MeshElement *> myIDElements;
//purpose :
//=======================================================================
-SMDS_MeshGroup::SMDS_MeshGroup(const SMDS_Mesh * aMesh)
- :myMesh(aMesh),myType(SMDSAbs_All), myParent(NULL)
+SMDS_MeshGroup::SMDS_MeshGroup(const SMDS_Mesh * theMesh,
+ const SMDSAbs_ElementType theType)
+ :myMesh(theMesh),myType(theType), myParent(NULL)
{
}
//purpose :
//=======================================================================
-SMDS_MeshGroup::SMDS_MeshGroup(SMDS_MeshGroup * parent)
- :myMesh(parent->myMesh),myType(SMDSAbs_All), myParent(parent)
+SMDS_MeshGroup::SMDS_MeshGroup(SMDS_MeshGroup * theParent,
+ const SMDSAbs_ElementType theType)
+ :myMesh(theParent->myMesh),myType(theType), myParent(theParent)
{
}
//purpose :
//=======================================================================
-const SMDS_MeshGroup *SMDS_MeshGroup::AddSubGroup()
+const SMDS_MeshGroup *SMDS_MeshGroup::AddSubGroup
+ (const SMDSAbs_ElementType theType)
{
- const SMDS_MeshGroup * subgroup = new SMDS_MeshGroup(this);
+ const SMDS_MeshGroup * subgroup = new SMDS_MeshGroup(this,theType);
myChildren.insert(myChildren.end(),subgroup);
return subgroup;
}
//purpose :
//=======================================================================
-bool SMDS_MeshGroup::RemoveSubGroup(const SMDS_MeshGroup * aGroup)
+bool SMDS_MeshGroup::RemoveSubGroup(const SMDS_MeshGroup * theGroup)
{
bool found = false;
list<const SMDS_MeshGroup*>::iterator itgroup;
for(itgroup=myChildren.begin(); itgroup!=myChildren.end(); itgroup++)
{
const SMDS_MeshGroup* subgroup=*itgroup;
- if (subgroup == aGroup)
+ if (subgroup == theGroup)
{
found = true;
myChildren.erase(itgroup);
myType = SMDSAbs_All;
}
-//=======================================================================
-//function : IsEmpty
-//purpose :
-//=======================================================================
-
-bool SMDS_MeshGroup::IsEmpty() const
-{
- return myElements.empty();
-}
-
-//=======================================================================
-//function : Extent
-//purpose :
-//=======================================================================
-
-int SMDS_MeshGroup::Extent() const
-{
- return myElements.size();
-}
-
//=======================================================================
//function : Add
//purpose :
//=======================================================================
-void SMDS_MeshGroup::Add(const SMDS_MeshElement * ME)
+void SMDS_MeshGroup::Add(const SMDS_MeshElement * theElem)
{
// the type of the group is determined by the first element added
- if (myElements.empty()) myType = ME->GetType();
- else if (ME->GetType() != myType)
+ if (myElements.empty()) myType = theElem->GetType();
+ else if (theElem->GetType() != myType)
MESSAGE("SMDS_MeshGroup::Add : Type Mismatch");
- myElements.insert(ME);
+ myElements.insert(theElem);
}
//=======================================================================
//purpose :
//=======================================================================
-void SMDS_MeshGroup::Remove(const SMDS_MeshElement * ME)
+void SMDS_MeshGroup::Remove(const SMDS_MeshElement * theElem)
{
- myElements.erase(ME);
+ myElements.erase(theElem);
if (myElements.empty()) myType = SMDSAbs_All;
}
//=======================================================================
-//function : Type
+//function : Contains
//purpose :
//=======================================================================
-SMDSAbs_ElementType SMDS_MeshGroup::Type() const
+bool SMDS_MeshGroup::Contains(const SMDS_MeshElement * theElem) const
{
- return myType;
+ return myElements.find(theElem)!=myElements.end();
}
//=======================================================================
-//function : Contains
+//function : SetType
//purpose :
//=======================================================================
-bool SMDS_MeshGroup::Contains(const SMDS_MeshElement * ME) const
+void SMDS_MeshGroup::SetType(const SMDSAbs_ElementType theType)
{
- return myElements.find(ME)!=myElements.end();
+ if (IsEmpty())
+ myType = theType;
}
class SMDS_MeshGroup:public SMDS_MeshObject
{
public:
- SMDS_MeshGroup(const SMDS_Mesh * aMesh);
- const SMDS_MeshGroup * AddSubGroup();
- virtual bool RemoveSubGroup(const SMDS_MeshGroup* aGroup);
+ SMDS_MeshGroup(const SMDS_Mesh * theMesh,
+ const SMDSAbs_ElementType theType = SMDSAbs_All);
+ const SMDS_MeshGroup * AddSubGroup
+ (const SMDSAbs_ElementType theType = SMDSAbs_All);
+ virtual bool RemoveSubGroup(const SMDS_MeshGroup* theGroup);
virtual bool RemoveFromParent();
- void Clear();
- void Add(const SMDS_MeshElement * ME);
- void Remove(const SMDS_MeshElement * ME);
- bool IsEmpty() const;
- int Extent() const;
- SMDSAbs_ElementType Type() const;
- bool Contains(const SMDS_MeshElement * ME) const;
-
- ~SMDS_MeshGroup();
+
+ const SMDS_Mesh* GetMesh() const { return myMesh; }
+
+ void SetType (const SMDSAbs_ElementType theType);
+ void Clear();
+ void Add(const SMDS_MeshElement * theElem);
+ void Remove(const SMDS_MeshElement * theElem);
+ bool IsEmpty() const { return myElements.empty(); }
+ int Extent() const { return myElements.size(); }
+
+ SMDSAbs_ElementType GetType() const { return myType; }
+
+ bool Contains(const SMDS_MeshElement * theElem) const;
+
+ void InitIterator() const
+ { const_cast<iterator&>(myIterator) = myElements.begin(); }
+
+ bool More() const { return myIterator != myElements.end(); }
+
+ const SMDS_MeshElement* Next() const
+ { return *(const_cast<iterator&>(myIterator))++; }
+
private:
- SMDS_MeshGroup(SMDS_MeshGroup* parent);
- const SMDS_Mesh *myMesh;
- SMDSAbs_ElementType myType;
- set<const SMDS_MeshElement *> myElements;
- SMDS_MeshGroup * myParent;
- list<const SMDS_MeshGroup*> myChildren;
+ SMDS_MeshGroup(SMDS_MeshGroup* theParent,
+ const SMDSAbs_ElementType theType = SMDSAbs_All);
+
+ typedef set<const SMDS_MeshElement *>::iterator iterator;
+ const SMDS_Mesh * myMesh;
+ SMDSAbs_ElementType myType;
+ set<const SMDS_MeshElement *> myElements;
+ SMDS_MeshGroup * myParent;
+ list<const SMDS_MeshGroup*> myChildren;
+ iterator myIterator;
};
#endif
//=======================================================================
void SMDS_MeshIDFactory::ReleaseID(const int ID)
{
- if (ID < myMaxID) myPoolOfID.push(ID);
+ if (ID > 0 && ID < myMaxID) myPoolOfID.push(ID);
}
//purpose :
//=======================================================================
-void SMDS_MeshNode::SetPosition(SMDS_Position * aPos)
+void SMDS_MeshNode::SetPosition(const SMDS_PositionPtr& aPos)
{
myPosition = aPos;
}
//purpose :
//=======================================================================
-SMDS_Position *SMDS_MeshNode::GetPosition()
+const SMDS_PositionPtr& SMDS_MeshNode::GetPosition() const
{
return myPosition;
}
-const SMDS_Position *SMDS_MeshNode::GetPosition() const
+class SMDS_MeshNode_MyInvIterator:public SMDS_ElemIterator
{
- return myPosition;
-}
-/**
-*/
-SMDS_Iterator<const SMDS_MeshElement*> * SMDS_MeshNode::
+ const set<const SMDS_MeshElement*>& mySet;
+ set<const SMDS_MeshElement*>::iterator myIterator;
+ public:
+ SMDS_MeshNode_MyInvIterator(const set<const SMDS_MeshElement*>& s):
+ mySet(s)
+ {
+ myIterator=mySet.begin();
+ }
+
+ bool more()
+ {
+ return myIterator!=mySet.end();
+ }
+
+ const SMDS_MeshElement* next()
+ {
+ const SMDS_MeshElement* current=*myIterator;
+ myIterator++;
+ return current;
+ }
+};
+
+SMDS_ElemIteratorPtr SMDS_MeshNode::
GetInverseElementIterator() const
{
- class SMDS_InverseElementIterator:public SMDS_Iterator<const SMDS_MeshElement*>
- {
- const set<const SMDS_MeshElement*>& mySet;
- set<const SMDS_MeshElement*>::iterator myIterator;
- public:
- SMDS_InverseElementIterator(const set<const SMDS_MeshElement*>& s):mySet(s)
- {
- myIterator=mySet.begin();
- }
-
- bool more()
- {
- return myIterator!=mySet.end();
- }
-
- const SMDS_MeshElement* next()
- {
- const SMDS_MeshElement* current=*myIterator;
- myIterator++;
- return current;
- }
- };
- return new SMDS_InverseElementIterator(myInverseElements);
-}
-
-SMDS_Iterator<const SMDS_MeshElement *> * SMDS_MeshNode::
+ return SMDS_ElemIteratorPtr(new SMDS_MeshNode_MyInvIterator(myInverseElements));
+}
+
+// Same as GetInverseElementIterator but the create iterator only return
+// wanted type elements.
+class SMDS_MeshNode_MyIterator:public SMDS_ElemIterator
+{
+ set<const SMDS_MeshElement*> mySet;
+ set<const SMDS_MeshElement*>::iterator myIterator;
+ public:
+ SMDS_MeshNode_MyIterator(SMDSAbs_ElementType type,
+ const set<const SMDS_MeshElement*>& s)
+ {
+ const SMDS_MeshElement * e;
+ bool toInsert;
+ set<const SMDS_MeshElement*>::iterator it=s.begin();
+ while(it!=s.end())
+ {
+ e=*it;
+ switch(type)
+ {
+ case SMDSAbs_Edge: toInsert=true; break;
+ case SMDSAbs_Face: toInsert=(e->GetType()!=SMDSAbs_Edge); break;
+ case SMDSAbs_Volume: toInsert=(e->GetType()==SMDSAbs_Volume); break;
+ }
+ if(toInsert) mySet.insert(e);
+ it++;
+ }
+ myIterator=mySet.begin();
+ }
+
+ bool more()
+ {
+ return myIterator!=mySet.end();
+ }
+
+ const SMDS_MeshElement* next()
+ {
+ const SMDS_MeshElement* current=*myIterator;
+ myIterator++;
+ return current;
+ }
+};
+
+SMDS_ElemIteratorPtr SMDS_MeshNode::
elementsIterator(SMDSAbs_ElementType type) const
{
- // Same as GetInverseElementIterator but the create iterator only return
- // wanted type elements.
- class MyIterator:public SMDS_Iterator<const SMDS_MeshElement*>
- {
- set<const SMDS_MeshElement*> mySet;
- set<const SMDS_MeshElement*>::iterator myIterator;
- public:
- MyIterator(SMDSAbs_ElementType type,
- const set<const SMDS_MeshElement*>& s)
- {
- const SMDS_MeshElement * e;
- bool toInsert;
- set<const SMDS_MeshElement*>::iterator it=s.begin();
- while(it!=s.end())
- {
- e=*it;
- switch(type)
- {
- case SMDSAbs_Edge: toInsert=true; break;
- case SMDSAbs_Face: toInsert=(e->GetType()!=SMDSAbs_Edge); break;
- case SMDSAbs_Volume: toInsert=(e->GetType()==SMDSAbs_Volume); break;
- }
- if(toInsert) mySet.insert(e);
- it++;
- }
- myIterator=mySet.begin();
- }
-
- bool more()
- {
- return myIterator!=mySet.end();
- }
-
- const SMDS_MeshElement* next()
- {
- const SMDS_MeshElement* current=*myIterator;
- myIterator++;
- return current;
- }
- };
-
- if(type==SMDSAbs_Node)
- return SMDS_MeshElement::elementsIterator(SMDSAbs_Node);
- else
- return new SMDS_IteratorOfElements(this,type,
- new MyIterator(type, myInverseElements));
+ if(type==SMDSAbs_Node)
+ return SMDS_MeshElement::elementsIterator(SMDSAbs_Node);
+ else
+ return SMDS_ElemIteratorPtr
+ (new SMDS_IteratorOfElements
+ (this,type,
+ SMDS_ElemIteratorPtr(new SMDS_MeshNode_MyIterator(type, myInverseElements))));
}
int SMDS_MeshNode::NbNodes() const
void RemoveInverseElement(const SMDS_MeshElement * parent);
void ClearInverseElements();
bool emptyInverseElements();
- SMDS_Iterator<const SMDS_MeshElement*> * GetInverseElementIterator() const;
- void SetPosition(SMDS_Position * aPos);
- SMDS_Position *GetPosition();
- const SMDS_Position *GetPosition() const;
+ SMDS_ElemIteratorPtr GetInverseElementIterator() const;
+ void SetPosition(const SMDS_PositionPtr& aPos);
+ const SMDS_PositionPtr& GetPosition() const;
SMDSAbs_ElementType GetType() const;
int NbNodes() const;
void setXYZ(double x, double y, double z);
friend bool operator<(const SMDS_MeshNode& e1, const SMDS_MeshNode& e2);
protected:
- SMDS_Iterator<const SMDS_MeshElement *> *
+ SMDS_ElemIteratorPtr
elementsIterator(SMDSAbs_ElementType type) const;
private:
double myX, myY, myZ;
- SMDS_Position *myPosition;
+ SMDS_PositionPtr myPosition;
set<const SMDS_MeshElement*> myInverseElements;
};
class SMDS_MeshObject
{
- public:
+ public:
+ virtual ~SMDS_MeshObject() {}
};
#endif
{
return myShapeId;
}
-
-SMDS_Position::~SMDS_Position()
-{
-}
#define _SMDS_Position_HeaderFile
#include "SMDS_TypeOfPosition.hxx"
+#include <boost/shared_ptr.hpp>
+
+class SMDS_Position;
+typedef boost::shared_ptr<SMDS_Position> SMDS_PositionPtr;
class SMDS_Position
{
virtual inline SMDS_TypeOfPosition GetTypeOfPosition() const = 0;
void SetShapeId(int aShapeId);
int GetShapeId() const;
- ~SMDS_Position();
+ virtual ~SMDS_Position() {}
protected:
SMDS_Position(int aShapeId);
return myCoords;
}
-SMDS_SpacePosition * SMDS_SpacePosition::originSpacePosition()
+SMDS_PositionPtr SMDS_SpacePosition::originSpacePosition()
{
- static SMDS_SpacePosition * staticpos=new SMDS_SpacePosition();
- return staticpos;
+ static SMDS_PositionPtr staticpos (new SMDS_SpacePosition());
+ return staticpos;
}
const virtual double * Coords() const;
virtual inline SMDS_TypeOfPosition GetTypeOfPosition() const;
inline void SetCoords(const double x, const double y, const double z);
- ~SMDS_SpacePosition();
- static SMDS_SpacePosition * originSpacePosition();
+ static SMDS_PositionPtr originSpacePosition();
private:
double myCoords[3];
};
OS << myNodes[i] << ") " << endl;
}
-SMDS_Iterator<const SMDS_MeshElement *> * SMDS_Tria3OfNodes::
- elementsIterator(SMDSAbs_ElementType type) const
+class SMDS_Tria3OfNodes_MyIterator:public SMDS_ElemIterator
{
- class MyIterator:public SMDS_Iterator<const SMDS_MeshElement*>
- {
- const SMDS_MeshNode * const* mySet;
- int index;
- public:
- MyIterator(const SMDS_MeshNode * const* s):mySet(s),index(0)
- {}
+ const SMDS_MeshNode * const* mySet;
+ int index;
+ public:
+ SMDS_Tria3OfNodes_MyIterator(const SMDS_MeshNode * const* s):
+ mySet(s),index(0) {}
- bool more()
- {
- return index<3;
- }
+ bool more()
+ {
+ return index<3;
+ }
- const SMDS_MeshElement* next()
- {
- index++;
- return mySet[index-1];
- }
- };
+ const SMDS_MeshElement* next()
+ {
+ index++;
+ return mySet[index-1];
+ }
+};
- switch(type)
- {
- case SMDSAbs_Face:return SMDS_MeshElement::elementsIterator(SMDSAbs_Face);
- case SMDSAbs_Node:return new MyIterator(myNodes);
- case SMDSAbs_Edge:
- MESSAGE("Error : edge iterator for SMDS_FaceOfNodes not implemented");
- break;
- default:return new SMDS_IteratorOfElements(this,type,new MyIterator(myNodes));
- }
+SMDS_ElemIteratorPtr SMDS_Tria3OfNodes::
+ elementsIterator(SMDSAbs_ElementType type) const
+{
+ switch(type)
+ {
+ case SMDSAbs_Face:
+ return SMDS_MeshElement::elementsIterator(SMDSAbs_Face);
+ case SMDSAbs_Node:
+ return SMDS_ElemIteratorPtr(new SMDS_Tria3OfNodes_MyIterator(myNodes));
+ case SMDSAbs_Edge:
+ MESSAGE("Error : edge iterator for SMDS_FaceOfNodes not implemented");
+ break;
+ default:
+ return SMDS_ElemIteratorPtr
+ (new SMDS_IteratorOfElements
+ (this,type,SMDS_ElemIteratorPtr(new SMDS_Tria3OfNodes_MyIterator(myNodes))));
+ }
}
-SMDS_Tria3OfNodes::SMDS_Tria3OfNodes(SMDS_MeshNode* node1, SMDS_MeshNode* node2,
- SMDS_MeshNode* node3)
+SMDS_Tria3OfNodes::SMDS_Tria3OfNodes(const SMDS_MeshNode* node1,
+ const SMDS_MeshNode* node2,
+ const SMDS_MeshNode* node3)
{
myNodes[0]=node1;
myNodes[1]=node2;
{
public:
void Print(ostream & OS) const;
- SMDS_Tria3OfNodes(SMDS_MeshNode* node1, SMDS_MeshNode* node2,
- SMDS_MeshNode* node3);
+ SMDS_Tria3OfNodes(const SMDS_MeshNode* node1,
+ const SMDS_MeshNode* node2,
+ const SMDS_MeshNode* node3);
int NbEdges() const;
int NbFaces() const;
int NbNodes() const;
protected:
- SMDS_Iterator<const SMDS_MeshElement *> *
+ SMDS_ElemIteratorPtr
elementsIterator(SMDSAbs_ElementType type) const;
private:
SMDS_TypeOfPosition GetTypeOfPosition() const;
SMDS_VertexPosition(int aVertexId=0);
const double *Coords() const;
- ~SMDS_VertexPosition();
};
#endif
//
//
//
-// File : SMDS_MeshVolume.cxx
+// File : SMDS_VolumeOfFaces.cxx
// Author : Jean-Michel BOULCOURT
// Module : SMESH
return myFaces.size();
}
-SMDS_Iterator<const SMDS_MeshElement *> * SMDS_VolumeOfFaces::
- elementsIterator(SMDSAbs_ElementType type) const
+class SMDS_VolumeOfFaces_MyIterator:public SMDS_ElemIterator
{
- class MyIterator:public SMDS_Iterator<const SMDS_MeshElement*>
- {
- const vector<SMDS_MeshFace*>& mySet;
- int index;
- public:
- MyIterator(const vector<SMDS_MeshFace*>& s):mySet(s),index(0)
- {}
+ const vector<const SMDS_MeshFace*>& mySet;
+ int index;
+ public:
+ SMDS_VolumeOfFaces_MyIterator(const vector<const SMDS_MeshFace*>& s):
+ mySet(s),index(0) {}
- bool more()
- {
- return index<mySet.size();
- }
+ bool more()
+ {
+ return index<mySet.size();
+ }
- const SMDS_MeshElement* next()
- {
- index++;
- return mySet[index-1];
- }
- };
+ const SMDS_MeshElement* next()
+ {
+ index++;
+ return mySet[index-1];
+ }
+};
- switch(type)
- {
- case SMDSAbs_Volume:return SMDS_MeshElement::elementsIterator(SMDSAbs_Volume);
- case SMDSAbs_Face:return new MyIterator(myFaces);
- default:return new SMDS_IteratorOfElements(this,type,new MyIterator(myFaces));
- }
+SMDS_ElemIteratorPtr SMDS_VolumeOfFaces::
+ elementsIterator(SMDSAbs_ElementType type) const
+{
+ switch(type)
+ {
+ case SMDSAbs_Volume:
+ return SMDS_MeshElement::elementsIterator(SMDSAbs_Volume);
+ case SMDSAbs_Face:
+ return SMDS_ElemIteratorPtr(new SMDS_VolumeOfFaces_MyIterator(myFaces));
+ default:
+ return SMDS_ElemIteratorPtr
+ (new SMDS_IteratorOfElements
+ (this,type,SMDS_ElemIteratorPtr(new SMDS_VolumeOfFaces_MyIterator(myFaces))));
+ }
}
-SMDS_VolumeOfFaces::SMDS_VolumeOfFaces(SMDS_MeshFace * face1, SMDS_MeshFace * face2,
- SMDS_MeshFace * face3, SMDS_MeshFace * face4)
+SMDS_VolumeOfFaces::SMDS_VolumeOfFaces(const SMDS_MeshFace * face1,
+ const SMDS_MeshFace * face2,
+ const SMDS_MeshFace * face3,
+ const SMDS_MeshFace * face4)
{
myFaces.resize(4);
myFaces[0]=face1;
myFaces[3]=face4;
}
-SMDS_VolumeOfFaces::SMDS_VolumeOfFaces(SMDS_MeshFace * face1, SMDS_MeshFace * face2,
- SMDS_MeshFace * face3, SMDS_MeshFace * face4,
- SMDS_MeshFace * face5)
+SMDS_VolumeOfFaces::SMDS_VolumeOfFaces(const SMDS_MeshFace * face1,
+ const SMDS_MeshFace * face2,
+ const SMDS_MeshFace * face3,
+ const SMDS_MeshFace * face4,
+ const SMDS_MeshFace * face5)
{
myFaces.resize(5);
myFaces[0]=face1;
myFaces[4]=face5;
}
-SMDS_VolumeOfFaces::SMDS_VolumeOfFaces(SMDS_MeshFace * face1, SMDS_MeshFace * face2,
- SMDS_MeshFace * face3, SMDS_MeshFace * face4,
- SMDS_MeshFace * face5,SMDS_MeshFace * face6)
+SMDS_VolumeOfFaces::SMDS_VolumeOfFaces(const SMDS_MeshFace * face1,
+ const SMDS_MeshFace * face2,
+ const SMDS_MeshFace * face3,
+ const SMDS_MeshFace * face4,
+ const SMDS_MeshFace * face5,
+ const SMDS_MeshFace * face6)
{
myFaces.resize(6);
myFaces[0]=face1;
//
//
//
-// File : SMDS_MeshVolume.hxx
+// File : SMDS_VolumeOfFaces.hxx
// Module : SMESH
#ifndef _SMDS_VolumeOfFaces_HeaderFile
{
public:
- SMDS_VolumeOfFaces(SMDS_MeshFace * face1, SMDS_MeshFace * face2,
- SMDS_MeshFace * face3, SMDS_MeshFace * face4);
- SMDS_VolumeOfFaces(SMDS_MeshFace * face1, SMDS_MeshFace * face2,
- SMDS_MeshFace * face3, SMDS_MeshFace * face4,
- SMDS_MeshFace * face5);
- SMDS_VolumeOfFaces(SMDS_MeshFace * face1, SMDS_MeshFace * face2,
- SMDS_MeshFace * face3, SMDS_MeshFace * face4,
- SMDS_MeshFace * face5,SMDS_MeshFace * face6);
+ SMDS_VolumeOfFaces(const SMDS_MeshFace * face1,
+ const SMDS_MeshFace * face2,
+ const SMDS_MeshFace * face3,
+ const SMDS_MeshFace * face4);
+ SMDS_VolumeOfFaces(const SMDS_MeshFace * face1,
+ const SMDS_MeshFace * face2,
+ const SMDS_MeshFace * face3,
+ const SMDS_MeshFace * face4,
+ const SMDS_MeshFace * face5);
+ SMDS_VolumeOfFaces(const SMDS_MeshFace * face1,
+ const SMDS_MeshFace * face2,
+ const SMDS_MeshFace * face3,
+ const SMDS_MeshFace * face4,
+ const SMDS_MeshFace * face5,
+ const SMDS_MeshFace * face6);
void Print(ostream & OS) const;
int NbFaces() const;
protected:
- SMDS_Iterator<const SMDS_MeshElement *> *
+ SMDS_ElemIteratorPtr
elementsIterator(SMDSAbs_ElementType type) const;
- vector<SMDS_MeshFace *> myFaces;
+ vector<const SMDS_MeshFace *> myFaces;
};
#endif
/// 5,1 and 7,3 are an edges.
///////////////////////////////////////////////////////////////////////////////
SMDS_VolumeOfNodes::SMDS_VolumeOfNodes(
- SMDS_MeshNode * node1,
- SMDS_MeshNode * node2,
- SMDS_MeshNode * node3,
- SMDS_MeshNode * node4,
- SMDS_MeshNode * node5,
- SMDS_MeshNode * node6,
- SMDS_MeshNode * node7,
- SMDS_MeshNode * node8)
+ const SMDS_MeshNode * node1,
+ const SMDS_MeshNode * node2,
+ const SMDS_MeshNode * node3,
+ const SMDS_MeshNode * node4,
+ const SMDS_MeshNode * node5,
+ const SMDS_MeshNode * node6,
+ const SMDS_MeshNode * node7,
+ const SMDS_MeshNode * node8)
{
myNodes.resize(8);
myNodes[0]=node1;
}
SMDS_VolumeOfNodes::SMDS_VolumeOfNodes(
- SMDS_MeshNode * node1,
- SMDS_MeshNode * node2,
- SMDS_MeshNode * node3,
- SMDS_MeshNode * node4)
+ const SMDS_MeshNode * node1,
+ const SMDS_MeshNode * node2,
+ const SMDS_MeshNode * node3,
+ const SMDS_MeshNode * node4)
{
myNodes.resize(4);
myNodes[0]=node1;
}
SMDS_VolumeOfNodes::SMDS_VolumeOfNodes(
- SMDS_MeshNode * node1,
- SMDS_MeshNode * node2,
- SMDS_MeshNode * node3,
- SMDS_MeshNode * node4,
- SMDS_MeshNode * node5)
+ const SMDS_MeshNode * node1,
+ const SMDS_MeshNode * node2,
+ const SMDS_MeshNode * node3,
+ const SMDS_MeshNode * node4,
+ const SMDS_MeshNode * node5)
{
myNodes.resize(5);
myNodes[0]=node1;
}
SMDS_VolumeOfNodes::SMDS_VolumeOfNodes(
- SMDS_MeshNode * node1,
- SMDS_MeshNode * node2,
- SMDS_MeshNode * node3,
- SMDS_MeshNode * node4,
- SMDS_MeshNode * node5,
- SMDS_MeshNode * node6)
+ const SMDS_MeshNode * node1,
+ const SMDS_MeshNode * node2,
+ const SMDS_MeshNode * node3,
+ const SMDS_MeshNode * node4,
+ const SMDS_MeshNode * node5,
+ const SMDS_MeshNode * node6)
{
myNodes.resize(6);
myNodes[0]=node1;
}
}
-SMDS_Iterator<const SMDS_MeshElement *> * SMDS_VolumeOfNodes::
- elementsIterator(SMDSAbs_ElementType type) const
+class SMDS_VolumeOfNodes_MyIterator:public SMDS_ElemIterator
{
- class MyIterator:public SMDS_Iterator<const SMDS_MeshElement*>
- {
- const vector<const SMDS_MeshNode*>& mySet;
- int index;
- public:
- MyIterator(const vector<const SMDS_MeshNode*>& s):mySet(s),index(0)
- {}
+ const vector<const SMDS_MeshNode*>& mySet;
+ int index;
+ public:
+ SMDS_VolumeOfNodes_MyIterator(const vector<const SMDS_MeshNode*>& s):
+ mySet(s),index(0) {}
- bool more()
- {
- return index<mySet.size();
- }
+ bool more()
+ {
+ return index<mySet.size();
+ }
- const SMDS_MeshElement* next()
- {
- index++;
- return mySet[index-1];
- }
- };
- switch(type)
- {
- case SMDSAbs_Volume:return SMDS_MeshElement::elementsIterator(SMDSAbs_Volume);
- case SMDSAbs_Node:return new MyIterator(myNodes);
- default: MESSAGE("ERROR : Iterator not implemented");
- }
+ const SMDS_MeshElement* next()
+ {
+ index++;
+ return mySet[index-1];
+ }
+};
+
+SMDS_ElemIteratorPtr SMDS_VolumeOfNodes::
+ elementsIterator(SMDSAbs_ElementType type) const
+{
+ switch(type)
+ {
+ case SMDSAbs_Volume:
+ return SMDS_MeshElement::elementsIterator(SMDSAbs_Volume);
+ case SMDSAbs_Node:
+ return SMDS_ElemIteratorPtr(new SMDS_VolumeOfNodes_MyIterator(myNodes));
+ default:
+ MESSAGE("ERROR : Iterator not implemented");
+ return SMDS_ElemIteratorPtr((SMDS_ElemIterator*)NULL);
+ }
}
SMDSAbs_ElementType SMDS_VolumeOfNodes::GetType() const
public:
SMDS_VolumeOfNodes(
- SMDS_MeshNode * node1,
- SMDS_MeshNode * node2,
- SMDS_MeshNode * node3,
- SMDS_MeshNode * node4);
+ const SMDS_MeshNode * node1,
+ const SMDS_MeshNode * node2,
+ const SMDS_MeshNode * node3,
+ const SMDS_MeshNode * node4);
SMDS_VolumeOfNodes(
- SMDS_MeshNode * node1,
- SMDS_MeshNode * node2,
- SMDS_MeshNode * node3,
- SMDS_MeshNode * node4,
- SMDS_MeshNode * node5);
+ const SMDS_MeshNode * node1,
+ const SMDS_MeshNode * node2,
+ const SMDS_MeshNode * node3,
+ const SMDS_MeshNode * node4,
+ const SMDS_MeshNode * node5);
SMDS_VolumeOfNodes(
- SMDS_MeshNode * node1,
- SMDS_MeshNode * node2,
- SMDS_MeshNode * node3,
- SMDS_MeshNode * node4,
- SMDS_MeshNode * node5,
- SMDS_MeshNode * node6);
+ const SMDS_MeshNode * node1,
+ const SMDS_MeshNode * node2,
+ const SMDS_MeshNode * node3,
+ const SMDS_MeshNode * node4,
+ const SMDS_MeshNode * node5,
+ const SMDS_MeshNode * node6);
SMDS_VolumeOfNodes(
- SMDS_MeshNode * node1,
- SMDS_MeshNode * node2,
- SMDS_MeshNode * node3,
- SMDS_MeshNode * node4,
- SMDS_MeshNode * node5,
- SMDS_MeshNode * node6,
- SMDS_MeshNode * node7,
- SMDS_MeshNode * node8);
+ const SMDS_MeshNode * node1,
+ const SMDS_MeshNode * node2,
+ const SMDS_MeshNode * node3,
+ const SMDS_MeshNode * node4,
+ const SMDS_MeshNode * node5,
+ const SMDS_MeshNode * node6,
+ const SMDS_MeshNode * node7,
+ const SMDS_MeshNode * node8);
void Print(ostream & OS) const;
int NbFaces() const;
int NbEdges() const;
SMDSAbs_ElementType GetType() const;
protected:
- SMDS_Iterator<const SMDS_MeshElement *> *
+ SMDS_ElemIteratorPtr
elementsIterator(SMDSAbs_ElementType type) const;
vector<const SMDS_MeshNode *> myNodes;
};
SMESHDS_Script.cxx \
SMESHDS_Command.cxx \
SMESHDS_SubMesh.cxx \
- SMESHDS_Mesh.cxx
+ SMESHDS_Mesh.cxx \
+ SMESHDS_Group.cxx
LIB_CLIENT_IDL =
LIB_SERVER_IDL =
SMESHDS_Script.hxx \
SMESHDS_Command.hxx \
SMESHDS_CommandType.hxx \
- SMESHDS_SubMesh.hxx
+ SMESHDS_SubMesh.hxx \
+ SMESHDS_Group.hxx
# additionnal information to compil and link file
-CPPFLAGS += $(OCC_INCLUDES) -I${KERNEL_ROOT_DIR}/include/salome
+CPPFLAGS += $(OCC_INCLUDES) -I${KERNEL_ROOT_DIR}/include/salome $(BOOST_CPPFLAGS)
CXXFLAGS += $(OCC_CXXFLAGS) -I${KERNEL_ROOT_DIR}/include/salome
LDFLAGS += $(OCC_KERNEL_LIBS)
#include "SMESHDS_CommandType.hxx"
#include <list>
-using namespace std;
class SMESHDS_Command
{
SMESHDS_AddHexahedron,
SMESHDS_RemoveNode,
SMESHDS_RemoveElement,
-SMESHDS_MoveNode,
-SMESHDS_UpdateAll
+SMESHDS_MoveNode
};
--- /dev/null
+// SMESH SMESHDS : idl implementation based on 'SMESH' unit's classes
+//
+// Copyright (C) 2004 CEA
+//
+// This library 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.
+//
+// This library 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 this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+//
+// See http://www.salome-platform.org or email : webmaster.salome@opencascade.org
+//
+//
+//
+// File : SMESHDS_Group.cxx
+// Author : Michael Sazonov, OCC
+// Module : SMESH
+// $Header$
+
+#include <SMESHDS_Group.hxx>
+#include <SMESHDS_Mesh.hxx>
+
+//=============================================================================
+/*!
+ *
+ */
+//=============================================================================
+
+SMESHDS_Group::SMESHDS_Group (const SMESHDS_Mesh* theMesh,
+ const SMDSAbs_ElementType theType)
+ : SMDS_MeshGroup(theMesh,theType), myStoreName(""),
+ myCurIndex(0), myCurID(0)
+{
+}
+
+//=============================================================================
+/*!
+ *
+ */
+//=============================================================================
+
+bool SMESHDS_Group::Contains (const int theID) const
+{
+ const SMDS_MeshElement* aElem = findInMesh (theID);
+ if (aElem)
+ return SMDS_MeshGroup::Contains(aElem);
+ return false;
+}
+
+//=============================================================================
+/*!
+ *
+ */
+//=============================================================================
+
+bool SMESHDS_Group::Add (const int theID)
+{
+ const SMDS_MeshElement* aElem = findInMesh (theID);
+ if (!aElem || SMDS_MeshGroup::Contains(aElem))
+ return false;
+ SMDS_MeshGroup::Add (aElem);
+ return true;
+}
+
+//=============================================================================
+/*!
+ *
+ */
+//=============================================================================
+
+bool SMESHDS_Group::Remove (const int theID)
+{
+ const SMDS_MeshElement* aElem = findInMesh (theID);
+ if (!aElem || !SMDS_MeshGroup::Contains(aElem))
+ return false;
+ SMDS_MeshGroup::Remove (aElem);
+ return true;
+}
+
+//=============================================================================
+/*!
+ *
+ */
+//=============================================================================
+
+int SMESHDS_Group::GetID (const int theIndex)
+{
+ if (theIndex < 1 || theIndex > Extent())
+ return -1;
+ if (myCurIndex < 1 || myCurIndex > theIndex) {
+ InitIterator();
+ myCurIndex = 0;
+ myCurID = -1;
+ }
+ while (myCurIndex < theIndex && More()) {
+ myCurIndex++;
+ myCurID = Next()->GetID();
+ }
+ return myCurID;
+}
+
+//=============================================================================
+/*!
+ *
+ */
+//=============================================================================
+
+const SMDS_MeshElement* SMESHDS_Group::findInMesh (const int theID) const
+{
+ SMDSAbs_ElementType aType = GetType();
+ const SMDS_MeshElement* aElem = NULL;
+ if (aType == SMDSAbs_Node) {
+ aElem = GetMesh()->FindNode(theID);
+ }
+ else if (aType != SMDSAbs_All) {
+ aElem = GetMesh()->FindElement(theID);
+ if (aElem && aType != aElem->GetType())
+ aElem = NULL;
+ }
+ return aElem;
+}
--- /dev/null
+// SMESH SMESHDS : management of mesh data and SMESH document
+//
+// Copyright (C) 2004 CEA
+//
+// This library 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.
+//
+// This library 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 this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+//
+// See http://www.salome-platform.org or email : webmaster.salome@opencascade.org
+//
+//
+//
+// File : SMESHDS_Group.hxx
+// Author : Michael Sazonov (OCC)
+// Module : SMESH
+// $Header$
+
+#ifndef _SMESHDS_Group_HeaderFile
+#define _SMESHDS_Group_HeaderFile
+
+#include <SMDS_MeshGroup.hxx>
+#include <string>
+
+class SMESHDS_Mesh;
+
+class SMESHDS_Group : public SMDS_MeshGroup
+{
+ public:
+
+ SMESHDS_Group (const SMESHDS_Mesh* theMesh,
+ const SMDSAbs_ElementType theType);
+
+ void SetStoreName (const char* theName)
+ { myStoreName = theName; }
+
+ const char* GetStoreName () const
+ { return myStoreName.c_str(); }
+
+ bool Contains (const int theID) const;
+
+ bool Add (const int theID);
+ bool Remove (const int theID);
+
+ int GetID (const int theIndex);
+ // use it for iterations 1..Extent() as alternative to parent's
+ // InitIterator(), More(), Next()
+
+ private:
+ SMESHDS_Group (const SMESHDS_Group& theOther);
+ // prohibited copy constructor
+ SMESHDS_Group& operator = (const SMESHDS_Group& theOther);
+ // prohibited assign operator
+
+ const SMDS_MeshElement* findInMesh (const int theID) const;
+
+ string myStoreName;
+ int myCurIndex;
+ int myCurID;
+
+};
+
+#endif
return _type;
}
-void SMESHDS_Hypothesis::SetID(int id)
-{
- _hypId=id;
-}
\ No newline at end of file
const char* GetName() const;
int GetID() const;
- void SetID(int id);
int GetType() const;
virtual ostream & SaveTo(ostream & save)=0;
//function : AddNode
//purpose :
//=======================================================================
-SMDS_MeshNode* SMESHDS_Mesh::AddNode(double x, double y, double z)
-{
- SMDS_MeshNode* node = SMDS_Mesh::AddNode(x, y, z);
- if(node!=NULL) myScript->AddNode(node->GetID(), x, y, z);
- return node;
+SMDS_MeshNode* SMESHDS_Mesh::AddNode(double x, double y, double z){
+ SMDS_MeshNode* node = SMDS_Mesh::AddNode(x, y, z);
+ if(node!=NULL) myScript->AddNode(node->GetID(), x, y, z);
+ return node;
+}
+
+SMDS_MeshNode* SMESHDS_Mesh::AddNodeWithID(double x, double y, double z, int ID){
+ SMDS_MeshNode* node = SMDS_Mesh::AddNodeWithID(x,y,z,ID);
+ if(node!=NULL) myScript->AddNode(node->GetID(), x, y, z);
+ return node;
}
//=======================================================================
//=======================================================================
void SMESHDS_Mesh::MoveNode(const SMDS_MeshNode *n, double x, double y, double z)
{
- SMDS_MeshNode * node=const_cast<SMDS_MeshNode*>(n);
- node->setXYZ(x,y,z);
- myScript->MoveNode(n->GetID(), x, y, z);
+ SMDS_MeshNode * node=const_cast<SMDS_MeshNode*>(n);
+ node->setXYZ(x,y,z);
+ myScript->MoveNode(n->GetID(), x, y, z);
}
//=======================================================================
//function : AddEdge
//purpose :
//=======================================================================
+SMDS_MeshEdge* SMESHDS_Mesh::AddEdgeWithID(int n1, int n2, int ID)
+{
+ SMDS_MeshEdge* anElem = SMDS_Mesh::AddEdgeWithID(n1,n2,ID);
+ if(anElem) myScript->AddEdge(ID,n1,n2);
+ return anElem;
+}
+
+SMDS_MeshEdge* SMESHDS_Mesh::AddEdgeWithID(const SMDS_MeshNode * n1,
+ const SMDS_MeshNode * n2,
+ int ID)
+{
+ return AddEdgeWithID(n1->GetID(),
+ n2->GetID(),
+ ID);
+}
+
SMDS_MeshEdge* SMESHDS_Mesh::AddEdge(const SMDS_MeshNode * n1,
- const SMDS_MeshNode * n2)
+ const SMDS_MeshNode * n2)
{
- SMDS_MeshEdge* e = SMDS_Mesh::AddEdge(n1,n2);
- if(e!=NULL) myScript->AddEdge(e->GetID(), n1->GetID(), n2->GetID());
- return e;
+ SMDS_MeshEdge* anElem = SMDS_Mesh::AddEdge(n1,n2);
+ if(anElem) myScript->AddEdge(anElem->GetID(),
+ n1->GetID(),
+ n2->GetID());
+ return anElem;
}
//=======================================================================
//function :AddFace
//purpose :
//=======================================================================
+SMDS_MeshFace* SMESHDS_Mesh::AddFaceWithID(int n1, int n2, int n3, int ID)
+{
+ SMDS_MeshFace *anElem = SMDS_Mesh::AddFaceWithID(n1, n2, n3, ID);
+ if(anElem) myScript->AddFace(ID,n1,n2,n3);
+ return anElem;
+}
+
+SMDS_MeshFace* SMESHDS_Mesh::AddFaceWithID(const SMDS_MeshNode * n1,
+ const SMDS_MeshNode * n2,
+ const SMDS_MeshNode * n3,
+ int ID)
+{
+ return AddFaceWithID(n1->GetID(),
+ n2->GetID(),
+ n3->GetID(),
+ ID);
+}
+
SMDS_MeshFace* SMESHDS_Mesh::AddFace( const SMDS_MeshNode * n1,
- const SMDS_MeshNode * n2,
- const SMDS_MeshNode * n3)
+ const SMDS_MeshNode * n2,
+ const SMDS_MeshNode * n3)
{
- SMDS_MeshFace *f = SMDS_Mesh::AddFace(n1, n2, n3);
- if(f!=NULL) myScript->AddFace(f->GetID(), n1->GetID(), n2->GetID(),
- n3->GetID());
- return f;
+ SMDS_MeshFace *anElem = SMDS_Mesh::AddFace(n1, n2, n3);
+ if(anElem) myScript->AddFace(anElem->GetID(),
+ n1->GetID(),
+ n2->GetID(),
+ n3->GetID());
+ return anElem;
}
//=======================================================================
//function :AddFace
//purpose :
//=======================================================================
+SMDS_MeshFace* SMESHDS_Mesh::AddFaceWithID(int n1, int n2, int n3, int n4, int ID)
+{
+ SMDS_MeshFace *anElem = SMDS_Mesh::AddFaceWithID(n1, n2, n3, n4, ID);
+ if(anElem) myScript->AddFace(ID, n1, n2, n3, n4);
+ return anElem;
+}
+
+SMDS_MeshFace* SMESHDS_Mesh::AddFaceWithID(const SMDS_MeshNode * n1,
+ const SMDS_MeshNode * n2,
+ const SMDS_MeshNode * n3,
+ const SMDS_MeshNode * n4,
+ int ID)
+{
+ return AddFaceWithID(n1->GetID(),
+ n2->GetID(),
+ n3->GetID(),
+ n4->GetID(),
+ ID);
+}
+
SMDS_MeshFace* SMESHDS_Mesh::AddFace(const SMDS_MeshNode * n1,
- const SMDS_MeshNode * n2,
- const SMDS_MeshNode * n3,
- const SMDS_MeshNode * n4)
+ const SMDS_MeshNode * n2,
+ const SMDS_MeshNode * n3,
+ const SMDS_MeshNode * n4)
{
- SMDS_MeshFace *f = SMDS_Mesh::AddFace(n1, n2, n3, n4);
- if(f!=NULL)
- myScript->AddFace(f->GetID(), n1->GetID(), n2->GetID(), n3->GetID(),
- n4->GetID());
- return f;
+ SMDS_MeshFace *anElem = SMDS_Mesh::AddFace(n1, n2, n3, n4);
+ if(anElem) myScript->AddFace(anElem->GetID(),
+ n1->GetID(),
+ n2->GetID(),
+ n3->GetID(),
+ n4->GetID());
+ return anElem;
}
//=======================================================================
//function :AddVolume
//purpose :
//=======================================================================
-SMDS_MeshVolume* SMESHDS_Mesh::AddVolume(
- const SMDS_MeshNode * n1,
- const SMDS_MeshNode * n2,
- const SMDS_MeshNode * n3,
- const SMDS_MeshNode * n4)
+SMDS_MeshVolume* SMESHDS_Mesh::AddVolumeWithID(int n1, int n2, int n3, int n4, int ID)
+{
+ SMDS_MeshVolume *anElem = SMDS_Mesh::AddVolumeWithID(n1, n2, n3, n4, ID);
+ if(anElem) myScript->AddVolume(ID, n1, n2, n3, n4);
+ return anElem;
+}
+
+SMDS_MeshVolume* SMESHDS_Mesh::AddVolumeWithID(const SMDS_MeshNode * n1,
+ const SMDS_MeshNode * n2,
+ const SMDS_MeshNode * n3,
+ const SMDS_MeshNode * n4,
+ int ID)
+{
+ return AddVolumeWithID(n1->GetID(),
+ n2->GetID(),
+ n3->GetID(),
+ n4->GetID(),
+ ID);
+}
+
+SMDS_MeshVolume* SMESHDS_Mesh::AddVolume(const SMDS_MeshNode * n1,
+ const SMDS_MeshNode * n2,
+ const SMDS_MeshNode * n3,
+ const SMDS_MeshNode * n4)
{
- SMDS_MeshVolume *f = SMDS_Mesh::AddVolume(n1, n2, n3, n4);
- if(f!=NULL)
- myScript->AddVolume(f->GetID(), n1->GetID(), n2->GetID(), n3->GetID(),
- n4->GetID());
- return f;
+ SMDS_MeshVolume *anElem = SMDS_Mesh::AddVolume(n1, n2, n3, n4);
+ if(anElem) myScript->AddVolume(anElem->GetID(),
+ n1->GetID(),
+ n2->GetID(),
+ n3->GetID(),
+ n4->GetID());
+ return anElem;
}
//=======================================================================
//function :AddVolume
//purpose :
//=======================================================================
-SMDS_MeshVolume* SMESHDS_Mesh::AddVolume(
- const SMDS_MeshNode * n1,
- const SMDS_MeshNode * n2,
- const SMDS_MeshNode * n3,
- const SMDS_MeshNode * n4,
- const SMDS_MeshNode * n5)
+SMDS_MeshVolume* SMESHDS_Mesh::AddVolumeWithID(int n1, int n2, int n3, int n4, int n5, int ID)
+{
+ SMDS_MeshVolume *anElem = SMDS_Mesh::AddVolumeWithID(n1, n2, n3, n4, n5, ID);
+ if(anElem) myScript->AddVolume(ID, n1, n2, n3, n4, n5);
+ return anElem;
+}
+
+SMDS_MeshVolume* SMESHDS_Mesh::AddVolumeWithID(const SMDS_MeshNode * n1,
+ const SMDS_MeshNode * n2,
+ const SMDS_MeshNode * n3,
+ const SMDS_MeshNode * n4,
+ const SMDS_MeshNode * n5,
+ int ID)
+{
+ return AddVolumeWithID(n1->GetID(),
+ n2->GetID(),
+ n3->GetID(),
+ n4->GetID(),
+ n5->GetID(),
+ ID);
+}
+
+SMDS_MeshVolume* SMESHDS_Mesh::AddVolume(const SMDS_MeshNode * n1,
+ const SMDS_MeshNode * n2,
+ const SMDS_MeshNode * n3,
+ const SMDS_MeshNode * n4,
+ const SMDS_MeshNode * n5)
{
- SMDS_MeshVolume *v = SMDS_Mesh::AddVolume(n1, n2, n3, n4, n5);
- if(v!=NULL)
- myScript->AddVolume(v->GetID(), n1->GetID(), n2->GetID(), n3->GetID(),
- n4->GetID(), n5->GetID());
- return v;
+ SMDS_MeshVolume *anElem = SMDS_Mesh::AddVolume(n1, n2, n3, n4, n5);
+ if(anElem) myScript->AddVolume(anElem->GetID(),
+ n1->GetID(),
+ n2->GetID(),
+ n3->GetID(),
+ n4->GetID(),
+ n5->GetID());
+ return anElem;
}
//=======================================================================
//function :AddVolume
//purpose :
//=======================================================================
-SMDS_MeshVolume* SMESHDS_Mesh::AddVolume(
- const SMDS_MeshNode * n1,
- const SMDS_MeshNode * n2,
- const SMDS_MeshNode * n3,
- const SMDS_MeshNode * n4,
- const SMDS_MeshNode * n5,
- const SMDS_MeshNode * n6)
+SMDS_MeshVolume* SMESHDS_Mesh::AddVolumeWithID(int n1, int n2, int n3, int n4, int n5, int n6, int ID)
{
- SMDS_MeshVolume *v= SMDS_Mesh::AddVolume(n1, n2, n3, n4, n5, n6);
- if(v!=NULL)
- myScript->AddVolume(v->GetID(), n1->GetID(), n2->GetID(), n3->GetID(),
- n4->GetID(), n5->GetID(), n6->GetID());
- return v;
+ SMDS_MeshVolume *anElem= SMDS_Mesh::AddVolumeWithID(n1, n2, n3, n4, n5, n6, ID);
+ if(anElem) myScript->AddVolume(ID, n1, n2, n3, n4, n5, n6);
+ return anElem;
+}
+
+SMDS_MeshVolume* SMESHDS_Mesh::AddVolumeWithID(const SMDS_MeshNode * n1,
+ const SMDS_MeshNode * n2,
+ const SMDS_MeshNode * n3,
+ const SMDS_MeshNode * n4,
+ const SMDS_MeshNode * n5,
+ const SMDS_MeshNode * n6,
+ int ID)
+{
+ return AddVolumeWithID(n1->GetID(),
+ n2->GetID(),
+ n3->GetID(),
+ n4->GetID(),
+ n5->GetID(),
+ n6->GetID(),
+ ID);
+}
+
+SMDS_MeshVolume* SMESHDS_Mesh::AddVolume(const SMDS_MeshNode * n1,
+ const SMDS_MeshNode * n2,
+ const SMDS_MeshNode * n3,
+ const SMDS_MeshNode * n4,
+ const SMDS_MeshNode * n5,
+ const SMDS_MeshNode * n6)
+{
+ SMDS_MeshVolume *anElem = SMDS_Mesh::AddVolume(n1, n2, n3, n4, n5, n6);
+ if(anElem) myScript->AddVolume(anElem->GetID(),
+ n1->GetID(),
+ n2->GetID(),
+ n3->GetID(),
+ n4->GetID(),
+ n5->GetID(),
+ n6->GetID());
+ return anElem;
}
//=======================================================================
//function :AddVolume
//purpose :
//=======================================================================
-SMDS_MeshVolume* SMESHDS_Mesh::AddVolume(
- const SMDS_MeshNode * n1,
- const SMDS_MeshNode * n2,
- const SMDS_MeshNode * n3,
- const SMDS_MeshNode * n4,
- const SMDS_MeshNode * n5,
- const SMDS_MeshNode * n6,
- const SMDS_MeshNode * n7,
- const SMDS_MeshNode * n8)
-{
- SMDS_MeshVolume *v=
- SMDS_Mesh::AddVolume(n1, n2, n3, n4, n5, n6, n7, n8);
- if(v!=NULL)
- myScript->AddVolume(v->GetID(), n1->GetID(), n2->GetID(), n3->GetID(),
- n4->GetID(), n5->GetID(), n6->GetID(), n7->GetID(), n8->GetID());
- return v;
-}
-
+SMDS_MeshVolume* SMESHDS_Mesh::AddVolumeWithID(int n1, int n2, int n3, int n4, int n5, int n6, int n7, int n8, int ID)
+{
+ SMDS_MeshVolume *anElem= SMDS_Mesh::AddVolumeWithID(n1, n2, n3, n4, n5, n6, n7, n8, ID);
+ if(anElem) myScript->AddVolume(ID, n1, n2, n3, n4, n5, n6, n7, n8);
+ return anElem;
+}
+
+SMDS_MeshVolume* SMESHDS_Mesh::AddVolumeWithID(const SMDS_MeshNode * n1,
+ const SMDS_MeshNode * n2,
+ const SMDS_MeshNode * n3,
+ const SMDS_MeshNode * n4,
+ const SMDS_MeshNode * n5,
+ const SMDS_MeshNode * n6,
+ const SMDS_MeshNode * n7,
+ const SMDS_MeshNode * n8,
+ int ID)
+{
+ return AddVolumeWithID(n1->GetID(),
+ n2->GetID(),
+ n3->GetID(),
+ n4->GetID(),
+ n5->GetID(),
+ n6->GetID(),
+ n7->GetID(),
+ n8->GetID(),
+ ID);
+}
+
+SMDS_MeshVolume* SMESHDS_Mesh::AddVolume(const SMDS_MeshNode * n1,
+ const SMDS_MeshNode * n2,
+ const SMDS_MeshNode * n3,
+ const SMDS_MeshNode * n4,
+ const SMDS_MeshNode * n5,
+ const SMDS_MeshNode * n6,
+ const SMDS_MeshNode * n7,
+ const SMDS_MeshNode * n8)
+{
+ SMDS_MeshVolume *anElem = SMDS_Mesh::AddVolume(n1, n2, n3, n4, n5, n6, n7, n8);
+ if(anElem) myScript->AddVolume(anElem->GetID(),
+ n1->GetID(),
+ n2->GetID(),
+ n3->GetID(),
+ n4->GetID(),
+ n5->GetID(),
+ n6->GetID(),
+ n7->GetID(),
+ n8->GetID());
+ return anElem;
+}
+//=======================================================================
+//function : removeFromSubMeshes
+//purpose :
+//=======================================================================
+
+static void removeFromSubMeshes (map<int,SMESHDS_SubMesh*> & theSubMeshes,
+ list<const SMDS_MeshElement *> & theElems,
+ const bool isNode)
+{
+ if ( theElems.empty() )
+ return;
+
+ map<int,SMESHDS_SubMesh*>::iterator SubIt = theSubMeshes.begin();
+ for ( ; SubIt != theSubMeshes.end(); SubIt++ )
+ {
+ list<const SMDS_MeshElement *>::iterator elIt = theElems.begin();
+ while ( elIt != theElems.end() )
+ {
+ bool removed = false;
+ if ( isNode )
+ removed = (*SubIt).second->RemoveNode( static_cast<const SMDS_MeshNode*> (*elIt) );
+ else
+ removed = (*SubIt).second->RemoveElement( *elIt );
+
+ if (removed)
+ {
+ elIt = theElems.erase( elIt );
+ if ( theElems.empty() )
+ return; // all elements are found and removed
+ }
+ else
+ {
+ elIt++ ;
+ }
+ }
+ }
+}
+
//=======================================================================
//function : RemoveNode
//purpose :
//=======================================================================
void SMESHDS_Mesh::RemoveNode(const SMDS_MeshNode * n)
{
- SMDS_Mesh::RemoveNode(n);
- myScript->RemoveNode(n->GetID());
+ myScript->RemoveNode(n->GetID());
+
+ list<const SMDS_MeshElement *> removedElems;
+ list<const SMDS_MeshElement *> removedNodes;
+
+ SMDS_Mesh::RemoveElement( n, removedElems, removedNodes, true );
+
+ removeFromSubMeshes( myShapeIndexToSubMesh, removedElems, false );
+ removeFromSubMeshes( myShapeIndexToSubMesh, removedNodes, true );
}
//=======================================================================
//========================================================================
void SMESHDS_Mesh::RemoveElement(const SMDS_MeshElement * elt)
{
- SMDS_Mesh::RemoveElement(elt);
- myScript->RemoveElement(elt->GetID());
+ if (elt->GetType() == SMDSAbs_Node)
+ {
+ RemoveNode( static_cast<const SMDS_MeshNode*>( elt ));
+ return;
+ }
+
+ myScript->RemoveElement(elt->GetID());
+
+ list<const SMDS_MeshElement *> removedElems;
+ list<const SMDS_MeshElement *> removedNodes;
+
+ SMDS_Mesh::RemoveElement(elt, removedElems, removedNodes, false);
+
+ removeFromSubMeshes( myShapeIndexToSubMesh, removedElems, false );
}
//=======================================================================
int Index = myIndexToShape.FindIndex(S);
//Set Position on Node
- aNode->SetPosition(new SMDS_FacePosition(Index, 0., 0.));
+ aNode->SetPosition(SMDS_PositionPtr(new SMDS_FacePosition(Index, 0., 0.)));
//Update or build submesh
map<int,SMESHDS_SubMesh*>::iterator it=myShapeIndexToSubMesh.find(Index);
int Index = myIndexToShape.FindIndex(S);
//Set Position on Node
- aNode->SetPosition(new SMDS_EdgePosition(Index, 0.));
+ aNode->SetPosition(SMDS_PositionPtr(new SMDS_EdgePosition(Index, 0.)));
//Update or build submesh
map<int,SMESHDS_SubMesh*>::iterator it=myShapeIndexToSubMesh.find(Index);
int Index = myIndexToShape.FindIndex(S);
//Set Position on Node
- aNode->SetPosition(new SMDS_VertexPosition(Index));
+ aNode->SetPosition(SMDS_PositionPtr(new SMDS_VertexPosition(Index)));
//Update or build submesh
map<int,SMESHDS_SubMesh*>::iterator it=myShapeIndexToSubMesh.find(Index);
///////////////////////////////////////////////////////////////////////////////
SMESHDS_SubMesh * SMESHDS_Mesh::MeshElements(const TopoDS_Shape & S)
{
- if (myShape.IsNull()) MESSAGE("myShape is NULL");
+ if (myShape.IsNull()) MESSAGE("myShape is NULL");
- int Index = myIndexToShape.FindIndex(S);
- if (myShapeIndexToSubMesh.find(Index)!=myShapeIndexToSubMesh.end())
- return myShapeIndexToSubMesh[Index];
- else
- return NULL;
+ int Index = myIndexToShape.FindIndex(S);
+ if (myShapeIndexToSubMesh.find(Index)!=myShapeIndexToSubMesh.end())
+ return myShapeIndexToSubMesh[Index];
+ else
+ return NULL;
+}
+
+///////////////////////////////////////////////////////////////////////////////
+/// Return the sub mesh by Id of shape it is linked to
+///////////////////////////////////////////////////////////////////////////////
+SMESHDS_SubMesh * SMESHDS_Mesh::MeshElements(const int Index)
+{
+ if (myShape.IsNull()) MESSAGE("myShape is NULL");
+
+ if (myShapeIndexToSubMesh.find(Index)!=myShapeIndexToSubMesh.end())
+ return myShapeIndexToSubMesh[Index];
+ else
+ return NULL;
+}
+
+//=======================================================================
+//function : SubMeshIndices
+//purpose :
+//=======================================================================
+list<int> SMESHDS_Mesh::SubMeshIndices()
+{
+ list<int> anIndices;
+ std::map<int,SMESHDS_SubMesh*>::iterator anIter = myShapeIndexToSubMesh.begin();
+ for (; anIter != myShapeIndexToSubMesh.end(); anIter++) {
+ anIndices.push_back((*anIter).first);
+ }
+ return anIndices;
}
//=======================================================================
void SMESHDS_Mesh::SetNodeOnFace(SMDS_MeshNode* aNode, int Index)
{
//Set Position on Node
- aNode->SetPosition(new SMDS_FacePosition(Index, 0., 0.));
+ aNode->SetPosition(SMDS_PositionPtr(new SMDS_FacePosition(Index, 0., 0.)));
//Update or build submesh
if (myShapeIndexToSubMesh.find(Index)==myShapeIndexToSubMesh.end())
void SMESHDS_Mesh::SetNodeOnEdge(SMDS_MeshNode* aNode, int Index)
{
//Set Position on Node
- aNode->SetPosition(new SMDS_EdgePosition(Index, 0.));
+ aNode->SetPosition(SMDS_PositionPtr(new SMDS_EdgePosition(Index, 0.)));
//Update or build submesh
if (myShapeIndexToSubMesh.find(Index)==myShapeIndexToSubMesh.end())
void SMESHDS_Mesh::SetNodeOnVertex(SMDS_MeshNode* aNode, int Index)
{
//Set Position on Node
- aNode->SetPosition(new SMDS_VertexPosition(Index));
+ aNode->SetPosition(SMDS_PositionPtr(new SMDS_VertexPosition(Index)));
//Update or build submesh
if (myShapeIndexToSubMesh.find(Index)==myShapeIndexToSubMesh.end())
SMESHDS_Mesh::~SMESHDS_Mesh()
{
}
-
-/**
- * Add FULL_UPDATE command to the log of this mesh. Once interpreted by the
- * graphical client it will (re)draw the full mesh.
- */
-void SMESHDS_Mesh::logFullUpdate()
-{
- myScript->UpdateAll();
-}
#include <hash_map.h>
#else
#include <ext/hash_map>
- using namespace __gnu_cxx;
+ namespace gstd = __gnu_cxx;
#endif
#endif
-using namespace std;
-
-class SMESHDS_Mesh:public SMDS_Mesh
-{
-
- public:
-
- SMESHDS_Mesh(int MeshID);
- void ShapeToMesh(const TopoDS_Shape & S);
- bool AddHypothesis(const TopoDS_Shape & SS, const SMESHDS_Hypothesis * H);
- bool RemoveHypothesis(const TopoDS_Shape & S, const SMESHDS_Hypothesis * H);
- SMDS_MeshNode * AddNode(double x, double y, double z);
- void RemoveNode(const SMDS_MeshNode *);
- void MoveNode(const SMDS_MeshNode *, double x, double y, double z);
- SMDS_MeshEdge* AddEdge(
- const SMDS_MeshNode * n1,
- const SMDS_MeshNode * n2);
- SMDS_MeshFace* AddFace(
- const SMDS_MeshNode * n1,
- const SMDS_MeshNode * n2,
- const SMDS_MeshNode * n3);
- SMDS_MeshFace* AddFace(
- const SMDS_MeshNode * n1,
- const SMDS_MeshNode * n2,
- const SMDS_MeshNode * n3,
- const SMDS_MeshNode * n4);
- SMDS_MeshVolume* AddVolume(
- const SMDS_MeshNode * n1,
- const SMDS_MeshNode * n2,
- const SMDS_MeshNode * n3,
- const SMDS_MeshNode * n4);
- SMDS_MeshVolume* AddVolume(
- const SMDS_MeshNode * n1,
- const SMDS_MeshNode * n2,
- const SMDS_MeshNode * n3,
- const SMDS_MeshNode * n4,
- const SMDS_MeshNode * n5);
- SMDS_MeshVolume* AddVolume(
- const SMDS_MeshNode * n1,
- const SMDS_MeshNode * n2,
- const SMDS_MeshNode * n3,
- const SMDS_MeshNode * n4,
- const SMDS_MeshNode * n5,
- const SMDS_MeshNode * n6);
- SMDS_MeshVolume* AddVolume(
- const SMDS_MeshNode * n1,
- const SMDS_MeshNode * n2,
- const SMDS_MeshNode * n3,
- const SMDS_MeshNode * n4,
- const SMDS_MeshNode * n5,
- const SMDS_MeshNode * n6,
- const SMDS_MeshNode * n7,
- const SMDS_MeshNode * n8);
-
- void RemoveElement(const SMDS_MeshElement *);
- void SetNodeInVolume(SMDS_MeshNode * aNode, const TopoDS_Shell & S);
- void SetNodeOnFace(SMDS_MeshNode * aNode, const TopoDS_Face & S);
- void SetNodeOnEdge(SMDS_MeshNode * aNode, const TopoDS_Edge & S);
- void SetNodeOnVertex(SMDS_MeshNode * aNode, const TopoDS_Vertex & S);
- void UnSetNodeOnShape(const SMDS_MeshNode * aNode);
- void SetMeshElementOnShape(const SMDS_MeshElement * anElt,
- const TopoDS_Shape & S);
- void UnSetMeshElementOnShape(const SMDS_MeshElement * anElt,
- const TopoDS_Shape & S);
- TopoDS_Shape ShapeToMesh() const;
- bool HasMeshElements(const TopoDS_Shape & S);
- SMESHDS_SubMesh * MeshElements(const TopoDS_Shape & S);
- bool HasHypothesis(const TopoDS_Shape & S);
- const list<const SMESHDS_Hypothesis*>& GetHypothesis(const TopoDS_Shape & S) const;
- SMESHDS_Script * GetScript();
- void ClearScript();
- int ShapeToIndex(const TopoDS_Shape & aShape);
- TopoDS_Shape IndexToShape(int ShapeIndex);
- void NewSubMesh(int Index);
- void SetNodeInVolume(const SMDS_MeshNode * aNode, int Index);
- void SetNodeOnFace(SMDS_MeshNode * aNode, int Index);
- void SetNodeOnEdge(SMDS_MeshNode * aNode, int Index);
- void SetNodeOnVertex(SMDS_MeshNode * aNode, int Index);
- void SetMeshElementOnShape(const SMDS_MeshElement * anElt, int Index);
- ~SMESHDS_Mesh();
- void logFullUpdate();
-
- private:
- struct HashTopoDS_Shape
- {
- size_t operator()(const TopoDS_Shape& S) const {return S.HashCode(2147483647);}
- };
- typedef hash_map<TopoDS_Shape, list<const SMESHDS_Hypothesis*>,HashTopoDS_Shape > ShapeToHypothesis;
- int myMeshID;
- TopoDS_Shape myShape;
- TopTools_IndexedMapOfShape myIndexToShape;
- map<int,SMESHDS_SubMesh*> myShapeIndexToSubMesh;
- ShapeToHypothesis myShapeToHypothesis;
- SMESHDS_Script * myScript;
+class SMESHDS_Mesh:public SMDS_Mesh{
+public:
+ SMESHDS_Mesh(int MeshID);
+ void ShapeToMesh(const TopoDS_Shape & S);
+ bool AddHypothesis(const TopoDS_Shape & SS, const SMESHDS_Hypothesis * H);
+ bool RemoveHypothesis(const TopoDS_Shape & S, const SMESHDS_Hypothesis * H);
+
+ virtual SMDS_MeshNode* AddNodeWithID(double x, double y, double z, int ID);
+ virtual SMDS_MeshNode * AddNode(double x, double y, double z);
+
+ virtual SMDS_MeshEdge* AddEdgeWithID(int n1, int n2, int ID);
+ virtual SMDS_MeshEdge* AddEdgeWithID(const SMDS_MeshNode * n1,
+ const SMDS_MeshNode * n2,
+ int ID);
+ virtual SMDS_MeshEdge* AddEdge(const SMDS_MeshNode * n1,
+ const SMDS_MeshNode * n2);
+
+ virtual SMDS_MeshFace* AddFaceWithID(int n1, int n2, int n3, int ID);
+ virtual SMDS_MeshFace* AddFaceWithID(const SMDS_MeshNode * n1,
+ const SMDS_MeshNode * n2,
+ const SMDS_MeshNode * n3,
+ int ID);
+ virtual SMDS_MeshFace* AddFace(const SMDS_MeshNode * n1,
+ const SMDS_MeshNode * n2,
+ const SMDS_MeshNode * n3);
+
+ virtual SMDS_MeshFace* AddFaceWithID(int n1, int n2, int n3, int n4, int ID);
+ virtual SMDS_MeshFace* AddFaceWithID(const SMDS_MeshNode * n1,
+ const SMDS_MeshNode * n2,
+ const SMDS_MeshNode * n3,
+ const SMDS_MeshNode * n4,
+ int ID);
+ virtual SMDS_MeshFace* AddFace(const SMDS_MeshNode * n1,
+ const SMDS_MeshNode * n2,
+ const SMDS_MeshNode * n3,
+ const SMDS_MeshNode * n4);
+
+ virtual SMDS_MeshVolume* AddVolumeWithID(int n1, int n2, int n3, int n4, int ID);
+ virtual SMDS_MeshVolume* AddVolumeWithID(const SMDS_MeshNode * n1,
+ const SMDS_MeshNode * n2,
+ const SMDS_MeshNode * n3,
+ const SMDS_MeshNode * n4,
+ int ID);
+ virtual SMDS_MeshVolume* AddVolume(const SMDS_MeshNode * n1,
+ const SMDS_MeshNode * n2,
+ const SMDS_MeshNode * n3,
+ const SMDS_MeshNode * n4);
+
+ virtual SMDS_MeshVolume* AddVolumeWithID(int n1, int n2, int n3, int n4, int n5, int ID);
+ virtual SMDS_MeshVolume* AddVolumeWithID(const SMDS_MeshNode * n1,
+ const SMDS_MeshNode * n2,
+ const SMDS_MeshNode * n3,
+ const SMDS_MeshNode * n4,
+ const SMDS_MeshNode * n5,
+ int ID);
+ virtual SMDS_MeshVolume* AddVolume(const SMDS_MeshNode * n1,
+ const SMDS_MeshNode * n2,
+ const SMDS_MeshNode * n3,
+ const SMDS_MeshNode * n4,
+ const SMDS_MeshNode * n5);
+
+ virtual SMDS_MeshVolume* AddVolumeWithID(int n1, int n2, int n3, int n4, int n5, int n6, int ID);
+ virtual SMDS_MeshVolume* AddVolumeWithID(const SMDS_MeshNode * n1,
+ const SMDS_MeshNode * n2,
+ const SMDS_MeshNode * n3,
+ const SMDS_MeshNode * n4,
+ const SMDS_MeshNode * n5,
+ const SMDS_MeshNode * n6,
+ int ID);
+ virtual SMDS_MeshVolume* AddVolume(const SMDS_MeshNode * n1,
+ const SMDS_MeshNode * n2,
+ const SMDS_MeshNode * n3,
+ const SMDS_MeshNode * n4,
+ const SMDS_MeshNode * n5,
+ const SMDS_MeshNode * n6);
+
+ virtual SMDS_MeshVolume* AddVolumeWithID(int n1, int n2, int n3, int n4, int n5, int n6, int n7, int n8, int ID);
+ virtual SMDS_MeshVolume* AddVolumeWithID(const SMDS_MeshNode * n1,
+ const SMDS_MeshNode * n2,
+ const SMDS_MeshNode * n3,
+ const SMDS_MeshNode * n4,
+ const SMDS_MeshNode * n5,
+ const SMDS_MeshNode * n6,
+ const SMDS_MeshNode * n7,
+ const SMDS_MeshNode * n8,
+ int ID);
+ virtual SMDS_MeshVolume* AddVolume(const SMDS_MeshNode * n1,
+ const SMDS_MeshNode * n2,
+ const SMDS_MeshNode * n3,
+ const SMDS_MeshNode * n4,
+ const SMDS_MeshNode * n5,
+ const SMDS_MeshNode * n6,
+ const SMDS_MeshNode * n7,
+ const SMDS_MeshNode * n8);
+
+ void MoveNode(const SMDS_MeshNode *, double x, double y, double z);
+ virtual void RemoveNode(const SMDS_MeshNode *);
+ void RemoveElement(const SMDS_MeshElement *);
+
+ void SetNodeInVolume(SMDS_MeshNode * aNode, const TopoDS_Shell & S);
+ void SetNodeOnFace(SMDS_MeshNode * aNode, const TopoDS_Face & S);
+ void SetNodeOnEdge(SMDS_MeshNode * aNode, const TopoDS_Edge & S);
+ void SetNodeOnVertex(SMDS_MeshNode * aNode, const TopoDS_Vertex & S);
+ void UnSetNodeOnShape(const SMDS_MeshNode * aNode);
+ void SetMeshElementOnShape(const SMDS_MeshElement * anElt,
+ const TopoDS_Shape & S);
+ void UnSetMeshElementOnShape(const SMDS_MeshElement * anElt,
+ const TopoDS_Shape & S);
+ TopoDS_Shape ShapeToMesh() const;
+ bool HasMeshElements(const TopoDS_Shape & S);
+ SMESHDS_SubMesh * MeshElements(const TopoDS_Shape & S);
+ SMESHDS_SubMesh * MeshElements(const int Index);
+ list<int> SubMeshIndices();
+ const std::map<int,SMESHDS_SubMesh*>& SubMeshes()
+ { return myShapeIndexToSubMesh; }
+
+ bool HasHypothesis(const TopoDS_Shape & S);
+ const list<const SMESHDS_Hypothesis*>& GetHypothesis(const TopoDS_Shape & S) const;
+ SMESHDS_Script * GetScript();
+ void ClearScript();
+ int ShapeToIndex(const TopoDS_Shape & aShape);
+ TopoDS_Shape IndexToShape(int ShapeIndex);
+
+ void NewSubMesh(int Index);
+ void SetNodeInVolume(const SMDS_MeshNode * aNode, int Index);
+ void SetNodeOnFace(SMDS_MeshNode * aNode, int Index);
+ void SetNodeOnEdge(SMDS_MeshNode * aNode, int Index);
+ void SetNodeOnVertex(SMDS_MeshNode * aNode, int Index);
+ void SetMeshElementOnShape(const SMDS_MeshElement * anElt, int Index);
+
+ ~SMESHDS_Mesh();
+
+private:
+ struct HashTopoDS_Shape{
+ size_t operator()(const TopoDS_Shape& S) const {
+ return S.HashCode(2147483647);
+ }
+ };
+ typedef std::list<const SMESHDS_Hypothesis*> THypList;
+ typedef gstd::hash_map<TopoDS_Shape,THypList,HashTopoDS_Shape> ShapeToHypothesis;
+ ShapeToHypothesis myShapeToHypothesis;
+
+ int myMeshID;
+ TopoDS_Shape myShape;
+ TopTools_IndexedMapOfShape myIndexToShape;
+ std::map<int,SMESHDS_SubMesh*> myShapeIndexToSubMesh;
+ SMESHDS_Script* myScript;
};
+
+
#endif
// Module : SMESH
// $Header:
+using namespace std;
#include "SMESHDS_Script.hxx"
//=======================================================================
{
return myCommands;
}
-
-/**
- * Add UpdateAll command to the log of this mesh. Once interpreted by the
- * graphical client it will (re)draw the full mesh.
- */
-void SMESHDS_Script::UpdateAll()
-{
- myCommands.insert(myCommands.end(), new SMESHDS_Command(SMESHDS_UpdateAll));
-}
void RemoveElement(int ElementID);
void Clear();
const list<SMESHDS_Command*> & GetCommands();
- void UpdateAll();
~SMESHDS_Script();
private:
//function : RemoveElement
//purpose :
//=======================================================================
-void SMESHDS_SubMesh::RemoveElement(const SMDS_MeshElement * ME)
+bool SMESHDS_SubMesh::RemoveElement(const SMDS_MeshElement * ME)
{
- myElements.erase(ME);
+ if ( NbElements() )
+ return myElements.erase(ME);
+
+ return false;
}
//=======================================================================
//function : RemoveNode
//purpose :
//=======================================================================
-void SMESHDS_SubMesh::RemoveNode(const SMDS_MeshNode * N)
+bool SMESHDS_SubMesh::RemoveNode(const SMDS_MeshNode * N)
{
- myNodes.erase(N);
+ if ( NbNodes() )
+ return myNodes.erase(N);
+
+ return false;
}
//=======================================================================
template<typename T> class MySetIterator:public SMDS_Iterator<const T*>
{
- const set<const T*>& mySet;
- set<const T*>::const_iterator myIt;
+ typedef const set<const T*> TSet;
+ typename TSet::const_iterator myIt;
+ TSet& mySet;
public:
MySetIterator(const set<const T*>& s):mySet(s), myIt(s.begin())
///Return an iterator on the elements of submesh
///The created iterator must be free by the caller
///////////////////////////////////////////////////////////////////////////////
-SMDS_Iterator<const SMDS_MeshElement*> * SMESHDS_SubMesh::GetElements() const
+SMDS_ElemIteratorPtr SMESHDS_SubMesh::GetElements() const
{
- return new MySetIterator<SMDS_MeshElement>(myElements);
+ return SMDS_ElemIteratorPtr(new MySetIterator<SMDS_MeshElement>(myElements));
}
///////////////////////////////////////////////////////////////////////////////
///Return an iterator on the nodes of submesh
///The created iterator must be free by the caller
///////////////////////////////////////////////////////////////////////////////
-SMDS_Iterator<const SMDS_MeshNode*> * SMESHDS_SubMesh::GetNodes() const
+SMDS_NodeIteratorPtr SMESHDS_SubMesh::GetNodes() const
{
- return new MySetIterator<SMDS_MeshNode>(myNodes);
+ return SMDS_NodeIteratorPtr(new MySetIterator<SMDS_MeshNode>(myNodes));
}
{
public:
void AddElement(const SMDS_MeshElement * ME);
- void RemoveElement(const SMDS_MeshElement * ME);
+ bool RemoveElement(const SMDS_MeshElement * ME); // ret true if ME was in
void AddNode(const SMDS_MeshNode * ME);
- void RemoveNode(const SMDS_MeshNode * ME);
+ bool RemoveNode(const SMDS_MeshNode * ME); // ret true if ME was in
int NbElements() const;
- SMDS_Iterator<const SMDS_MeshElement*> * GetElements() const;
+ SMDS_ElemIteratorPtr GetElements() const;
int NbNodes() const;
- SMDS_Iterator<const SMDS_MeshNode*> * GetNodes() const;
+ SMDS_NodeIteratorPtr GetNodes() const;
private:
const SMDS_Mesh * myMesh;
SUBMESH_EDGE,
SUBMESH_FACE,
SUBMESH_SOLID,
- SUBMESH_COMPOUND
+ SUBMESH_COMPOUND,
+ GROUP
};
if ( !meshFilter->IsOk(anObj) )
return false;
+ bool Ok = false;
+
if ( anObj->hasEntry() ) {
QAD_Study* ActiveStudy = QAD_Application::getDesktop()->getActiveStudy();
SALOMEDS::Study_var aStudy = ActiveStudy->getStudyDocument();
SALOMEDS::SObject_var obj = aStudy->FindObjectID( anObj->getEntry() );
- bool Ok = false;
+ SALOMEDS::SObject_var objFather = obj->GetFather();
+ SALOMEDS::SComponent_var objComponent = obj->GetFatherComponent();
+
+ if ( strlen( obj->GetID() ) <= strlen( objComponent->GetID() ) )
+ return false;
switch ( myKind )
{
case HYPOTHESIS:
{
- SALOMEDS::SObject_var objFather = obj->GetFather();
- SALOMEDS::SComponent_var objComponent = obj->GetFatherComponent();
if (( objFather->Tag() == 1 ) && (strcmp( objFather->GetID(), objComponent->GetID() ) != 0 ) )
Ok = true;
break;
}
case ALGORITHM:
{
- SALOMEDS::SObject_var objFather = obj->GetFather();
- SALOMEDS::SComponent_var objComponent = obj->GetFatherComponent();
if (( objFather->Tag() == 2 ) && (strcmp( objFather->GetID(), objComponent->GetID() ) != 0 ) )
Ok = true;
break;
}
case MESH:
{
- SALOMEDS::SObject_var objFather = obj->GetFather();
- SALOMEDS::SComponent_var objComponent = obj->GetFatherComponent();
-
if (( obj->Tag() >= 3 ) && (strcmp( objFather->GetID(), objComponent->GetID() ) == 0 ) )
Ok = true;
break;
}
case SUBMESH:
{
- SALOMEDS::SObject_var objFather = obj->GetFather();
- SALOMEDS::SComponent_var objComponent = obj->GetFatherComponent();
-
- if (( objFather->Tag() >= 4 ) && (strcmp( objFather->GetID(), objComponent->GetID() ) != 0 ) )
+ if (( objFather->Tag() >= 4 && objFather->Tag() < 9 ) && (strcmp( objFather->GetID(), objComponent->GetID() ) != 0 ) )
Ok = true;
break;
}
case MESHorSUBMESH:
{
- SALOMEDS::SObject_var objFather = obj->GetFather();
- SALOMEDS::SComponent_var objComponent = obj->GetFatherComponent();
-
if (( obj->Tag() >= 3 ) && (strcmp( objFather->GetID(), objComponent->GetID() ) == 0 ) )
Ok = true;
- if (( objFather->Tag() >= 4 ) && (strcmp( objFather->GetID(), objComponent->GetID() ) != 0 ) )
+ if (( objFather->Tag() >= 4 && objFather->Tag() < 9 ) && (strcmp( objFather->GetID(), objComponent->GetID() ) != 0 ) )
Ok = true;
break;
}
- case SUBMESH_VERTEX:
+ case SUBMESH_VERTEX: // Label "SubMeshes on vertexes"
{
- SALOMEDS::SObject_var objFather = obj->GetFather();
- SALOMEDS::SComponent_var objComponent = obj->GetFatherComponent();
-
if (( obj->Tag() == 4 ) && (strcmp( objFather->GetID(), objComponent->GetID() ) != 0 ) && ( objFather->Tag() >= 3 ))
Ok = true;
break;
}
case SUBMESH_EDGE:
{
- SALOMEDS::SObject_var objFather = obj->GetFather();
- SALOMEDS::SComponent_var objComponent = obj->GetFatherComponent();
-
if (( obj->Tag() == 5 ) && (strcmp( objFather->GetID(), objComponent->GetID() ) != 0 ) && ( objFather->Tag() >= 3 ))
Ok = true;
break;
}
case SUBMESH_FACE:
{
- SALOMEDS::SObject_var objFather = obj->GetFather();
- SALOMEDS::SComponent_var objComponent = obj->GetFatherComponent();
-
if (( obj->Tag() == 6 ) && (strcmp( objFather->GetID(), objComponent->GetID() ) != 0 ) && ( objFather->Tag() >= 3 ))
Ok = true;
break;
}
case SUBMESH_SOLID:
{
- SALOMEDS::SObject_var objFather = obj->GetFather();
- SALOMEDS::SComponent_var objComponent = obj->GetFatherComponent();
-
if (( obj->Tag() == 7 ) && (strcmp( objFather->GetID(), objComponent->GetID() ) != 0 ) && ( objFather->Tag() >= 3 ))
Ok = true;
break;
}
case SUBMESH_COMPOUND:
{
- SALOMEDS::SObject_var objFather = obj->GetFather();
- SALOMEDS::SComponent_var objComponent = obj->GetFatherComponent();
-
if (( obj->Tag() == 8 ) && (strcmp( objFather->GetID(), objComponent->GetID() ) != 0 ) && ( objFather->Tag() >= 3 ))
Ok = true;
break;
}
+ case GROUP:
+ {
+ if (( objFather->Tag() >= 9 ) && (strcmp( objFather->GetID(), objComponent->GetID() ) != 0 ) )
+ Ok = true;
+ break;
+ }
}
-
- if ( Ok )
- return true;
}
- return false;
+ return Ok;
}
top_srcdir=@top_srcdir@
top_builddir=../..
srcdir=@srcdir@
-VPATH=.:@srcdir@:@top_srcdir@/idl:$(top_builddir)/idl:${KERNEL_ROOT_DIR}/idl/salome:${MED_ROOT_DIR}/idl/salome
+VPATH=.:@srcdir@:@top_srcdir@/idl:$(top_builddir)/idl
@COMMENCE@
# header files
EXPORT_HEADERS= SMESHGUI_Swig.hxx \
- SMESHGUI_Swig.i
+ SMESHGUI_Swig.i \
+ SMESHGUI.h \
+ SMESHGUI_Hypotheses.h \
+ SMESHGUI_SpinBox.h \
+ SMESHGUI_StudyAPI.h
# .po files to transform in .qm
PO_FILES = \
SMESHGUI_AddAlgorithmDlg.cxx \
SMESHGUI_InitMeshDlg.cxx \
SMESHGUI_AddSubMeshDlg.cxx \
- SMESHGUI_LocalLengthDlg.cxx \
- SMESHGUI_NbSegmentsDlg.cxx \
SMESHGUI_TransparencyDlg.cxx \
+ SMESHGUI_GroupDlg.cxx \
SMESHGUI_RemoveNodesDlg.cxx \
SMESHGUI_RemoveElementsDlg.cxx \
SMESHGUI_MeshInfosDlg.cxx \
SMESHGUI_Preferences_ColorDlg.cxx \
- SMESHGUI_MaxElementAreaDlg.cxx \
SMESHGUI_Preferences_ScalarBarDlg.cxx \
- SMESHGUI_EditScalarBarDlg.cxx \
+ SMESHGUI_Preferences_SelectionDlg.cxx \
SMESHGUI_aParameterDlg.cxx \
- SMESHGUI_MaxElementVolumeDlg.cxx \
SMESHGUI_Swig.cxx \
SMESHGUI_ComputeScalarValue.cxx \
SMESHGUI_MoveNodesDlg.cxx \
SMESHGUI_OrientationElementsDlg.cxx \
SMESHGUI_DiagonalInversionDlg.cxx \
- SMESHGUI_EdgesConnectivityDlg.cxx \
SMESHGUI_AddFaceDlg.cxx \
SMESHGUI_AddVolumeDlg.cxx \
SMESHGUI_AddEdgeDlg.cxx \
- SMESHGUI_EditHypothesesDlg.cxx
+ SMESHGUI_EditHypothesesDlg.cxx \
+ SMESHGUI_CreateHypothesesDlg.cxx \
+ SMESHGUI_XmlHandler.cxx \
+ SMESHGUI_Filter.cxx \
+ SMESHGUI_FilterDlg.cxx
LIB_MOC = \
SMESHGUI.h \
SMESHGUI_AddAlgorithmDlg.h \
SMESHGUI_InitMeshDlg.h \
SMESHGUI_AddSubMeshDlg.h \
- SMESHGUI_LocalLengthDlg.h \
- SMESHGUI_NbSegmentsDlg.h \
SMESHGUI_TransparencyDlg.h \
+ SMESHGUI_GroupDlg.h \
SMESHGUI_RemoveNodesDlg.h \
SMESHGUI_RemoveElementsDlg.h \
SMESHGUI_MeshInfosDlg.h \
SMESHGUI_Preferences_ColorDlg.h \
- SMESHGUI_MaxElementAreaDlg.h \
SMESHGUI_Preferences_ScalarBarDlg.h \
- SMESHGUI_EditScalarBarDlg.h \
+ SMESHGUI_Preferences_SelectionDlg.h \
SMESHGUI_aParameterDlg.h \
- SMESHGUI_MaxElementVolumeDlg.h \
SMESHGUI_MoveNodesDlg.h \
SMESHGUI_OrientationElementsDlg.h \
SMESHGUI_DiagonalInversionDlg.h \
- SMESHGUI_EdgesConnectivityDlg.h \
SMESHGUI_AddEdgeDlg.h \
SMESHGUI_AddVolumeDlg.h \
SMESHGUI_AddFaceDlg.h \
- SMESHGUI_EditHypothesesDlg.h
+ SMESHGUI_EditHypothesesDlg.h \
+ SMESHGUI_CreateHypothesesDlg.h \
+ SMESHGUI_FilterDlg.h
LIB_CLIENT_IDL = SALOME_Exception.idl \
GEOM_Gen.idl \
SMESH_Gen.idl \
SMESH_Mesh.idl \
SMESH_Hypothesis.idl \
- SMESH_BasicHypothesis.idl \
+ SMESH_Group.idl \
SALOMEDS.idl \
SALOMEDS_Attributes.idl \
SALOME_ModuleCatalog.idl \
SALOME_Component.idl \
- MED.idl
+ MED.idl \
+ SMESH_Filter.idl \
+ SALOME_GenericObj.idl
LIB_SERVER_IDL =
# additionnal information to compil and link file
-CPPFLAGS += $(QT_INCLUDES) $(VTK_INCLUDES) $(OGL_INCLUDES) $(OCC_INCLUDES) $(PYTHON_INCLUDES) $(MED2_INCLUDES) -I${KERNEL_ROOT_DIR}/include/salome -I${GEOM_ROOT_DIR}/include/salome
+CPPFLAGS += $(QT_INCLUDES) $(VTK_INCLUDES) $(OGL_INCLUDES) $(OCC_INCLUDES) $(PYTHON_INCLUDES) \
+ $(MED2_INCLUDES) -I${KERNEL_ROOT_DIR}/include/salome -I${GEOM_ROOT_DIR}/include/salome \
+ $(BOOST_CPPFLAGS)
CXXFLAGS += -I${KERNEL_ROOT_DIR}/include/salome -I${GEOM_ROOT_DIR}/include/salome
#$(OCC_CXXFLAGS)
-LDFLAGS += -lOCCViewer -lVTKViewer -lSalomeObject -lSalomeGUI -lSMESHObject -lSMDS -lSMESHDS -lSMESHFiltersSelection -lGEOMClient $(OCC_KERNEL_LIBS) -L${KERNEL_ROOT_DIR}/lib/salome -L${GEOM_ROOT_DIR}/lib/salome
+LDFLAGS += -lOCCViewer -lVTKViewer -lSalomeObject -lSalomeGUI -lSMESHObject -lSMDS -lSMESHDS -lSMESHFiltersSelection -lGEOMClient -lMeshDriverDAT -lMeshDriverMED -lMeshDriverUNV $(OCC_KERNEL_LIBS) -L${KERNEL_ROOT_DIR}/lib/salome -L${GEOM_ROOT_DIR}/lib/salome -lSalomeGenericObj
@CONCLUDE@
--- /dev/null
+int main(int argc, char** argv){
+ return 0;
+}
+
// License along with this library; if not, write to the Free Software
// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
//
-// See http://www.opencascade.org/SALOME/ or email : webmaster.salome@opencascade.org
-//
-//
+// See http://www.opencascade.org/SALOME/ or email : webmaster.salome@opencascade.org
//
// File : SMESHGUI.cxx
// Author : Nicolas REJNERI
// Module : SMESH
// $Header$
-using namespace std;
#include "SMESHGUI.h"
#include "SMESHGUI_AddHypothesisDlg.h"
#include "SMESHGUI_AddAlgorithmDlg.h"
#include "SMESHGUI_InitMeshDlg.h"
-#include "SMESHGUI_LocalLengthDlg.h"
-#include "SMESHGUI_NbSegmentsDlg.h"
#include "SMESHGUI_AddSubMeshDlg.h"
#include "SMESHGUI_NodesDlg.h"
#include "SMESHGUI_TransparencyDlg.h"
+#include "SMESHGUI_GroupDlg.h"
#include "SMESHGUI_RemoveNodesDlg.h"
#include "SMESHGUI_RemoveElementsDlg.h"
#include "SMESHGUI_MeshInfosDlg.h"
#include "SMESHGUI_Preferences_ColorDlg.h"
-#include "SMESHGUI_MaxElementAreaDlg.h"
-#include "SMESHGUI_MaxElementVolumeDlg.h"
#include "SMESHGUI_Preferences_ScalarBarDlg.h"
-#include "SMESHGUI_EditScalarBarDlg.h"
+#include "SMESHGUI_Preferences_SelectionDlg.h"
#include "SMESHGUI_aParameterDlg.h"
#include "SMESHGUI_ComputeScalarValue.h"
#include "SMESHGUI_MoveNodesDlg.h"
#include "SMESHGUI_OrientationElementsDlg.h"
#include "SMESHGUI_DiagonalInversionDlg.h"
-#include "SMESHGUI_EdgesConnectivityDlg.h"
#include "SMESHGUI_AddFaceDlg.h"
#include "SMESHGUI_AddEdgeDlg.h"
#include "SMESHGUI_AddVolumeDlg.h"
#include "SMESHGUI_EditHypothesesDlg.h"
+#include "SMESHGUI_CreateHypothesesDlg.h"
+#include "SMESHGUI_FilterDlg.h"
+#include "SMESHGUI_XmlHandler.h"
-#include "SMESH_Grid.h"
+#include "SMESH_Actor.h"
+#include "SMESH_Object.h"
// SALOME Includes
#include "Utils_ORB_INIT.hxx"
#include "QAD_MessageBox.h"
#include "QAD_Resource.h"
#include "QAD_FileDlg.h"
-#include "SALOMEGUI_Desktop.h"
-#include "SALOMEGUI_NameDlg.h"
+#include "QAD_Desktop.h"
+#include "QAD_ResourceMgr.h"
+#include "QAD_WaitCursor.h"
#include "OCCViewer_ViewPort.h"
#include "OCCViewer_ViewPort3d.h"
#include "OCCViewer_Viewer3d.h"
-#include "GEOM_Client.hxx"
#include "GEOM_InteractiveObject.hxx"
#include "SALOME_NamingService.hxx"
#include "SALOME_ListIteratorOfListIO.hxx"
#include "SALOME_InteractiveObject.hxx"
+#include "SALOMEGUI_Desktop.h"
+#include "SALOMEGUI_NameDlg.h"
#include "SALOMEGUI_ImportOperation.h"
#include "SALOMEGUI_QtCatchCorbaException.hxx"
+
#include "utilities.h"
+#include <dlfcn.h>
+
+#include "SMDS_Mesh.hxx"
+#include "SMESHDS_Document.hxx"
+#include "Document_Reader.h"
+#include "Document_Writer.h"
+#include "Mesh_Reader.h"
+#include "Mesh_Writer.h"
+
+#include "DriverDAT_R_SMESHDS_Document.h"
+#include "DriverMED_R_SMESHDS_Document.h"
+#include "DriverUNV_R_SMESHDS_Document.h"
+#include "DriverDAT_W_SMESHDS_Document.h"
+#include "DriverMED_W_SMESHDS_Document.h"
+#include "DriverUNV_W_SMESHDS_Document.h"
+#include "DriverDAT_R_SMESHDS_Mesh.h"
+#include "DriverMED_R_SMESHDS_Mesh.h"
+#include "DriverUNV_R_SMESHDS_Mesh.h"
+#include "DriverDAT_W_SMESHDS_Mesh.h"
+#include "DriverMED_W_SMESHDS_Mesh.h"
+#include "DriverUNV_W_SMESHDS_Mesh.h"
// QT Includes
#define INCLUDE_MENUITEM_DEF
#include <qstring.h>
#include <qcheckbox.h>
#include <qcolordialog.h>
-#include <qmessagebox.h>
#include <qspinbox.h>
#include <qlist.h>
#include <qwidget.h>
// VTK Includes
#include "VTKViewer_Common.h"
#include "VTKViewer_ViewFrame.h"
+#include "VTKViewer_InteractorStyleSALOME.h"
+
+#include <vtkScalarBarActor.h>
#include <vtkLegendBoxActor.h>
#include <vtkFeatureEdges.h>
#include <vtkDoubleArray.h>
+#include <vtkTextProperty.h>
// Open CASCADE Includes
#include <gp_Pnt.hxx>
#include <gp_Vec.hxx>
-static GEOM_Client ShapeReader;
+#include <boost/shared_ptr.hpp>
+
static SMESHGUI *smeshGUI = 0;
static CORBA::ORB_var _orb;
+using namespace std;
+
+typedef pair<int,string> TKeyOfVisualObj;
+typedef boost::shared_ptr<SMESH_VisualObj> TVisualObjPtr;
+typedef map<TKeyOfVisualObj,TVisualObjPtr> TVisualObjCont;
+static TVisualObjCont VISUALOBJCONT;
+
+
+TVisualObjPtr GetVisualObj(int theStudyId, const char* theEntry){
+ TVisualObjPtr aVisualObj;
+ try{
+ TVisualObjCont::key_type aKey(theStudyId,theEntry);
+ TVisualObjCont::iterator anIter = VISUALOBJCONT.find(aKey);
+ if(anIter != VISUALOBJCONT.end()){
+ aVisualObj = anIter->second;
+ }else{
+ SALOMEDS::Study_var aStudy = QAD_Application::getDesktop()->getActiveStudy()->getStudyDocument();
+ SALOMEDS::SObject_var aSObj = aStudy->FindObjectID(theEntry);
+ if(!CORBA::is_nil(aSObj)){
+ SALOMEDS::GenericAttribute_var anAttr;
+ if(aSObj->FindAttribute(anAttr,"AttributeIOR")){
+ SALOMEDS::AttributeIOR_var anIOR = SALOMEDS::AttributeIOR::_narrow(anAttr);
+ CORBA::String_var aVal = anIOR->Value();
+ CORBA::Object_var anObj =_orb->string_to_object(aVal.in());
+ if(!CORBA::is_nil(anObj)){
+ //Try narrow to SMESH_Mesh interafce
+ SMESH::SMESH_Mesh_var aMesh = SMESH::SMESH_Mesh::_narrow(anObj);
+ if(!aMesh->_is_nil()){
+ aVisualObj.reset(new SMESH_MeshObj(aMesh));
+ aVisualObj->Update();
+ TVisualObjCont::value_type aValue(aKey,aVisualObj);
+ VISUALOBJCONT.insert(aValue);
+ return aVisualObj;
+ }
+ //Try narrow to SMESH_Group interafce
+ SMESH::SMESH_Group_var aGroup = SMESH::SMESH_Group::_narrow(anObj);
+ if(!aGroup->_is_nil()){
+ SALOMEDS::SObject_var aFatherSObj = aSObj->GetFather();
+ if(aFatherSObj->_is_nil()) return aVisualObj;
+ aFatherSObj = aFatherSObj->GetFather();
+ if(aFatherSObj->_is_nil()) return aVisualObj;
+ CORBA::String_var anEntry = aFatherSObj->GetID();
+ TVisualObjPtr aVisObj = GetVisualObj(theStudyId,anEntry.in());
+ if(SMESH_MeshObj* aMeshObj = dynamic_cast<SMESH_MeshObj*>(aVisObj.get())){
+ aVisualObj.reset(new SMESH_GroupObj(aGroup,aMeshObj));
+ aVisualObj->Update();
+ TVisualObjCont::value_type aValue(aKey,aVisualObj);
+ VISUALOBJCONT.insert(aValue);
+ return aVisualObj;
+ }
+ }
+ //Try narrow to SMESH_subMesh interafce
+ SMESH::SMESH_subMesh_var aSubMesh = SMESH::SMESH_subMesh::_narrow(anObj);
+ if(!aSubMesh->_is_nil()){
+ SALOMEDS::SObject_var aFatherSObj = aSObj->GetFather();
+ if(aFatherSObj->_is_nil()) return aVisualObj;
+ aFatherSObj = aFatherSObj->GetFather();
+ if(aFatherSObj->_is_nil()) return aVisualObj;
+ CORBA::String_var anEntry = aFatherSObj->GetID();
+ TVisualObjPtr aVisObj = GetVisualObj(theStudyId,anEntry.in());
+ if(SMESH_MeshObj* aMeshObj = dynamic_cast<SMESH_MeshObj*>(aVisObj.get())){
+ aVisualObj.reset(new SMESH_subMeshObj(aSubMesh,aMeshObj));
+ aVisualObj->Update();
+ TVisualObjCont::value_type aValue(aKey,aVisualObj);
+ VISUALOBJCONT.insert(aValue);
+ return aVisualObj;
+ }
+ }
+ }
+ }
+ }
+ }
+ }catch(...){
+ INFOS("GetMeshObj - There is no SMESH_Mesh object for the SALOMEDS::Strudy and Entry!!!");
+ }
+ return aVisualObj;
+}
+
+
+VTKViewer_ViewFrame* GetVtkViewFrame(QAD_StudyFrame* theStudyFrame){
+ QAD_ViewFrame* aViewFrame = theStudyFrame->getRightFrame()->getViewFrame();
+ return dynamic_cast<VTKViewer_ViewFrame*>(aViewFrame);
+}
+
+void UpdateSelectionProp() {
+ QAD_Study* aStudy = SMESHGUI::GetSMESHGUI()->GetActiveStudy();
+ QList<QAD_StudyFrame> aFrameList = aStudy->getStudyFrames();
+
+ QString SCr, SCg, SCb;
+ SCr = QAD_CONFIG->getSetting("SMESH:SettingsSelectColorRed");
+ SCg = QAD_CONFIG->getSetting("SMESH:SettingsSelectColorGreen");
+ SCb = QAD_CONFIG->getSetting("SMESH:SettingsSelectColorBlue");
+ QColor aHiColor = Qt::white;
+ if (!SCr.isEmpty() && !SCg.isEmpty() && !SCb.isEmpty())
+ aHiColor = QColor(SCr.toInt(), SCg.toInt(), SCb.toInt());
+
+ SCr = QAD_CONFIG->getSetting("SMESH:SettingsItemSelectColorRed");
+ SCg = QAD_CONFIG->getSetting("SMESH:SettingsItemSelectColorGreen");
+ SCb = QAD_CONFIG->getSetting("SMESH:SettingsItemSelectColorBlue");
+ QColor aSelColor = Qt::yellow;
+ if (!SCr.isEmpty() && !SCg.isEmpty() && !SCb.isEmpty())
+ aSelColor = QColor(SCr.toInt(), SCg.toInt(), SCb.toInt());
+ QString SW = QAD_CONFIG->getSetting("SMESH:SettingsItemSelectWidth");
+ if (SW.isEmpty()) SW = "5";
+
+ SCr = QAD_CONFIG->getSetting("SMESH:SettingsPreSelectColorRed");
+ SCg = QAD_CONFIG->getSetting("SMESH:SettingsPreSelectColorGreen");
+ SCb = QAD_CONFIG->getSetting("SMESH:SettingsPreSelectColorBlue");
+ QColor aPreColor = Qt::cyan;
+ if (!SCr.isEmpty() && !SCg.isEmpty() && !SCb.isEmpty())
+ aPreColor = QColor(SCr.toInt(), SCg.toInt(), SCb.toInt());
+ QString PW = QAD_CONFIG->getSetting("SMESH:SettingsPreSelectWidth");
+ if (PW.isEmpty()) PW = "5";
+
+ QString SP1 = QAD_CONFIG->getSetting("SMESH:SettingsNodeSelectTol");
+ if (SP1.isEmpty()) SP1 = "0.025";
+ QString SP2 = QAD_CONFIG->getSetting("SMESH:SettingsElementsSelectTol");
+ if (SP2.isEmpty()) SP2 = "0.001";
+
+ for (QAD_StudyFrame* aStudyFrame = aFrameList.first(); aStudyFrame; aStudyFrame = aFrameList.next()) {
+ if (aStudyFrame->getTypeView() == VIEW_VTK) {
+ VTKViewer_ViewFrame* aVtkViewFrame = GetVtkViewFrame(aStudyFrame);
+ if (!aVtkViewFrame) continue;
+ // update VTK viewer properties
+ VTKViewer_RenderWindowInteractor* anInteractor = aVtkViewFrame->getRWInteractor();
+ if (anInteractor) {
+ // mesh element selection
+ anInteractor->SetSelectionProp(aSelColor.red()/255., aSelColor.green()/255.,
+ aSelColor.blue()/255., SW.toInt());
+
+ // tolerances
+ anInteractor->SetSelectionTolerance(SP1.toDouble(), SP2.toDouble());
+
+ // pre-selection
+ VTKViewer_InteractorStyleSALOME* aStyle = anInteractor->GetInteractorStyleSALOME();
+ if (aStyle) {
+ aStyle->setPreselectionProp(aPreColor.red()/255., aPreColor.green()/255.,
+ aPreColor.blue()/255., PW.toInt());
+ }
+ }
+ // update actors
+ vtkRenderer* aRenderer = aVtkViewFrame->getRenderer();
+ vtkActorCollection *aCollection = aRenderer->GetActors();
+ aCollection->InitTraversal();
+ while(vtkActor *anAct = aCollection->GetNextActor()){
+ if(SMESH_Actor *anActor = dynamic_cast<SMESH_Actor*>(anAct)){
+ anActor->SetHighlightColor(aHiColor.red()/255., aHiColor.green()/255.,
+ aHiColor.blue()/255.);
+ anActor->SetPreHighlightColor(aPreColor.red()/255., aPreColor.green()/255.,
+ aPreColor.blue()/255.);
+ }
+ }
+ }
+ }
+}
+
+VTKViewer_ViewFrame* GetCurrentVtkView(){
+ QAD_Study* aStudy = SMESHGUI::GetSMESHGUI()->GetActiveStudy();
+ QAD_StudyFrame *aStudyFrame = aStudy->getActiveStudyFrame();
+ return GetVtkViewFrame(aStudyFrame);
+}
+
+
+SMESH_Actor* FindActorByEntry(QAD_StudyFrame *theStudyFrame,
+ const char* theEntry)
+{
+ if(VTKViewer_ViewFrame* aViewFrame = GetVtkViewFrame(theStudyFrame)){
+ vtkRenderer *aRenderer = aViewFrame->getRenderer();
+ vtkActorCollection *aCollection = aRenderer->GetActors();
+ aCollection->InitTraversal();
+ while(vtkActor *anAct = aCollection->GetNextActor()){
+ if(SMESH_Actor *anActor = dynamic_cast<SMESH_Actor*>(anAct)){
+ if(anActor->hasIO()){
+ Handle(SALOME_InteractiveObject) anIO = anActor->getIO();
+ if(anIO->hasEntry() && strcmp(anIO->getEntry(),theEntry) == 0){
+ return anActor;
+ }
+ }
+ }
+ }
+ }
+ return NULL;
+}
+
+
+SMESH_Actor* FindActorByEntry(const char* theEntry){
+ QAD_Study* aStudy = SMESHGUI::GetSMESHGUI()->GetActiveStudy();
+ QAD_StudyFrame *aStudyFrame = aStudy->getActiveStudyFrame();
+ return FindActorByEntry(aStudyFrame,theEntry);
+}
+
+
+SMESH_Actor* CreateActor(SALOMEDS::Study_ptr theStudy,
+ const char* theEntry,
+ int theIsClear = false)
+{
+ SMESH_Actor *anActor = NULL;
+ CORBA::Long anId = theStudy->StudyId();
+ if(TVisualObjPtr aVisualObj = GetVisualObj(anId,theEntry)){
+ SALOMEDS::SObject_var aSObj = theStudy->FindObjectID(theEntry);
+ if(!aSObj->_is_nil()){
+ SALOMEDS::GenericAttribute_var anAttr;
+ if(aSObj->FindAttribute(anAttr,"AttributeName")){
+ SALOMEDS::AttributeName_var aName = SALOMEDS::AttributeName::_narrow(anAttr);
+ CORBA::String_var aVal = aName->Value();
+ string aNameVal = aVal.in();
+ SMESH::FilterManager_ptr aFilterMgr = smeshGUI->GetFilterMgr();
+ anActor = SMESH_Actor::New(aVisualObj,aFilterMgr,theEntry,aNameVal.c_str(),theIsClear);
+ }
+ }
+ }
+ return anActor;
+}
+
+
+void DisplayActor(QAD_StudyFrame *theStudyFrame, SMESH_Actor* theActor){
+ if(VTKViewer_ViewFrame* aViewFrame = GetVtkViewFrame(theStudyFrame)){
+ aViewFrame->AddActor(theActor);
+ aViewFrame->Repaint();
+ }
+}
+
+
+void RemoveActor(QAD_StudyFrame *theStudyFrame, SMESH_Actor* theActor){
+ if(VTKViewer_ViewFrame* aViewFrame = GetVtkViewFrame(theStudyFrame)){
+ aViewFrame->RemoveActor(theActor);
+ aViewFrame->Repaint();
+ }
+}
+
+
+void FitAll(){
+ if(VTKViewer_ViewFrame* aViewFrame = GetCurrentVtkView()){
+ aViewFrame->onViewFitAll();
+ aViewFrame->Repaint();
+ }
+}
+
+vtkRenderer* GetCurrentRenderer(){
+ if(VTKViewer_ViewFrame* aViewFrame = GetCurrentVtkView())
+ return aViewFrame->getRenderer();
+ return NULL;
+}
+
+void RepaintCurrentView(){
+ if(VTKViewer_ViewFrame* aViewFrame = GetCurrentVtkView())
+ aViewFrame->Repaint();
+}
+
+
+enum EDisplaing {eDisplayAll, eDisplay, eDisplayOnly, eErase, eEraseAll};
+void UpdateView(QAD_StudyFrame *theStudyFrame, EDisplaing theAction,
+ const char* theEntry = "")
+{
+ if(VTKViewer_ViewFrame* aViewFrame = GetVtkViewFrame(theStudyFrame)){
+ vtkRenderer *aRenderer = aViewFrame->getRenderer();
+ vtkActorCollection *aCollection = aRenderer->GetActors();
+ aCollection->InitTraversal();
+ switch(theAction){
+ case eDisplayAll: {
+ while(vtkActor *anAct = aCollection->GetNextActor()){
+ if(SMESH_Actor *anActor = dynamic_cast<SMESH_Actor*>(anAct)){
+ anActor->SetVisibility(true);
+ }
+ }
+ break;
+ }
+ case eDisplayOnly:
+ case eEraseAll: {
+ while(vtkActor *anAct = aCollection->GetNextActor()){
+ if(SMESH_Actor *anActor = dynamic_cast<SMESH_Actor*>(anAct)){
+ anActor->SetVisibility(false);
+ }
+ }
+ }
+ default: {
+ if(SMESH_Actor *anActor = FindActorByEntry(theStudyFrame,theEntry)){
+ switch(theAction) {
+ case eDisplay:
+ case eDisplayOnly:
+ anActor->SetVisibility(true);
+ break;
+ case eErase:
+ anActor->SetVisibility(false);
+ break;
+ }
+ } else {
+ switch(theAction){
+ case eDisplay:
+ case eDisplayOnly:{
+ QAD_Study* aStudy = theStudyFrame->getStudy();
+ SALOMEDS::Study_var aDocument = aStudy->getStudyDocument();
+ if(anActor = CreateActor(aDocument,theEntry,true)) {
+ DisplayActor(theStudyFrame,anActor);
+ FitAll();
+ }
+ break;
+ }
+ }
+ }
+ }
+ }
+ }
+}
+
+
+void UpdateView(EDisplaing theAction, const char* theEntry = ""){
+ QAD_Study* aStudy = SMESHGUI::GetSMESHGUI()->GetActiveStudy();
+ QAD_StudyFrame *aStudyFrame = aStudy->getActiveStudyFrame();
+ UpdateView(aStudyFrame,theAction,theEntry);
+}
+
+static bool IsReferencedObject( SALOMEDS::SObject_ptr SO )
+{
+ if ( !SO->_is_nil() ) {
+ SALOMEDS::GenericAttribute_var anAttr;
+ if ( SO->FindAttribute( anAttr, "AttributeTarget" ) ) {
+ SALOMEDS::AttributeTarget_var aTarget = SALOMEDS::AttributeTarget::_narrow( anAttr );
+ SALOMEDS::Study::ListOfSObject_var aList = aTarget->Get();
+ if ( aList->length() > 0 ) {
+ return true;
+ }
+ }
+ }
+ return false;
+}
+
+void SetPointRepresentation(bool theIsVisible){
+ if(VTKViewer_ViewFrame* aViewFrame = GetCurrentVtkView()){
+ vtkRenderer *aRenderer = aViewFrame->getRenderer();
+ vtkActorCollection *aCollection = aRenderer->GetActors();
+ aCollection->InitTraversal();
+ while(vtkActor *anAct = aCollection->GetNextActor()){
+ if(SMESH_Actor *anActor = dynamic_cast<SMESH_Actor*>(anAct)){
+ if(anActor->GetVisibility()){
+ anActor->SetPointRepresentation(theIsVisible);
+ }
+ }
+ }
+ RepaintCurrentView();
+ }
+}
+
+
//=============================================================================
/*!
*
//=============================================================================
class CustomItem:public QCustomMenuItem
{
- public:
- CustomItem(const QString & s, const QFont & f):string(s), font(f)
- {
- };
- ~CustomItem()
- {
- }
-
- void paint(QPainter * p, const QColorGroup & /*cg */ , bool /*act */ ,
- bool /*enabled */ , int x, int y, int w, int h)
- {
- p->setFont(font);
- p->drawText(x, y, w, h,
- AlignHCenter | AlignVCenter | ShowPrefix | DontClip, string);
- }
-
- QSize sizeHint()
- {
- return QFontMetrics(font).
- size(AlignHCenter | AlignVCenter | ShowPrefix | DontClip, string);
- }
- private:
- QString string;
- QFont font;
+ public:
+ CustomItem(const QString & s, const QFont & f):string(s), font(f)
+ {
+ };
+ ~CustomItem()
+ {
+ }
+
+ void paint(QPainter * p, const QColorGroup & /*cg */ , bool /*act */ ,
+ bool /*enabled */ , int x, int y, int w, int h)
+ {
+ p->setFont(font);
+ p->drawText(x, y, w, h,
+ AlignHCenter | AlignVCenter | ShowPrefix | DontClip, string);
+ }
+
+ QSize sizeHint()
+ {
+ return QFontMetrics(font).
+ size(AlignHCenter | AlignVCenter | ShowPrefix | DontClip, string);
+ }
+ private:
+ QString string;
+ QFont font;
};
//=============================================================================
*
*/
//=============================================================================
-SMESHGUI::SMESHGUI():
-QObject()
+SMESHGUI::SMESHGUI( const QString& theName, QObject* theParent ) :
+ SALOMEGUI( theName, theParent )
{
}
*
*/
//=============================================================================
-SMESHGUI *SMESHGUI::GetSMESHGUI()
+SMESHGUI* SMESHGUI::GetSMESHGUI()
{
- return smeshGUI;
+ if ( !smeshGUI )
+ GetOrCreateSMESHGUI( QAD_Application::getDesktop() );
+ return smeshGUI;
}
+extern "C"
+{
+ Standard_EXPORT SALOMEGUI* GetComponentGUI() {
+ return SMESHGUI::GetSMESHGUI();
+ }
+}
//=============================================================================
/*!
*
*/
//=============================================================================
-SMESHGUI *SMESHGUI::GetOrCreateSMESHGUI(QAD_Desktop * desktop)
+SMESHGUI* SMESHGUI::GetOrCreateSMESHGUI( QAD_Desktop* desktop )
{
- if (smeshGUI == 0)
- {
- setOrb();
- smeshGUI = new SMESHGUI;
- smeshGUI->myActiveDialogBox = 0;
- smeshGUI->myState = -1;
- smeshGUI->myDesktop = desktop;
- smeshGUI->myActiveStudy = desktop->getActiveStudy();
-
- Engines::Component_var comp =
- desktop->getEngine("FactoryServer", "SMESH");
- smeshGUI->myComponentMesh = SMESH::SMESH_Gen::_narrow(comp);
-
- Engines::Component_var comp1 =
- desktop->getEngine("FactoryServer", "GEOM");
- smeshGUI->myComponentGeom = GEOM::GEOM_Gen::_narrow(comp1);
-
- /* GetCurrentStudy */
- smeshGUI->myStudyId = smeshGUI->myActiveStudy->getStudyId();
-
- smeshGUI->myComponentGeom->GetCurrentStudy(smeshGUI->myStudyId);
- // smeshGUI->myComponentGeom->NbLabels();
-
- smeshGUI->myStudy = smeshGUI->myActiveStudy->getStudyDocument();
-
- smeshGUI->myStudyAPI =
- SMESHGUI_StudyAPI(smeshGUI->myStudy, smeshGUI->myComponentMesh);
-
- smeshGUI->mySimulationActors = vtkActorCollection::New();
- smeshGUI->mySimulationActors2D = vtkActor2DCollection::New();
- }
- else
- {
- /* study may have changed */
- smeshGUI->myActiveStudy = desktop->getActiveStudy();
- smeshGUI->myStudyAPI.Update(smeshGUI->myComponentMesh);
- }
-
- /* Automatic Update */
- if (desktop->menuBar()->isItemChecked(1001))
- smeshGUI->myAutomaticUpdate = true;
- else
- smeshGUI->myAutomaticUpdate = false;
-
- return smeshGUI;
+ if( !smeshGUI ) {
+ setOrb();
+ smeshGUI = new SMESHGUI;
+ smeshGUI->myActiveDialogBox = 0 ;
+ smeshGUI->myState = -1 ;
+ smeshGUI->myDesktop = desktop ;
+
+ /* get smesh engine */
+ Engines::Component_var comp = desktop->getEngine("FactoryServer", "SMESH");
+ smeshGUI->myComponentMesh = SMESH::SMESH_Gen::_narrow(comp);
+
+ /* get geom engine */
+ Engines::Component_var comp1 = desktop->getEngine("FactoryServer", "GEOM");
+ smeshGUI->myComponentGeom = GEOM::GEOM_Gen::_narrow(comp1);
+
+ /* set current study */
+ smeshGUI->myActiveStudy = desktop->getActiveStudy();
+ smeshGUI->myStudyId = smeshGUI->myActiveStudy->getStudyId();
+ smeshGUI->myStudy = smeshGUI->myActiveStudy->getStudyDocument();
+ smeshGUI->myComponentGeom->GetCurrentStudy( smeshGUI->myStudyId );
+ smeshGUI->myComponentMesh->SetCurrentStudy( smeshGUI->myStudy );
+ // smeshGUI->myComponentGeom->NbLabels();
+
+ /* create service object */
+ smeshGUI->myStudyAPI = SMESHGUI_StudyAPI(smeshGUI->myStudy, smeshGUI->myComponentMesh);
+
+ smeshGUI->myDocument = new SMESHDS_Document(1);//NBU
+
+ smeshGUI->mySimulationActors = vtkActorCollection::New();
+ smeshGUI->mySimulationActors2D = vtkActor2DCollection::New();
+
+ /*filter manager*/
+ smeshGUI->myFilterMgr = smeshGUI->myComponentMesh->CreateFilterManager();
+
+ /* load resources for all available meshers */
+ smeshGUI->InitAvailableHypotheses();
+ } else {
+ /* study may have changed - set current study */
+ smeshGUI->myActiveStudy = desktop->getActiveStudy();
+ smeshGUI->myStudyId = smeshGUI->myActiveStudy->getStudyId();
+ smeshGUI->myStudy = smeshGUI->myActiveStudy->getStudyDocument();
+ smeshGUI->myComponentGeom->GetCurrentStudy( smeshGUI->myStudyId );
+ smeshGUI->myComponentMesh->SetCurrentStudy( smeshGUI->myStudy );
+
+ // Set active study to Study API
+ smeshGUI->myStudyAPI.Update( smeshGUI->myStudy );
+ }
+
+ /* Automatic Update flag */
+ smeshGUI->myAutomaticUpdate = ( QAD_CONFIG->getSetting( "SMESH:AutomaticUpdate" ).compare( "true" ) == 0 );
+
+ return smeshGUI;
}
//=============================================================================
//=============================================================================
void SMESHGUI::SetState(int aState)
{
- this->myState = aState;
- return;
+ this->myState = aState;
+ return;
}
//=============================================================================
//=============================================================================
void SMESHGUI::ResetState()
{
- this->myState = -1;
- return;
+ this->myState = -1;
+ return;
}
//=============================================================================
//=============================================================================
void SMESHGUI::EmitSignalDeactivateDialog()
{
- emit this->SignalDeactivateActiveDialog();
- return;
+ emit this->SignalDeactivateActiveDialog();
+ return;
}
//=============================================================================
//=============================================================================
void SMESHGUI::EmitSignalCloseAllDialogs()
{
- emit this->SignalCloseAllDialogs();
- return;
+ emit SignalCloseAllDialogs();
+ return;
}
//=============================================================================
//=============================================================================
QDialog *SMESHGUI::GetActiveDialogBox()
{
- return this->myActiveDialogBox;
+ return this->myActiveDialogBox;
}
//=============================================================================
//=============================================================================
void SMESHGUI::SetActiveDialogBox(QDialog * aDlg)
{
- this->myActiveDialogBox = (QDialog *) aDlg;
- return;
+ this->myActiveDialogBox = (QDialog *) aDlg;
+ return;
}
//=============================================================================
//=============================================================================
QAD_Study *SMESHGUI::GetActiveStudy()
{
- return this->myActiveStudy;
+ return this->myActiveStudy;
}
//=============================================================================
//=============================================================================
SALOMEDS::Study_ptr SMESHGUI::GetStudy()
{
- return SALOMEDS::Study::_narrow(myStudy);
+ return SALOMEDS::Study::_narrow(myStudy);
}
//=============================================================================
//=============================================================================
SMESHGUI_StudyAPI SMESHGUI::GetStudyAPI()
{
- return myStudyAPI;
+ return myStudyAPI;
}
//=============================================================================
//=============================================================================
QAD_Desktop *SMESHGUI::GetDesktop()
{
- return this->myDesktop;
+ return this->myDesktop;
}
//=============================================================================
*
*/
//=============================================================================
-vtkScalarBarActor *SMESHGUI::GetScalarBar()
+bool SMESHGUI::ActiveStudyChanged(QAD_Desktop* parent)
{
- vtkRenderer *aRenderer =
- ((VTKViewer_ViewFrame *) myActiveStudy->getActiveStudyFrame()->
- getRightFrame()->getViewFrame())->getRenderer();
- vtkActor2DCollection *actor2DList = aRenderer->GetActors2D();
- actor2DList->InitTraversal();
- vtkActor2D *aActor2d = actor2DList->GetNextActor2D();
- while (aActor2d != NULL)
- {
- if (aActor2d->IsA("vtkScalarBarActor"))
- return vtkScalarBarActor::SafeDownCast(aActor2d);
- actor2DList->GetNextActor2D();
- }
- return NULL;
+ MESSAGE("SMESHGUI::activeStudyChanged init.");
+ QAD_Study* prevStudy = 0;
+ if ( smeshGUI )
+ prevStudy = smeshGUI->myActiveStudy;
+ /* Create or retrieve an object SMESHGUI */
+ MESSAGE("Active study changed : prev study =" << prevStudy);
+ SMESHGUI::GetOrCreateSMESHGUI( parent );
+ MESSAGE("Active study changed : active study =" << smeshGUI->myActiveStudy);
+ if ( prevStudy != smeshGUI->myActiveStudy ) {
+ smeshGUI->EmitSignalCloseAllDialogs();
+ MESSAGE("Active study changed : SMESHGUI nullified" << endl);
+ //smeshGUI = 0;
+ ::UpdateSelectionProp();
+ }
+ MESSAGE("SMESHGUI::activeStudyChanged done.");
+ return true;
}
//=============================================================================
*
*/
//=============================================================================
-void SMESHGUI::activeStudyChanged(QAD_Desktop * parent)
+bool SMESHGUI::DefineDlgPosition(QWidget * aDlg, int &x, int &y)
{
- MESSAGE("SMESHGUI::activeStudyChanged init.")
- /* Create or retrieve an object SMESHGUI */
- SMESHGUI::GetOrCreateSMESHGUI(parent);
- if (smeshGUI != 0)
- {
- smeshGUI->EmitSignalCloseAllDialogs();
- MESSAGE("Active study changed : SMESHGUI nullified" << endl);
- smeshGUI = 0;
- }
-
- //smeshGUI->SetSettings( parent ); //DCQ : Pb. Multi-Etudes
- MESSAGE("SMESHGUI::activeStudyChanged done.") return;
+ /* Here the position is on the bottom right corner - 10 */
+ // aDlg->resize(QSize().expandedTo(aDlg->minimumSizeHint()));
+ aDlg->adjustSize();
+ QAD_Desktop *PP = QAD_Application::getDesktop();
+ x = abs(PP->x() + PP->size().width() - aDlg->size().width() - 10);
+ y = abs(PP->y() + PP->size().height() - aDlg->size().height() - 10);
+ return true;
}
//=============================================================================
*
*/
//=============================================================================
-bool SMESHGUI::DefineDlgPosition(QWidget * aDlg, int &x, int &y)
+void SMESHGUI::EraseSimulationActors()
{
- /* Here the position is on the bottom right corner - 10 */
- aDlg->resize(QSize().expandedTo(aDlg->minimumSizeHint()));
- QAD_Desktop *PP = QAD_Application::getDesktop();
- x = abs(PP->x() + PP->size().width() - aDlg->size().width() - 10);
- y = abs(PP->y() + PP->size().height() - aDlg->size().height() - 10);
- return true;
+ if (myActiveStudy->getActiveStudyFrame()->getTypeView() == VIEW_VTK)
+ { //VTK
+ vtkRenderer *theRenderer =
+ ((VTKViewer_ViewFrame *) myActiveStudy->getActiveStudyFrame()->
+ getRightFrame()->getViewFrame())->getRenderer();
+ vtkRenderWindow *renWin = theRenderer->GetRenderWindow();
+
+ if (mySimulationActors != NULL)
+ {
+ mySimulationActors->InitTraversal();
+ vtkActor *ac = mySimulationActors->GetNextActor();
+ while (!(ac == NULL))
+ {
+ theRenderer->RemoveActor(ac);
+ ac = mySimulationActors->GetNextActor();
+ }
+ mySimulationActors->RemoveAllItems();
+ }
+ if (mySimulationActors2D != NULL)
+ {
+ mySimulationActors2D->InitTraversal();
+ vtkActor2D *ac = mySimulationActors2D->GetNextActor2D();
+ while (!(ac == NULL))
+ {
+ theRenderer->RemoveActor2D(ac);
+ ac = mySimulationActors2D->GetNextActor2D();
+ }
+ mySimulationActors2D->RemoveAllItems();
+ }
+ SetPointRepresentation(false);
+ }
}
//=============================================================================
*
*/
//=============================================================================
-void SMESHGUI::EraseSimulationActors()
+SMESH::SMESH_Mesh_ptr SMESHGUI::InitMesh( GEOM::GEOM_Shape_ptr aShape,
+ QString NameMesh )
{
- if (myActiveStudy->getActiveStudyFrame()->getTypeView() == VIEW_VTK)
- { //VTK
- vtkRenderer *theRenderer =
- ((VTKViewer_ViewFrame *) myActiveStudy->getActiveStudyFrame()->
- getRightFrame()->getViewFrame())->getRenderer();
- vtkRenderWindow *renWin = theRenderer->GetRenderWindow();
-
- if (mySimulationActors != NULL)
- {
-
- mySimulationActors->InitTraversal();
- vtkActor *ac = mySimulationActors->GetNextActor();
- while (!(ac == NULL))
- {
- theRenderer->RemoveActor(ac);
- ac = mySimulationActors->GetNextActor();
- }
- mySimulationActors->RemoveAllItems();
- }
- if (mySimulationActors2D != NULL)
- {
- mySimulationActors2D->InitTraversal();
- vtkActor2D *ac = mySimulationActors2D->GetNextActor2D();
- while (!(ac == NULL))
- {
- theRenderer->RemoveActor2D(ac);
- ac = mySimulationActors2D->GetNextActor2D();
- }
- mySimulationActors2D->RemoveAllItems();
- }
- renWin->Render();
- }
+ try {
+ if ( !myComponentMesh->_is_nil() && !aShape->_is_nil() ) {
+ SMESH::SMESH_Mesh_var aMesh = myComponentMesh->CreateMesh( aShape );
+ if ( !aMesh->_is_nil() ) {
+ SALOMEDS::SObject_var SM = smeshGUI->myStudy->FindObjectIOR( _orb->object_to_string( aMesh ) );
+ myStudyAPI.SetName( SM, NameMesh );
+ return SMESH::SMESH_Mesh::_narrow(aMesh);
+ }
+ }
+ }
+ catch( const SALOME::SALOME_Exception& S_ex ) {
+ QtCatchCorbaException( S_ex );
+ }
+ return SMESH::SMESH_Mesh::_nil();
}
//=============================================================================
*
*/
//=============================================================================
-SMESH::SMESH_Mesh_ptr SMESHGUI::InitMesh(GEOM::GEOM_Shape_ptr aShape,
- QString NameMesh)
+SMESH::SMESH_subMesh_ptr SMESHGUI::AddSubMesh( SMESH::SMESH_Mesh_ptr aMesh,
+ GEOM::GEOM_Shape_ptr aShape,
+ QString NameMesh )
{
- try
- {
- if (!myComponentMesh->_is_nil() && !aShape->_is_nil())
- {
- SMESH::SMESH_Mesh_var aMesh =
- myComponentMesh->Init(myComponentGeom, myStudyId, aShape);
-
- if (!aMesh->_is_nil())
- {
- SALOMEDS::SObject_var SM = myStudyAPI.AddNewMesh(aMesh);
- myStudyAPI.SetName(SM, NameMesh);
-
- // GEOM::GEOM_Shape has non-empty StudyShapeId only after AddInStudy operation,
- // not after loading from file, so let's use more reliable way to retrieve SObject
- Standard_CString ShapeIOR = _orb->object_to_string(aShape);
- SALOMEDS::SObject_var SObject =
- myStudy->FindObjectIOR(ShapeIOR);
- if (!SObject->_is_nil() && !SM->_is_nil())
- {
- myStudyAPI.SetShape(SM, SObject);
- }
- return SMESH::SMESH_Mesh::_narrow(aMesh);
- }
- }
- }
- catch(const SALOME::SALOME_Exception & S_ex)
- {
- QtCatchCorbaException(S_ex);
- }
- myActiveStudy->updateObjBrowser(true);
- return SMESH::SMESH_Mesh::_nil();
+ SMESH::SMESH_subMesh_var aSubMesh;
+ try {
+ if ( !aMesh->_is_nil() && !aShape->_is_nil() )
+ // create sub mesh
+ aSubMesh = SMESH::SMESH_subMesh::_duplicate( aMesh->GetSubMesh( aShape, NameMesh.latin1() ) ); //VSR: published automatically
+ }
+ catch( const SALOME::SALOME_Exception& S_ex ) {
+ QtCatchCorbaException( S_ex );
+ aSubMesh = SMESH::SMESH_subMesh::_nil();
+ }
+ return aSubMesh._retn();
}
//=============================================================================
*
*/
//=============================================================================
-SMESH::SMESH_subMesh_ptr SMESHGUI::AddSubMesh(SMESH::SMESH_Mesh_ptr aMesh,
- GEOM::GEOM_Shape_ptr aShape, QString NameMesh)
+SMESH::SMESH_Group_ptr SMESHGUI::AddGroup( SMESH::SMESH_Mesh_ptr aMesh,
+ SMESH::ElementType aType,
+ QString aName )
{
- try
- {
- SMESH::SMESH_subMesh_var aSubMesh = aMesh->GetElementsOnShape(aShape);
- SALOMEDS::SObject_var SO_Mesh = myStudyAPI.FindMesh(aMesh);
- Standard_CString ShapeIOR = _orb->object_to_string(aShape);
- SALOMEDS::SObject_var SO_GeomShape = myStudy->FindObjectIOR(ShapeIOR);
-
- if (!SO_GeomShape->_is_nil() && !SO_Mesh->_is_nil() &&
- !aSubMesh->_is_nil() && !aMesh->_is_nil())
- {
- SALOMEDS::SObject_var SO =
- myStudyAPI.AddSubMeshOnShape(SO_Mesh, SO_GeomShape, aSubMesh,
- aShape->ShapeType());
- myStudyAPI.SetName(SO, NameMesh);
-
- SMESH_Actor *amesh = SMESH_Actor::New();
- Handle(SALOME_InteractiveObject) IO =
- new SALOME_InteractiveObject(SO->GetID(), "MESH",
- strdup(NameMesh));
- amesh->setIO(IO);
- amesh->setName(strdup(NameMesh));
- DisplayActor(amesh, false);
- return SMESH::SMESH_subMesh::_narrow(aSubMesh);
- }
- }
- catch(const SALOME::SALOME_Exception & S_ex)
- {
- QtCatchCorbaException(S_ex);
- }
- myActiveStudy->updateObjBrowser(true);
- return SMESH::SMESH_subMesh::_nil();
+ SMESH::SMESH_Group_var aGroup;
+ try {
+ if ( !aMesh->_is_nil() )
+ // create group
+ aGroup = SMESH::SMESH_Group::_duplicate( aMesh->CreateGroup( aType, strdup(aName) ) ); //VSR: published automatically
+ }
+ catch( const SALOME::SALOME_Exception& S_ex ) {
+ QtCatchCorbaException( S_ex );
+ aGroup = SMESH::SMESH_Group::_nil();
+ }
+ myActiveStudy->updateObjBrowser( true );
+ return aGroup._retn();
}
//=============================================================================
*
*/
//=============================================================================
-SMESH::SMESH_Hypothesis_ptr SMESHGUI::CreateHypothesis(QString TypeHypothesis,
- QString NameHypothesis)
-{
- SMESH::SMESH_Hypothesis_var Hyp;
- try
- {
- Hyp = myComponentMesh->CreateHypothesis(TypeHypothesis, myStudyId);
- if (!Hyp->_is_nil())
- {
- SALOMEDS::SObject_var SHyp = myStudyAPI.AddNewHypothesis(Hyp);
- myStudyAPI.SetName(SHyp, NameHypothesis);
- }
- }
- catch(const SALOME::SALOME_Exception & S_ex)
- {
- QtCatchCorbaException(S_ex);
- }
- return SMESH::SMESH_Hypothesis::_narrow(Hyp);
+static void addMap( const map<string, HypothesisData*>& theMap,
+ map<string, HypothesisData*>& toMap)
+{
+ map<string, HypothesisData*>::const_iterator it;
+ for ( it = theMap.begin(); it != theMap.end(); it++ )
+ toMap.insert( *it );
}
+
//=============================================================================
/*!
- *
+ * InitAvailableHypotheses (read from resource XML file)
*/
//=============================================================================
-void SMESHGUI::AddHypothesisOnMesh(SMESH::SMESH_Mesh_ptr aMesh,
- SMESH::SMESH_Hypothesis_ptr aHyp)
+void SMESHGUI::InitAvailableHypotheses ()
{
- if (!aMesh->_is_nil())
- {
- QApplication::setOverrideCursor(Qt::waitCursor);
- SALOMEDS::SObject_var SM = myStudyAPI.FindMesh(aMesh);
- GEOM::GEOM_Shape_var aShape = myStudyAPI.GetShapeOnMeshOrSubMesh(SM);
- try
- {
- bool res = aMesh->AddHypothesis(aShape, aHyp);
- if (res)
- {
- SALOMEDS::SObject_var SH =
- myStudyAPI.FindHypothesisOrAlgorithms(aHyp);
- if (!SM->_is_nil() && !SH->_is_nil())
- {
- myStudyAPI.SetHypothesis(SM, SH);
- myStudyAPI.ModifiedMesh(SM, false);
- }
- QApplication::restoreOverrideCursor();
- }
- else
- {
- QApplication::restoreOverrideCursor();
- QAD_MessageBox::warn1(QAD_Application::getDesktop(),
- tr("SMESH_WRN_WARNING"),
- tr("SMESH_WRN_HYPOTHESIS_ALREADYEXIST"),
- tr("SMESH_BUT_YES"));
- }
- }
- catch(const SALOME::SALOME_Exception & S_ex)
- {
- QtCatchCorbaException(S_ex);
- }
- }
- myActiveStudy->updateObjBrowser(true);
- QApplication::restoreOverrideCursor();
+ QAD_WaitCursor wc;
+ if ((myHypothesesMap.begin() == myHypothesesMap.end()) &&
+ (myAlgorithmsMap.begin() == myAlgorithmsMap.end()))
+ {
+ // Resource manager
+ QAD_ResourceMgr* resMgr = QAD_Desktop::createResourceManager();
+ if (!resMgr) return;
+
+ // Find name of a resource XML file ("SMESH_Meshers.xml");
+ QString HypsXml;
+ char* cenv = getenv("SMESH_MeshersList");
+ if (cenv)
+ HypsXml.sprintf("%s", cenv);
+
+ QStringList HypsXmlList = QStringList::split( ":", HypsXml, false );
+ if (HypsXmlList.count() == 0)
+ {
+ QAD_MessageBox::error1(QAD_Application::getDesktop(),
+ tr("SMESH_WRN_WARNING"),
+ tr("MESHERS_FILE_NO_VARIABLE"),
+ tr("SMESH_BUT_OK"));
+ return;
+ }
+
+ // loop on files in HypsXml
+ QString aNoAccessFiles;
+ for ( int i = 0; i < HypsXmlList.count(); i++ ) {
+ QString HypsXml = HypsXmlList[ i ];
+
+ // Find full path to the resource XML file
+ QString xmlFile = HypsXml + ".xml";
+ xmlFile = QAD_Tools::addSlash(resMgr->findFile(xmlFile, HypsXml)) + xmlFile;
+
+ QFile file (QAD_Tools::unix2win(xmlFile));
+ if (file.exists() && file.open(IO_ReadOnly))
+ {
+ file.close();
+
+ SMESHGUI_XmlHandler* myXmlHandler = new SMESHGUI_XmlHandler();
+ ASSERT(myXmlHandler);
+
+ QXmlInputSource source (file);
+ QXmlSimpleReader reader;
+ reader.setContentHandler(myXmlHandler);
+ reader.setErrorHandler(myXmlHandler);
+ bool ok = reader.parse(source);
+ file.close();
+ if (ok)
+ {
+ addMap( myXmlHandler->myHypothesesMap, myHypothesesMap );
+ addMap( myXmlHandler->myAlgorithmsMap, myAlgorithmsMap );
+ }
+ else
+ {
+ QAD_MessageBox::error1(myDesktop,
+ tr("INF_PARSE_ERROR"),
+ tr(myXmlHandler->errorProtocol()),
+ tr("SMESH_BUT_OK"));
+ }
+ }
+ else
+ {
+ if (aNoAccessFiles.isEmpty())
+ aNoAccessFiles = xmlFile;
+ else
+ aNoAccessFiles += ", " + xmlFile;
+ }
+ } // end loop
+
+
+ if (!aNoAccessFiles.isEmpty())
+ {
+ QString aMess = tr("MESHERS_FILE_CANT_OPEN") + " " + aNoAccessFiles + "\n";
+ aMess += tr("MESHERS_FILE_CHECK_VARIABLE");
+ wc.stop();
+ QAD_MessageBox::warn1(QAD_Application::getDesktop(),
+ tr("SMESH_WRN_WARNING"),
+ aMess,
+ tr("SMESH_BUT_OK"));
+ wc.start();
+ }
+ }
}
//=============================================================================
/*!
- *
+ * GetAvailableHypotheses (read from resource XML file)
*/
//=============================================================================
-void SMESHGUI::
-RemoveHypothesisOrAlgorithmOnMesh(const Handle(SALOME_InteractiveObject) &
- IObject)
+QStringList SMESHGUI::GetAvailableHypotheses (const bool isAlgo)
{
- if (IObject->hasReference())
- {
- SMESH::SMESH_Hypothesis_var anHyp;
- SALOMEDS::SObject_var SO_Hypothesis =
- smeshGUI->myStudy->FindObjectID(IObject->getEntry());
- SALOMEDS::GenericAttribute_var anAttr;
- SALOMEDS::AttributeIOR_var anIOR;
-
- if (!SO_Hypothesis->_is_nil())
- {
- QApplication::setOverrideCursor(Qt::waitCursor);
- if (SO_Hypothesis->FindAttribute(anAttr, "AttributeIOR"))
- {
- anIOR = SALOMEDS::AttributeIOR::_narrow(anAttr);
- anHyp =
- SMESH::SMESH_Hypothesis::_narrow(_orb->
- string_to_object(anIOR->Value()));
- }
-
- SALOMEDS::SObject_var SO_Applied_Hypothesis =
- smeshGUI->myStudy->FindObjectID(IObject->getReference());
- if (!SO_Applied_Hypothesis->_is_nil())
- {
- SALOMEDS::SObject_var MorSM =
- smeshGUI->myStudyAPI.
- GetMeshOrSubmesh(SO_Applied_Hypothesis);
- if (!MorSM->_is_nil())
- {
- smeshGUI->myStudyAPI.ModifiedMesh(MorSM, false);
-
- GEOM::GEOM_Shape_var aShape =
- smeshGUI->myStudyAPI.GetShapeOnMeshOrSubMesh(MorSM);
- if (!aShape->_is_nil())
- {
- if (MorSM->FindAttribute(anAttr, "AttributeIOR"))
- {
- anIOR = SALOMEDS::AttributeIOR::_narrow(anAttr);
- SMESH::SMESH_Mesh_var aMesh =
- SMESH::SMESH_Mesh::_narrow(_orb->
- string_to_object(anIOR->Value()));
- SMESH::SMESH_subMesh_var aSubMesh =
- SMESH::SMESH_subMesh::_narrow(_orb->
- string_to_object(anIOR->Value()));
- if (!aMesh->_is_nil())
- {
- bool res =
- aMesh->RemoveHypothesis(aShape, anHyp);
- if (!res)
- {
- QApplication::restoreOverrideCursor();
- QAD_MessageBox::warn1(QAD_Application::
- getDesktop(), tr("SMESH_WRN_WARNING"),
- tr("SMESH_WRN_HYPOTHESIS_NOTEXIST"),
- tr("SMESH_BUT_YES"));
- }
- }
- else if (!aSubMesh->_is_nil())
- {
- aMesh = aSubMesh->GetFather();
- if (!aMesh->_is_nil())
- {
- bool res =
- aMesh->RemoveHypothesis(aShape, anHyp);
- if (!res)
- {
- QApplication::restoreOverrideCursor();
- QAD_MessageBox::warn1(QAD_Application::
- getDesktop(),
- tr("SMESH_WRN_WARNING"),
- tr("SMESH_WRN_HYPOTHESIS_NOTEXIST"),
- tr("SMESH_BUT_YES"));
- }
- }
- }
- if (myAutomaticUpdate)
- {
- SMESH_Actor *Mesh = smeshGUI->ReadScript(aMesh);
- if (Mesh != NULL)
- {
-#ifdef TRACE
- Dump(Mesh);
-#endif
- DisplayActor(Mesh);
- DisplayEdges(Mesh);
- smeshGUI->ChangeRepresentation(Mesh,
- Mesh->getDisplayMode());
- }
- }
- }
- }
- }
- smeshGUI->myStudyAPI.UnSetHypothesis(SO_Applied_Hypothesis);
- }
- }
- }
- else if (IObject->hasEntry())
- {
- MESSAGE("IObject entry " << IObject->getEntry())}
- QApplication::restoreOverrideCursor();
+ QStringList aHypList;
+
+ // Init list of available hypotheses, if needed
+ InitAvailableHypotheses();
+
+ // fill list of hypotheses/algorithms
+ map<string, HypothesisData*>::iterator anIter;
+ if (isAlgo)
+ {
+ anIter = myAlgorithmsMap.begin();
+ for (; anIter != myAlgorithmsMap.end(); anIter++)
+ {
+ aHypList.append(((*anIter).first).c_str());
+ }
+ }
+ else
+ {
+ anIter = myHypothesesMap.begin();
+ for (; anIter != myHypothesesMap.end(); anIter++)
+ {
+ aHypList.append(((*anIter).first).c_str());
+ }
+ }
+
+ return aHypList;
}
//=============================================================================
/*!
- *
+ * GetHypothesisData
*/
//=============================================================================
-void SMESHGUI::RemoveHypothesisOrAlgorithmOnMesh(SALOMEDS::SObject_ptr MorSM,
- SMESH::SMESH_Hypothesis_ptr anHyp)
+HypothesisData* SMESHGUI::GetHypothesisData (const char* aHypType)
{
- SALOMEDS::SObject_var AHR, aRef;
- SALOMEDS::GenericAttribute_var anAttr;
- SALOMEDS::AttributeIOR_var anIOR;
-
- if (!MorSM->_is_nil())
- {
- GEOM::GEOM_Shape_var aShape =
- smeshGUI->myStudyAPI.GetShapeOnMeshOrSubMesh(MorSM);
- if (!aShape->_is_nil())
- {
- if (MorSM->FindAttribute(anAttr, "AttributeIOR"))
- {
- anIOR = SALOMEDS::AttributeIOR::_narrow(anAttr);
- SMESH::SMESH_Mesh_var aMesh =
- SMESH::SMESH_Mesh::_narrow(_orb->string_to_object(anIOR->
- Value()));
- SMESH::SMESH_subMesh_var aSubMesh =
- SMESH::SMESH_subMesh::_narrow(_orb->string_to_object(anIOR->
- Value()));
- if (!aMesh->_is_nil())
- {
- bool res = aMesh->RemoveHypothesis(aShape, anHyp);
- if (!res)
- {
- QApplication::restoreOverrideCursor();
- QAD_MessageBox::warn1(QAD_Application::getDesktop(),
- tr("SMESH_WRN_WARNING"),
- tr("SMESH_WRN_HYPOTHESIS_NOTEXIST"),
- tr("SMESH_BUT_YES"));
- }
- }
- else if (!aSubMesh->_is_nil())
- {
- aMesh = aSubMesh->GetFather();
- if (!aMesh->_is_nil())
- {
- bool res = aMesh->RemoveHypothesis(aShape, anHyp);
- if (!res)
- {
- QApplication::restoreOverrideCursor();
- QAD_MessageBox::warn1(QAD_Application::getDesktop(),
- tr("SMESH_WRN_WARNING"),
- tr("SMESH_WRN_HYPOTHESIS_NOTEXIST"),
- tr("SMESH_BUT_YES"));
- }
- }
- }
- if (myAutomaticUpdate)
- {
- SMESH_Actor *Mesh = smeshGUI->ReadScript(aMesh);
- if (Mesh != NULL)
- {
-#ifdef TRACE
- Dump(Mesh);
-#endif
- DisplayActor(Mesh);
- DisplayEdges(Mesh);
- // smeshGUI->ChangeRepresentation( Mesh, Mesh->getDisplayMode() );
- }
- }
- }
- }
-
- if (MorSM->FindSubObject(2, AHR))
- {
- SALOMEDS::ChildIterator_var it = myStudy->NewChildIterator(AHR);
- for (; it->More(); it->Next())
- {
- SALOMEDS::SObject_var Obj = it->Value();
- if (Obj->ReferencedObject(aRef))
- {
- if (aRef->FindAttribute(anAttr, "AttributeIOR"))
- {
- anIOR = SALOMEDS::AttributeIOR::_narrow(anAttr);
- if (strcmp(anIOR->Value(),
- _orb->object_to_string(anHyp)) == 0)
- {
- smeshGUI->myStudyAPI.UnSetHypothesis(Obj);
- break;
- }
- }
- }
- }
- }
- if (MorSM->FindSubObject(3, AHR))
- {
- SALOMEDS::ChildIterator_var it = myStudy->NewChildIterator(AHR);
- for (; it->More(); it->Next())
- {
- SALOMEDS::SObject_var Obj = it->Value();
- if (Obj->ReferencedObject(aRef))
- {
- if (aRef->FindAttribute(anAttr, "AttributeIOR"))
- {
- anIOR = SALOMEDS::AttributeIOR::_narrow(anAttr);
- if (strcmp(anIOR->Value(),
- _orb->object_to_string(anHyp)) == 0)
- {
- smeshGUI->myStudyAPI.UnSetAlgorithm(Obj);
- break;
- }
- }
- }
- }
- }
- smeshGUI->myStudyAPI.ModifiedMesh(MorSM, false);
- }
- QApplication::restoreOverrideCursor();
+ HypothesisData* aHypData = 0;
+
+ // Init list of available hypotheses, if needed
+ InitAvailableHypotheses();
+
+ if (myHypothesesMap.find(aHypType) == myHypothesesMap.end())
+ {
+ if (myAlgorithmsMap.find(aHypType) != myAlgorithmsMap.end())
+ {
+ aHypData = myAlgorithmsMap[aHypType];
+ }
+ }
+ else
+ {
+ aHypData = myHypothesesMap[aHypType];
+ }
+ return aHypData;
}
//=============================================================================
-/*!
- *
+/*!
+ * Get a Hypothesis Creator from a Plugin Library
*/
//=============================================================================
-void SMESHGUI::AddAlgorithmOnMesh(SMESH::SMESH_Mesh_ptr aMesh,
- SMESH::SMESH_Hypothesis_ptr aHyp)
+SMESHGUI_GenericHypothesisCreator* SMESHGUI::GetHypothesisCreator(const QString& aHypType)
{
- if (!aMesh->_is_nil())
- {
- QApplication::setOverrideCursor(Qt::waitCursor);
- SALOMEDS::SObject_var SM = myStudyAPI.FindMesh(aMesh);
- GEOM::GEOM_Shape_var aShape = myStudyAPI.GetShapeOnMeshOrSubMesh(SM);
- try
- {
- bool res = aMesh->AddHypothesis(aShape, aHyp);
- if (res)
- {
- SALOMEDS::SObject_var SH =
- myStudyAPI.FindHypothesisOrAlgorithms(aHyp);
- if (!SM->_is_nil() && !SH->_is_nil())
- {
- myStudyAPI.SetAlgorithms(SM, SH);
- myStudyAPI.ModifiedMesh(SM, false);
- }
- }
- else
- {
- QApplication::restoreOverrideCursor();
- QAD_MessageBox::warn1(QAD_Application::getDesktop(),
- tr("SMESH_WRN_WARNING"),
- tr("SMESH_WRN_ALGORITHM_ALREADYEXIST"),
- tr("SMESH_BUT_YES"));
- }
- }
- catch(const SALOME::SALOME_Exception & S_ex)
- {
- QtCatchCorbaException(S_ex);
- }
- }
- myActiveStudy->updateObjBrowser(true);
- QApplication::restoreOverrideCursor();
+ char* sHypType = (char*)aHypType.latin1();
+ MESSAGE("Get HypothesisCreator for " << sHypType);
+
+ SMESHGUI_GenericHypothesisCreator* aCreator = 0;
+
+ // check, if creator for this hypothesis type already exists
+ if (myHypCreatorMap.find(sHypType) != myHypCreatorMap.end())
+ {
+ aCreator = myHypCreatorMap[sHypType];
+ }
+ else
+ {
+ // 1. Init list of available hypotheses, if needed
+ InitAvailableHypotheses();
+
+ // 2. Get names of plugin libraries
+ HypothesisData* aHypData = GetHypothesisData(sHypType);
+ if (!aHypData)
+ {
+ return aCreator;
+ }
+ QString aClientLibName = aHypData->ClientLibName;
+ QString aServerLibName = aHypData->ServerLibName;
+
+ // 3. Load Client Plugin Library
+ try
+ {
+ // load plugin library
+ MESSAGE("Loading client meshers plugin library ...");
+ void* libHandle = dlopen (aClientLibName, RTLD_LAZY);
+ if (!libHandle)
+ {
+ // report any error, if occured
+ const char* anError = dlerror();
+ MESSAGE(anError);
+ }
+ else
+ {
+ // get method, returning hypothesis creator
+ MESSAGE("Find GetHypothesisCreator() method ...");
+ typedef SMESHGUI_GenericHypothesisCreator* (*GetHypothesisCreator) \
+ (QString aHypType, QString aServerLibName, SMESHGUI* aSMESHGUI);
+ GetHypothesisCreator procHandle =
+ (GetHypothesisCreator)dlsym( libHandle, "GetHypothesisCreator" );
+ if (!procHandle)
+ {
+ MESSAGE("bad hypothesis client plugin library");
+ dlclose(libHandle);
+ }
+ else
+ {
+ // get hypothesis creator
+ MESSAGE("Get Hypothesis Creator for " << aHypType);
+ aCreator = procHandle(aHypType, aServerLibName, smeshGUI);
+ if (!aCreator)
+ {
+ MESSAGE("no such a hypothesis in this plugin");
+ }
+ else
+ {
+ // map hypothesis creator to a hypothesis name
+ myHypCreatorMap[sHypType] = aCreator;
+ }
+ }
+ }
+ }
+ catch (const SALOME::SALOME_Exception& S_ex)
+ {
+ QtCatchCorbaException(S_ex);
+ }
+ }
+
+ return aCreator;
}
//=============================================================================
*
*/
//=============================================================================
-void SMESHGUI::AddHypothesisOnSubMesh(SMESH::SMESH_subMesh_ptr aSubMesh,
- SMESH::SMESH_Hypothesis_ptr aHyp)
+SMESH::SMESH_Hypothesis_ptr SMESHGUI::CreateHypothesis (const QString& aHypType,
+ const QString& aHypName,
+ const bool isAlgo)
{
- if (!aSubMesh->_is_nil())
- {
- QApplication::setOverrideCursor(Qt::waitCursor);
- try
- {
- SMESH::SMESH_Mesh_var aMesh = aSubMesh->GetFather();
- SALOMEDS::SObject_var SsubM = myStudyAPI.FindSubMesh(aSubMesh);
- GEOM::GEOM_Shape_var aShape =
- myStudyAPI.GetShapeOnMeshOrSubMesh(SsubM);
- if (!aMesh->_is_nil())
- {
- bool res = aMesh->AddHypothesis(aShape, aHyp);
- if (res)
- {
- SALOMEDS::SObject_var SH =
- myStudyAPI.FindHypothesisOrAlgorithms(aHyp);
- if (!SsubM->_is_nil() && !SH->_is_nil())
- {
- myStudyAPI.SetHypothesis(SsubM, SH);
- myStudyAPI.ModifiedMesh(SsubM, false);
- }
- }
- else
- {
- QApplication::restoreOverrideCursor();
- QAD_MessageBox::warn1(QAD_Application::getDesktop(),
- tr("SMESH_WRN_WARNING"),
- tr("SMESH_WRN_HYPOTHESIS_ALREADYEXIST"),
- tr("SMESH_BUT_YES"));
- }
- }
- }
- catch(const SALOME::SALOME_Exception & S_ex)
- {
- QtCatchCorbaException(S_ex);
- }
- }
- myActiveStudy->updateObjBrowser(true);
- QApplication::restoreOverrideCursor();
+ MESSAGE("Create " << aHypType << " with name " << aHypName);
+
+ SMESH::SMESH_Hypothesis_var Hyp;
+
+ HypothesisData* aHypData = GetHypothesisData((char*)aHypType.latin1());
+ QString aServLib = aHypData->ServerLibName;
+
+ try
+ {
+ Hyp = myComponentMesh->CreateHypothesis(aHypType, aServLib);
+ if (!Hyp->_is_nil())
+ {
+ SALOMEDS::SObject_var SHyp =
+ smeshGUI->myStudy->FindObjectIOR( _orb->object_to_string( Hyp ) );
+ if (!SHyp->_is_nil())
+ {
+ if ( !aHypName.isEmpty() )
+ myStudyAPI.SetName( SHyp, aHypName );
+ myActiveStudy->updateObjBrowser(true);
+ return Hyp._retn();
+ }
+ }
+ }
+ catch (const SALOME::SALOME_Exception & S_ex)
+ {
+ QtCatchCorbaException(S_ex);
+ }
+
+ return SMESH::SMESH_Hypothesis::_nil();
}
//=============================================================================
*
*/
//=============================================================================
-void SMESHGUI::AddAlgorithmOnSubMesh(SMESH::SMESH_subMesh_ptr aSubMesh,
- SMESH::SMESH_Hypothesis_ptr aHyp)
+bool SMESHGUI::AddHypothesisOnMesh(SMESH::SMESH_Mesh_ptr aMesh,
+ SMESH::SMESH_Hypothesis_ptr aHyp)
{
- if (!aSubMesh->_is_nil())
- {
- QApplication::setOverrideCursor(Qt::waitCursor);
- try
- {
- SMESH::SMESH_Mesh_var aMesh = aSubMesh->GetFather();
- SALOMEDS::SObject_var SsubM = myStudyAPI.FindSubMesh(aSubMesh);
- GEOM::GEOM_Shape_var aShape =
- myStudyAPI.GetShapeOnMeshOrSubMesh(SsubM);
- if (!aMesh->_is_nil())
- {
- bool res = aMesh->AddHypothesis(aShape, aHyp);
- if (res)
- {
- SALOMEDS::SObject_var SH =
- myStudyAPI.FindHypothesisOrAlgorithms(aHyp);
- if (!SsubM->_is_nil() && !SH->_is_nil())
- {
- myStudyAPI.SetAlgorithms(SsubM, SH);
- myStudyAPI.ModifiedMesh(SsubM, false);
- }
- }
- else
- {
- QApplication::restoreOverrideCursor();
- QAD_MessageBox::warn1(QAD_Application::getDesktop(),
- tr("SMESH_WRN_WARNING"),
- tr("SMESH_WRN_ALGORITHM_ALREADYEXIST"),
- tr("SMESH_BUT_YES"));
- }
- }
- }
- catch(const SALOME::SALOME_Exception & S_ex)
- {
- QtCatchCorbaException(S_ex);
- }
- }
- myActiveStudy->updateObjBrowser(true);
- QApplication::restoreOverrideCursor();
+ int res = SMESH::HYP_UNKNOWN_FATAL;
+ QAD_WaitCursor wc;
+
+ if ( !aMesh->_is_nil() ) {
+ SALOMEDS::SObject_var SM = myStudyAPI.FindObject( aMesh );
+ GEOM::GEOM_Shape_var aShape = myStudyAPI.GetShapeOnMeshOrSubMesh(SM);
+ try {
+ res = aMesh->AddHypothesis( aShape, aHyp );
+ if ( res < SMESH::HYP_UNKNOWN_FATAL ) {
+ SALOMEDS::SObject_var SH = myStudyAPI.FindObject(aHyp);
+ if ( !SM->_is_nil() && !SH->_is_nil() ) {
+ //myStudyAPI.SetHypothesis(SM, SH); // VSR: published automatically by engine
+ myStudyAPI.ModifiedMesh(SM, false);
+ }
+ }
+ if ( res >= SMESH::HYP_UNKNOWN_FATAL ) {
+ wc.stop();
+ QAD_MessageBox::error1(QAD_Application::getDesktop(),
+ tr("SMESH_ERROR"),
+ tr(QString("SMESH_HYP_%1").arg(res)),
+ tr("SMESH_BUT_OK"));
+ wc.start();
+ }
+ else if ( res > SMESH::HYP_OK ) {
+ wc.stop();
+ QAD_MessageBox::warn1(QAD_Application::getDesktop(),
+ tr("SMESH_WRN_WARNING"),
+ tr(QString("SMESH_HYP_%1").arg(res)),
+ tr("SMESH_BUT_OK"));
+ wc.start();
+ }
+ }
+ catch( const SALOME::SALOME_Exception& S_ex ) {
+ wc.stop();
+ QtCatchCorbaException( S_ex );
+ res = SMESH::HYP_UNKNOWN_FATAL;
+ }
+ }
+ return res < SMESH::HYP_UNKNOWN_FATAL;
}
//=============================================================================
*
*/
//=============================================================================
-void SMESHGUI::CreateAlgorithm(QString TypeAlgo, QString NameAlgo)
+bool SMESHGUI::RemoveHypothesisOrAlgorithmOnMesh
+ (const Handle(SALOME_InteractiveObject)& IObject)
{
- SMESH::SMESH_Hypothesis_var Hyp;
- try
- {
- if (TypeAlgo.compare("Regular_1D") == 0)
- Hyp = myComponentMesh->CreateHypothesis(TypeAlgo, myStudyId);
- else if (TypeAlgo.compare("MEFISTO_2D") == 0)
- Hyp = myComponentMesh->CreateHypothesis(TypeAlgo, myStudyId);
- else if (TypeAlgo.compare("Quadrangle_2D") == 0)
- Hyp = myComponentMesh->CreateHypothesis(TypeAlgo, myStudyId);
- else if (TypeAlgo.compare("Hexa_3D") == 0)
- Hyp = myComponentMesh->CreateHypothesis(TypeAlgo, myStudyId);
- else if (TypeAlgo.compare("NETGEN_3D") == 0)
- Hyp = myComponentMesh->CreateHypothesis(TypeAlgo, myStudyId);
-
- if (!Hyp->_is_nil())
- {
- SALOMEDS::SObject_var SHyp = myStudyAPI.AddNewAlgorithms(Hyp);
- myStudyAPI.SetName(SHyp, NameAlgo);
- }
- }
- catch(const SALOME::SALOME_Exception & S_ex)
- {
- QtCatchCorbaException(S_ex);
- }
- myActiveStudy->updateObjBrowser(true);
+ int res = SMESH::HYP_UNKNOWN_FATAL;
+ QAD_WaitCursor wc;
+
+ if (IObject->hasReference())
+ {
+ try {
+ SMESH::SMESH_Hypothesis_var anHyp;
+ SALOMEDS::SObject_var SO_Hypothesis =
+ smeshGUI->myStudy->FindObjectID(IObject->getEntry());
+ SALOMEDS::GenericAttribute_var anAttr;
+ SALOMEDS::AttributeIOR_var anIOR;
+
+ if (!SO_Hypothesis->_is_nil()) {
+ if (SO_Hypothesis->FindAttribute(anAttr, "AttributeIOR")) {
+ anIOR = SALOMEDS::AttributeIOR::_narrow(anAttr);
+ anHyp = SMESH::SMESH_Hypothesis::_narrow
+ (_orb->string_to_object(anIOR->Value()));
+ }
+
+ SALOMEDS::SObject_var SO_Applied_Hypothesis =
+ smeshGUI->myStudy->FindObjectID(IObject->getReference());
+ if (!SO_Applied_Hypothesis->_is_nil()) {
+ SALOMEDS::SObject_var MorSM =
+ smeshGUI->myStudyAPI.GetMeshOrSubmesh(SO_Applied_Hypothesis);
+ if (!MorSM->_is_nil()) {
+ GEOM::GEOM_Shape_var aShape =
+ smeshGUI->myStudyAPI.GetShapeOnMeshOrSubMesh(MorSM);
+ if (!aShape->_is_nil() && MorSM->FindAttribute(anAttr, "AttributeIOR")) {
+ anIOR = SALOMEDS::AttributeIOR::_narrow(anAttr);
+ SMESH::SMESH_Mesh_var aMesh =
+ SMESH::SMESH_Mesh::_narrow(_orb->string_to_object(anIOR->Value()));
+ SMESH::SMESH_subMesh_var aSubMesh =
+ SMESH::SMESH_subMesh::_narrow(_orb->string_to_object(anIOR->Value()));
+
+ if (!aSubMesh->_is_nil())
+ aMesh = aSubMesh->GetFather();
+
+ if (!aMesh->_is_nil())
+ {
+ res = aMesh->RemoveHypothesis(aShape, anHyp);
+ if ( res < SMESH::HYP_UNKNOWN_FATAL )
+ smeshGUI->myStudyAPI.ModifiedMesh(MorSM, false);
+ if ( res > SMESH::HYP_OK ) {
+ wc.stop();
+ QAD_MessageBox::warn1(QAD_Application::getDesktop(),
+ tr("SMESH_WRN_WARNING"),
+ tr(QString("SMESH_HYP_%1").arg(res)),
+ tr("SMESH_BUT_OK"));
+ wc.start();
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ catch( const SALOME::SALOME_Exception& S_ex ) {
+ wc.stop();
+ QtCatchCorbaException( S_ex );
+ res = SMESH::HYP_UNKNOWN_FATAL;
+ }
+ }
+ else if (IObject->hasEntry())
+ {
+ MESSAGE("IObject entry " << IObject->getEntry());
+ }
+ return res < SMESH::HYP_UNKNOWN_FATAL;
}
//=============================================================================
*
*/
//=============================================================================
-void SMESHGUI::CreateLocalLength(QString TypeHypothesis, QString NameHypothesis,
- double Length)
+bool SMESHGUI::RemoveHypothesisOrAlgorithmOnMesh(SALOMEDS::SObject_ptr MorSM,
+ SMESH::SMESH_Hypothesis_ptr anHyp)
{
- QApplication::setOverrideCursor(Qt::waitCursor);
- try
- {
- SMESH::SMESH_Hypothesis_var Hyp =
- SMESH::SMESH_Hypothesis::_narrow(CreateHypothesis(TypeHypothesis,
- NameHypothesis));
- SMESH::SMESH_LocalLength_var LL =
- SMESH::SMESH_LocalLength::_narrow(Hyp);
- if (!LL->_is_nil())
- LL->SetLength(Length);
- }
- catch(const SALOME::SALOME_Exception & S_ex)
- {
- QtCatchCorbaException(S_ex);
- }
- myActiveStudy->updateObjBrowser(true);
- QApplication::restoreOverrideCursor();
+ SALOMEDS::SObject_var AHR, aRef;
+ SALOMEDS::GenericAttribute_var anAttr;
+ SALOMEDS::AttributeIOR_var anIOR;
+ int res = SMESH::HYP_UNKNOWN_FATAL;
+ QAD_WaitCursor wc;
+
+ if (!MorSM->_is_nil()) {
+ try {
+ GEOM::GEOM_Shape_var aShape = smeshGUI->myStudyAPI.GetShapeOnMeshOrSubMesh(MorSM);
+ if (!aShape->_is_nil()) {
+ if (MorSM->FindAttribute(anAttr, "AttributeIOR")) {
+ anIOR = SALOMEDS::AttributeIOR::_narrow(anAttr);
+ SMESH::SMESH_Mesh_var aMesh =
+ SMESH::SMESH_Mesh::_narrow(_orb->string_to_object(anIOR->Value()));
+ SMESH::SMESH_subMesh_var aSubMesh =
+ SMESH::SMESH_subMesh::_narrow(_orb->string_to_object(anIOR->Value()));
+
+ if ( !aSubMesh->_is_nil() )
+ aMesh = aSubMesh->GetFather();
+
+ if (!aMesh->_is_nil()) {
+ res = aMesh->RemoveHypothesis(aShape, anHyp);
+ if ( res < SMESH::HYP_UNKNOWN_FATAL )
+ smeshGUI->myStudyAPI.ModifiedMesh(MorSM, false);
+ if ( res > SMESH::HYP_OK ) {
+ wc.stop();
+ QAD_MessageBox::warn1(QAD_Application::getDesktop(),
+ tr("SMESH_WRN_WARNING"),
+ tr(QString("SMESH_HYP_%1").arg(res)),
+ tr("SMESH_BUT_OK"));
+ wc.start();
+ }
+ }
+ }
+ }
+ }
+ catch( const SALOME::SALOME_Exception& S_ex ) {
+ wc.stop();
+ QtCatchCorbaException( S_ex );
+ res = SMESH::HYP_UNKNOWN_FATAL;
+ }
+ }
+ return res < SMESH::HYP_UNKNOWN_FATAL;
}
//=============================================================================
*
*/
//=============================================================================
-void SMESHGUI::CreateMaxElementArea(QString TypeHypothesis,
- QString NameHypothesis, double MaxArea)
+bool SMESHGUI::AddAlgorithmOnMesh( SMESH::SMESH_Mesh_ptr aMesh,
+ SMESH::SMESH_Hypothesis_ptr aHyp )
{
- QApplication::setOverrideCursor(Qt::waitCursor);
- try
- {
- SMESH::SMESH_Hypothesis_var Hyp =
- SMESH::SMESH_Hypothesis::_narrow(CreateHypothesis(TypeHypothesis,
- NameHypothesis));
- SMESH::SMESH_MaxElementArea_var MaxElArea =
- SMESH::SMESH_MaxElementArea::_narrow(Hyp);
- if (!MaxElArea->_is_nil())
- MaxElArea->SetMaxElementArea(MaxArea);
- }
- catch(SALOME::SALOME_Exception & S_ex)
- {
- QtCatchCorbaException(S_ex);
- }
-
- myActiveStudy->updateObjBrowser(true);
- QApplication::restoreOverrideCursor();
+ int res = SMESH::HYP_UNKNOWN_FATAL;
+ QAD_WaitCursor wc;
+
+ if ( !aMesh->_is_nil() ) {
+ SALOMEDS::SObject_var SM = myStudyAPI.FindObject( aMesh );
+ GEOM::GEOM_Shape_var aShape = myStudyAPI.GetShapeOnMeshOrSubMesh( SM );
+ try {
+ res = aMesh->AddHypothesis( aShape, aHyp );
+ if ( res < SMESH::HYP_UNKNOWN_FATAL ) {
+ //SALOMEDS::SObject_var SH = myStudyAPI.FindObject( aHyp );
+ //if ( !SM->_is_nil() && !SH->_is_nil() ) {
+ //myStudyAPI.SetAlgorithms(SM, SH);
+ myStudyAPI.ModifiedMesh( SM, false );
+ //}
+ }
+ if ( res >= SMESH::HYP_UNKNOWN_FATAL ) {
+ wc.stop();
+ QAD_MessageBox::error1(QAD_Application::getDesktop(),
+ tr("SMESH_ERROR"),
+ tr(QString("SMESH_HYP_%1").arg(res)),
+ tr("SMESH_BUT_OK"));
+ wc.start();
+ }
+ else if ( res > SMESH::HYP_OK ) {
+ wc.stop();
+ QAD_MessageBox::warn1( QAD_Application::getDesktop(),
+ tr( "SMESH_WRN_WARNING" ),
+ tr(QString("SMESH_HYP_%1").arg(res)),
+ tr( "SMESH_BUT_OK" ) );
+ wc.start();
+ }
+ }
+ catch( const SALOME::SALOME_Exception& S_ex ) {
+ wc.stop();
+ QtCatchCorbaException( S_ex );
+ res = SMESH::HYP_UNKNOWN_FATAL;
+ }
+ }
+ return res < SMESH::HYP_UNKNOWN_FATAL;
}
//=============================================================================
*
*/
//=============================================================================
-void SMESHGUI::CreateMaxElementVolume(QString TypeHypothesis,
- QString NameHypothesis, double MaxVolume)
+bool SMESHGUI::AddHypothesisOnSubMesh( SMESH::SMESH_subMesh_ptr aSubMesh,
+ SMESH::SMESH_Hypothesis_ptr aHyp )
{
- QApplication::setOverrideCursor(Qt::waitCursor);
- try
- {
- SMESH::SMESH_Hypothesis_var Hyp =
- SMESH::SMESH_Hypothesis::_narrow(CreateHypothesis(TypeHypothesis,
- NameHypothesis));
- SMESH::SMESH_MaxElementVolume_var MaxElVolume =
- SMESH::SMESH_MaxElementVolume::_narrow(Hyp);
- if (!MaxElVolume->_is_nil())
- MaxElVolume->SetMaxElementVolume(MaxVolume);
- }
- catch(const SALOME::SALOME_Exception & S_ex)
- {
- QtCatchCorbaException(S_ex);
- }
- myActiveStudy->updateObjBrowser(true);
- QApplication::restoreOverrideCursor();
+ int res = SMESH::HYP_UNKNOWN_FATAL;
+ QAD_WaitCursor wc;
+
+ if ( !aSubMesh->_is_nil() ) {
+ try {
+ SMESH::SMESH_Mesh_var aMesh = aSubMesh->GetFather();
+ SALOMEDS::SObject_var SsubM = myStudyAPI.FindObject( aSubMesh );
+ GEOM::GEOM_Shape_var aShape = myStudyAPI.GetShapeOnMeshOrSubMesh( SsubM );
+ if ( !aMesh->_is_nil() && !SsubM->_is_nil() && !aShape->_is_nil() ) {
+ res = aMesh->AddHypothesis( aShape, aHyp );
+ if ( res < SMESH::HYP_UNKNOWN_FATAL ) {
+ //SALOMEDS::SObject_var SH = myStudyAPI.FindObject(aHyp);
+ // if (!SsubM->_is_nil() && !SH->_is_nil())
+ // {
+ // myStudyAPI.SetHypothesis(SsubM, SH);
+ myStudyAPI.ModifiedMesh( SsubM, false );
+ // }
+ }
+ if ( res >= SMESH::HYP_UNKNOWN_FATAL ) {
+ wc.stop();
+ QAD_MessageBox::error1(QAD_Application::getDesktop(),
+ tr("SMESH_ERROR"),
+ tr(QString("SMESH_HYP_%1").arg(res)),
+ tr("SMESH_BUT_OK"));
+ wc.start();
+ }
+ else if ( res > SMESH::HYP_OK ) {
+ wc.stop();
+ QAD_MessageBox::warn1(QAD_Application::getDesktop(),
+ tr( "SMESH_WRN_WARNING" ),
+ tr(QString("SMESH_HYP_%1").arg(res)),
+ tr( "SMESH_BUT_OK" ) );
+ wc.start();
+ }
+ }
+ }
+ catch( const SALOME::SALOME_Exception& S_ex ) {
+ wc.stop();
+ QtCatchCorbaException( S_ex );
+ res = SMESH::HYP_UNKNOWN_FATAL;
+ }
+ }
+ return res < SMESH::HYP_UNKNOWN_FATAL;
}
//=============================================================================
*
*/
//=============================================================================
-void SMESHGUI::CreateNbSegments(QString TypeHypothesis, QString NameHypothesis,
- int nbSegments)
+bool SMESHGUI::AddAlgorithmOnSubMesh( SMESH::SMESH_subMesh_ptr aSubMesh,
+ SMESH::SMESH_Hypothesis_ptr aHyp )
{
- QApplication::setOverrideCursor(Qt::waitCursor);
- try
- {
- SMESH::SMESH_Hypothesis_var Hyp =
- SMESH::SMESH_Hypothesis::_narrow(CreateHypothesis(TypeHypothesis,
- NameHypothesis));
- SMESH::SMESH_NumberOfSegments_var NbS =
- SMESH::SMESH_NumberOfSegments::_narrow(Hyp);
- if (!NbS->_is_nil())
- NbS->SetNumberOfSegments(nbSegments);
- }
- catch(const SALOME::SALOME_Exception & S_ex)
- {
- QtCatchCorbaException(S_ex);
- }
- myActiveStudy->updateObjBrowser(true);
- QApplication::restoreOverrideCursor();
+ int res = SMESH::HYP_UNKNOWN_FATAL;
+ QAD_WaitCursor wc;
+
+ if ( !aSubMesh->_is_nil() ) {
+ try {
+ SMESH::SMESH_Mesh_var aMesh = aSubMesh->GetFather();
+ SALOMEDS::SObject_var SsubM = myStudyAPI.FindObject(aSubMesh);
+ GEOM::GEOM_Shape_var aShape = myStudyAPI.GetShapeOnMeshOrSubMesh(SsubM);
+ if ( !aMesh->_is_nil() && !SsubM->_is_nil() && !aShape->_is_nil() ) {
+ res = aMesh->AddHypothesis( aShape, aHyp );
+ if ( res < SMESH::HYP_UNKNOWN_FATAL ) {
+ //SALOMEDS::SObject_var SH = myStudyAPI.FindObject(aHyp);
+ //if (!SsubM->_is_nil() && !SH->_is_nil()) {
+ //myStudyAPI.SetAlgorithms(SsubM, SH);
+ myStudyAPI.ModifiedMesh( SsubM, false );
+ //}
+ }
+ if ( res >= SMESH::HYP_UNKNOWN_FATAL ) {
+ wc.stop();
+ QAD_MessageBox::error1(QAD_Application::getDesktop(),
+ tr("SMESH_ERROR"),
+ tr(QString("SMESH_HYP_%1").arg(res)),
+ tr("SMESH_BUT_OK"));
+ wc.start();
+ }
+ else if ( res > SMESH::HYP_OK ) {
+ wc.stop();
+ QAD_MessageBox::warn1(QAD_Application::getDesktop(),
+ tr( "SMESH_WRN_WARNING" ),
+ tr(QString("SMESH_HYP_%1").arg(res)),
+ tr( "SMESH_BUT_OK" ) );
+ wc.start();
+ }
+ }
+ }
+ catch( const SALOME::SALOME_Exception& S_ex ) {
+ wc.stop();
+ QtCatchCorbaException( S_ex );
+ res = SMESH::HYP_UNKNOWN_FATAL;
+ }
+ }
+ return res < SMESH::HYP_UNKNOWN_FATAL;
}
//=============================================================================
*
*/
//=============================================================================
-int SMESHGUI::GetNameOfSelectedNodes(SALOME_Selection * Sel, QString & aName)
-{
- int nbNodes = 0;
- int nbSel = Sel->IObjectCount();
- if (nbSel == 1)
- {
- Handle(SALOME_InteractiveObject) IObject = Sel->firstIObject();
- if (!IObject->hasEntry())
- return -1;
-
- Standard_Boolean res;
- SMESH_Actor *ac = FindActorByEntry(IObject->getEntry(), res, true);
- if (!res)
- return -1;
-
- TColStd_MapOfInteger MapIndex;
- Sel->GetIndex(IObject, MapIndex);
- TColStd_MapIteratorOfMapOfInteger ite(MapIndex);
- aName = " ";
- nbNodes = MapIndex.Extent();
- for (; ite.More(); ite.Next())
- {
- aName =
- aName + QString("%1").arg(ac->GetIdSMESHDSNode(ite.Key())) +
- " ";
- }
- }
- else
- {
- aName = "";
- }
- return nbNodes;
+int SMESHGUI::GetNameOfSelectedNodes(SALOME_Selection * Sel, QString & aName){
+ aName = "";
+ if(Sel->IObjectCount() == 1){
+ Handle(SALOME_InteractiveObject) IObject = Sel->firstIObject();
+ if(IObject->hasEntry()){
+ if(SMESH_Actor *anActor = ::FindActorByEntry(IObject->getEntry())){
+ TColStd_MapOfInteger MapIndex;
+ Sel->GetIndex(IObject, MapIndex);
+ TColStd_MapIteratorOfMapOfInteger ite(MapIndex);
+ for(; ite.More(); ite.Next()){
+ aName += QString(" %1").arg(anActor->GetNodeObjId(ite.Key()));
+ }
+ return MapIndex.Extent();
+ }
+ }
+ }
+ return -1;
}
//=============================================================================
*
*/
//=============================================================================
-int SMESHGUI::GetNameOfSelectedElements(SALOME_Selection * Sel, QString & aName)
-{
- int nbElements = 0;
- int nbSel = Sel->IObjectCount();
- if (nbSel == 1)
- {
- Handle(SALOME_InteractiveObject) IObject = Sel->firstIObject();
- if (!IObject->hasEntry())
- return -1;
+int SMESHGUI::GetNameOfSelectedElements(SALOME_Selection * Sel, QString & aName){
+ aName = "";
+ if(Sel->IObjectCount() == 1){
+ Handle(SALOME_InteractiveObject) IObject = Sel->firstIObject();
+ if(IObject->hasEntry()){
+ if(SMESH_Actor *anActor = ::FindActorByEntry(IObject->getEntry())){
+ TColStd_MapOfInteger MapIndex;
+ Sel->GetIndex(IObject, MapIndex);
+ TColStd_MapIteratorOfMapOfInteger ite(MapIndex);
+ std::vector<int> aList;
+ for(; ite.More(); ite.Next()){
+ int aVtkId = ite.Key();
+ int anObjId = anActor->GetElemObjId(aVtkId);
+ std::vector<int>::iterator found = find(aList.begin(), aList.end(), anObjId);
+ // MESSAGE("GetNameOfSelectedElements(): VTK Id = " << aVtkId << ", OBJECT Id = " << anObjId);
+ if (found == aList.end()) {
+ aList.push_back(anObjId);
+ aName += QString(" %1").arg(anObjId);
+ }
+ }
+ return aList.size();
+ }
+ }
+ }
+ return -1;
+}
- Standard_Boolean res;
- SMESH_Actor *ac = FindActorByEntry(IObject->getEntry(), res, true);
- if (!res)
- return -1;
- TColStd_MapOfInteger MapIndex;
- Sel->GetIndex(IObject, MapIndex);
- TColStd_MapIteratorOfMapOfInteger ite(MapIndex);
- aName = " ";
- nbElements = MapIndex.Extent();
- MESSAGE("GetNameOfSelectedElements(): number = " << nbElements);
- for (; ite.More(); ite.Next())
- {
- int idVTK = ite.Key();
- MESSAGE("GetNameOfSelectedElements(): VTK Id = " << idVTK);
- aName =
- aName + QString("%1").arg(ac->GetIdSMESHDSElement(idVTK)) + " ";
- }
- }
- else
- {
- aName = "";
- }
- return nbElements;
+//=============================================================================
+/*!
+ *
+ */
+//=============================================================================
+int SMESHGUI::GetNameOfSelectedEdges(SALOME_Selection * Sel, QString & aName){
+ aName = "";
+ if(Sel->IObjectCount() == 1){
+ Handle(SALOME_InteractiveObject) IObject = Sel->firstIObject();
+ if(IObject->hasEntry()){
+ if(SMESH_Actor *anActor = ::FindActorByEntry(IObject->getEntry())){
+ TColStd_MapOfInteger MapIndex;
+ Sel->GetIndex(IObject, MapIndex);
+ TColStd_MapIteratorOfMapOfInteger ite(MapIndex);
+ for(; ite.More(); ite.Next()){
+ aName += QString(" %1").arg(ite.Key());
+ }
+ return MapIndex.Extent();
+ }
+ }
+ }
+ return -1;
}
+
//=============================================================================
/*!
*
*/
//=============================================================================
-int SMESHGUI::GetNameOfSelectedEdges(SALOME_Selection * Sel, QString & aName)
+SMESH_Actor *SMESHGUI::FindActorByEntry(QString theEntry,
+ Standard_Boolean & theResult,
+ bool onlyInActiveView)
{
- int nbElements = 0;
- int nbSel = Sel->IObjectCount();
- if (nbSel == 1)
- {
- Handle(SALOME_InteractiveObject) IObject = Sel->firstIObject();
- if (!IObject->hasEntry())
- return -1;
-
- Standard_Boolean res;
- SMESH_Actor *ac = FindActorByEntry(IObject->getEntry(), res, true);
- if (!res)
- return -1;
-
- TColStd_MapOfInteger MapIndex;
- Sel->GetIndex(IObject, MapIndex);
- TColStd_MapIteratorOfMapOfInteger ite(MapIndex);
- aName = " ";
- nbElements = MapIndex.Extent();
- for (; ite.More(); ite.Next())
- {
- aName = aName + QString("%1").arg(ite.Key()) + " ";
- }
- }
- else
- {
- aName = "";
- }
- return nbElements;
+ theResult = false;
+ int aNbStudyFrames = myActiveStudy->getStudyFramesCount();
+ for (int i = 0; i < aNbStudyFrames; i++){
+ QAD_StudyFrame *aStudyFrame = myActiveStudy->getStudyFrame(i);
+ if(SMESH_Actor *anActor = ::FindActorByEntry(aStudyFrame,theEntry.latin1())){
+ theResult = true;
+ return anActor;
+ }
+ }
+ return NULL;
}
//=============================================================================
*
*/
//=============================================================================
-SMESH_Actor *SMESHGUI::FindActorByEntry(QString entry,
- Standard_Boolean & testResult, bool onlyInActiveView)
+SMESH_Actor* SMESHGUI::FindActor(CORBA::Object_ptr theObj,
+ Standard_Boolean & theResult,
+ bool theOnlyInActiveView)
{
- int nbSf = myActiveStudy->getStudyFramesCount();
- for (int i = 0; i < nbSf; i++)
- {
- QAD_StudyFrame *sf = myActiveStudy->getStudyFrame(i);
- if (sf->getTypeView() == VIEW_VTK)
- {
- vtkRenderer *Renderer =
- ((VTKViewer_ViewFrame *) sf->getRightFrame()->getViewFrame())->
- getRenderer();
- vtkActorCollection *theActors = Renderer->GetActors();
- theActors->InitTraversal();
- vtkActor *ac = theActors->GetNextActor();
- while (!(ac == NULL))
- {
- if (ac->IsA("SMESH_Actor"))
- {
- SMESH_Actor *anActor = SMESH_Actor::SafeDownCast(ac);
- if (anActor->hasIO())
- {
- Handle(SALOME_InteractiveObject) IO = anActor->getIO();
- if (strcmp(IO->getEntry(), entry) == 0)
- {
- if (onlyInActiveView)
- {
- if (sf == myActiveStudy->getActiveStudyFrame())
- {
- testResult = true;
- return anActor;
- }
- }
- else
- {
- testResult = true;
- return anActor;
- }
- }
- }
- }
- ac = theActors->GetNextActor();
- }
- }
- }
-
- MESSAGE(" Actor Not Found ") testResult = false;
- return SMESH_Actor::New();
+ theResult = false;
+ SMESH_Actor* aRes = NULL;
+ if ( !CORBA::is_nil( theObj ) ) {
+ SALOMEDS::SObject_var aSObject = SALOMEDS::SObject::_narrow( myStudy->FindObjectIOR( _orb->object_to_string( theObj ) ) );
+ if( !aSObject->_is_nil()) {
+ CORBA::String_var anEntry = aSObject->GetID();
+ aRes = FindActorByEntry( anEntry.in(), theResult, theOnlyInActiveView );
+ }
+ }
+ return aRes;
}
//=============================================================================
*
*/
//=============================================================================
-SMESH_Actor *SMESHGUI::FindActor(SMESH::SMESH_Mesh_ptr aMesh,
- Standard_Boolean & testResult, bool onlyInActiveView)
+SMESH::SMESH_Mesh_ptr SMESHGUI::ConvertIOinMesh(const Handle(SALOME_InteractiveObject) & IO,
+ Standard_Boolean & testResult)
{
- SALOMEDS::SObject_var SM = myStudyAPI.FindMesh(aMesh);
- if (SM->_is_nil())
- {
- MESSAGE(" Actor Not Found ") testResult = false;
- return SMESH_Actor::New();
- }
-
- return FindActorByEntry(SM->GetID(), testResult, onlyInActiveView);
+ SMESH::SMESH_Mesh_var aMesh;
+ testResult = false;
+
+ /* case SObject */
+ if (IO->hasEntry())
+ {
+ SALOMEDS::SObject_var obj = myStudy->FindObjectID(IO->getEntry());
+ SALOMEDS::GenericAttribute_var anAttr;
+ SALOMEDS::AttributeIOR_var anIOR;
+ if (!obj->_is_nil())
+ {
+ if (obj->FindAttribute(anAttr, "AttributeIOR"))
+ {
+ anIOR = SALOMEDS::AttributeIOR::_narrow(anAttr);
+ aMesh =
+ SMESH::SMESH_Mesh::_narrow(_orb->string_to_object(anIOR->Value()));
+ if (!aMesh->_is_nil())
+ {
+ testResult = true;
+ return SMESH::SMESH_Mesh::_duplicate(aMesh);
+ }
+ }
+ }
+ }
+ return SMESH::SMESH_Mesh::_nil();
}
//=============================================================================
*
*/
//=============================================================================
-SMESH::SMESH_Mesh_ptr SMESHGUI::
-ConvertIOinMesh(const Handle(SALOME_InteractiveObject) & IO,
- Standard_Boolean & testResult)
+SMESH::SMESH_subMesh_ptr SMESHGUI::ConvertIOinSubMesh(const Handle(SALOME_InteractiveObject) & IO,
+ Standard_Boolean & testResult)
{
- SMESH::SMESH_Mesh_var aMesh;
- testResult = false;
-
- /* case SObject */
- if (IO->hasEntry())
- {
- SALOMEDS::SObject_var obj = myStudy->FindObjectID(IO->getEntry());
- SALOMEDS::GenericAttribute_var anAttr;
- SALOMEDS::AttributeIOR_var anIOR;
- if (!obj->_is_nil())
- {
- if (obj->FindAttribute(anAttr, "AttributeIOR"))
- {
- anIOR = SALOMEDS::AttributeIOR::_narrow(anAttr);
- aMesh =
- SMESH::SMESH_Mesh::_narrow(_orb->string_to_object(anIOR->
- Value()));
- if (!aMesh->_is_nil())
- {
- testResult = true;
- return SMESH::SMESH_Mesh::_duplicate(aMesh);
- }
- }
- }
- }
- return SMESH::SMESH_Mesh::_nil();
+ SMESH::SMESH_subMesh_var aSubMesh;
+ testResult = false;
+
+ /* case SObject */
+ if (IO->hasEntry())
+ {
+ SALOMEDS::SObject_var obj = myStudy->FindObjectID(IO->getEntry());
+ SALOMEDS::GenericAttribute_var anAttr;
+ SALOMEDS::AttributeIOR_var anIOR;
+ if (!obj->_is_nil())
+ {
+ if (obj->FindAttribute(anAttr, "AttributeIOR"))
+ {
+ anIOR = SALOMEDS::AttributeIOR::_narrow(anAttr);
+ aSubMesh = SMESH::SMESH_subMesh::_narrow(_orb->string_to_object(anIOR->Value()));
+ if (!aSubMesh->_is_nil())
+ {
+ testResult = true;
+ return SMESH::SMESH_subMesh::_duplicate(aSubMesh);
+ }
+ }
+ }
+ }
+ return SMESH::SMESH_subMesh::_nil();
}
//=============================================================================
*
*/
//=============================================================================
-SMESH::SMESH_subMesh_ptr SMESHGUI::
-ConvertIOinSubMesh(const Handle(SALOME_InteractiveObject) & IO,
- Standard_Boolean & testResult)
+SMESH::SMESH_Hypothesis_ptr SMESHGUI::ConvertIOinSMESHHypothesis(const Handle(SALOME_InteractiveObject) & IO,
+ Standard_Boolean & testResult)
{
- SMESH::SMESH_subMesh_var aSubMesh;
- testResult = false;
-
- /* case SObject */
- if (IO->hasEntry())
- {
- SALOMEDS::SObject_var obj = myStudy->FindObjectID(IO->getEntry());
- SALOMEDS::GenericAttribute_var anAttr;
- SALOMEDS::AttributeIOR_var anIOR;
- if (!obj->_is_nil())
- {
- if (obj->FindAttribute(anAttr, "AttributeIOR"))
- {
- anIOR = SALOMEDS::AttributeIOR::_narrow(anAttr);
- aSubMesh =
- SMESH::SMESH_subMesh::_narrow(_orb->string_to_object(anIOR->
- Value()));
- if (!aSubMesh->_is_nil())
- {
- testResult = true;
- return SMESH::SMESH_subMesh::_duplicate(aSubMesh);
- }
- }
- }
- }
- return SMESH::SMESH_subMesh::_nil();
+ SMESH::SMESH_Hypothesis_var aHyp;
+ testResult = false;
+
+ /* case SObject */
+ if (IO->hasEntry())
+ {
+ SALOMEDS::SObject_var obj = myStudy->FindObjectID(IO->getEntry());
+ SALOMEDS::GenericAttribute_var anAttr;
+ SALOMEDS::AttributeIOR_var anIOR;
+ if (!obj->_is_nil())
+ {
+ if (obj->FindAttribute(anAttr, "AttributeIOR"))
+ {
+ anIOR = SALOMEDS::AttributeIOR::_narrow(anAttr);
+ aHyp = SMESH::SMESH_Hypothesis::_narrow(_orb->string_to_object(anIOR->Value()));
+ if (!aHyp->_is_nil())
+ {
+ testResult = true;
+ return SMESH::SMESH_Hypothesis::_duplicate(aHyp);
+ }
+ }
+ }
+ }
+ return SMESH::SMESH_Hypothesis::_nil();
}
//=============================================================================
*
*/
//=============================================================================
-SMESH::SMESH_Hypothesis_ptr SMESHGUI::
-ConvertIOinSMESHHypothesis(const Handle(SALOME_InteractiveObject) & IO,
- Standard_Boolean & testResult)
+SMESH::SMESH_Group_ptr SMESHGUI::ConvertIOinSMESHGroup(const Handle(SALOME_InteractiveObject) & IO,
+ Standard_Boolean & testResult)
{
- SMESH::SMESH_Hypothesis_var aHyp;
- testResult = false;
-
- /* case SObject */
- if (IO->hasEntry())
- {
- SALOMEDS::SObject_var obj = myStudy->FindObjectID(IO->getEntry());
- SALOMEDS::GenericAttribute_var anAttr;
- SALOMEDS::AttributeIOR_var anIOR;
- if (!obj->_is_nil())
- {
- if (obj->FindAttribute(anAttr, "AttributeIOR"))
- {
- anIOR = SALOMEDS::AttributeIOR::_narrow(anAttr);
- aHyp =
- SMESH::SMESH_Hypothesis::_narrow(_orb->
- string_to_object(anIOR->Value()));
- if (!aHyp->_is_nil())
- {
- testResult = true;
- return SMESH::SMESH_Hypothesis::_duplicate(aHyp);
- }
- }
- }
- }
- return SMESH::SMESH_Hypothesis::_nil();
+ SMESH::SMESH_Group_var aGroup;
+ testResult = false;
+
+ /* case SObject */
+ if (IO->hasEntry()) {
+ SALOMEDS::SObject_var obj = myStudy->FindObjectID(IO->getEntry());
+ SALOMEDS::GenericAttribute_var anAttr;
+ SALOMEDS::AttributeIOR_var anIOR;
+ if (!obj->_is_nil()) {
+ if (obj->FindAttribute(anAttr, "AttributeIOR")) {
+ anIOR = SALOMEDS::AttributeIOR::_narrow(anAttr);
+ aGroup = SMESH::SMESH_Group::_narrow(_orb->string_to_object(anIOR->Value()));
+ if (!aGroup->_is_nil()) {
+ testResult = true;
+ return SMESH::SMESH_Group::_duplicate(aGroup);
+ }
+ }
+ }
+ }
+ return SMESH::SMESH_Group::_nil();
}
//=============================================================================
*
*/
//=============================================================================
-GEOM::GEOM_Shape_ptr SMESHGUI::
-ConvertIOinGEOMShape(const Handle(SALOME_InteractiveObject) & IO,
- Standard_Boolean & testResult)
+GEOM::GEOM_Shape_ptr SMESHGUI::ConvertIOinGEOMShape(const Handle(SALOME_InteractiveObject) & IO,
+ Standard_Boolean & testResult)
{
- GEOM::GEOM_Shape_var aShape;
- testResult = false;
-
- /* case SObject */
- if (IO->hasEntry())
- {
- SALOMEDS::SObject_var obj = myStudy->FindObjectID(IO->getEntry());
- SALOMEDS::GenericAttribute_var anAttr;
- SALOMEDS::AttributeIOR_var anIOR;
- if (!obj->_is_nil())
- {
- if (obj->FindAttribute(anAttr, "AttributeIOR"))
- {
- anIOR = SALOMEDS::AttributeIOR::_narrow(anAttr);
- aShape = myComponentGeom->GetIORFromString(anIOR->Value());
- if (!aShape->_is_nil())
- {
- testResult = true;
- return GEOM::GEOM_Shape::_duplicate(aShape);
- }
- }
- }
- }
- return GEOM::GEOM_Shape::_nil();
+ GEOM::GEOM_Shape_var aShape;
+ testResult = false;
+
+ /* case SObject */
+ if (IO->hasEntry()) {
+ SALOMEDS::SObject_var obj = myStudy->FindObjectID(IO->getEntry());
+ SALOMEDS::GenericAttribute_var anAttr;
+ SALOMEDS::AttributeIOR_var anIOR;
+ if (!obj->_is_nil()) {
+ if (obj->FindAttribute(anAttr, "AttributeIOR")) {
+ anIOR = SALOMEDS::AttributeIOR::_narrow(anAttr);
+ aShape = myComponentGeom->GetIORFromString(anIOR->Value());
+ if (!aShape->_is_nil()) {
+ testResult = true;
+ return GEOM::GEOM_Shape::_duplicate(aShape);
+ }
+ }
+ }
+ }
+ return GEOM::GEOM_Shape::_nil();
}
//=============================================================================
*
*/
//=============================================================================
-void SMESHGUI::SetViewMode(int commandId)
-{
- SALOME_Selection *Sel =
- SALOME_Selection::Selection(myActiveStudy->getSelection());
- int nbSel = Sel->IObjectCount();
- if (nbSel >= 1)
- {
- SALOME_ListIteratorOfListIO It(Sel->StoredIObjects());
- for (; It.More(); It.Next())
- {
- Handle(SALOME_InteractiveObject) IObject = It.Value();
- if (IObject->hasEntry())
- {
- Standard_Boolean res;
- SMESH_Actor *ac =
- FindActorByEntry(IObject->getEntry(), res, true);
- if (res)
- {
- switch (commandId)
- {
- case 211:
- {
- ChangeRepresentation(ac, 0);
- break;
- }
- case 212:
- {
- ChangeRepresentation(ac, 1);
- break;
- }
- case 213:
- {
- ChangeRepresentation(ac, 2);
- break;
- }
- case 1132:
- {
- ChangeRepresentation(ac, 3);
- break;
- }
- }
- }
- }
- }
- if (commandId == 1133)
- {
- ChangeRepresentation(SMESH_Actor::New(), 4);
- }
- }
+void SMESHGUI::SetViewMode(int commandId){
+ SALOME_Selection *Sel = SALOME_Selection::Selection(myActiveStudy->getSelection());
+ if(Sel->IObjectCount() >= 1){
+ SALOME_ListIteratorOfListIO It(Sel->StoredIObjects());
+ for(; It.More(); It.Next()){
+ Handle(SALOME_InteractiveObject) IObject = It.Value();
+ if(IObject->hasEntry()){
+ if(SMESH_Actor *anActor = ::FindActorByEntry(IObject->getEntry())){
+ switch(commandId){
+ case 211:
+ ChangeRepresentation(anActor,0);
+ break;
+ case 212:
+ ChangeRepresentation(anActor,1);
+ break;
+ case 213:
+ ChangeRepresentation(anActor,2);
+ break;
+ case 215:
+ ChangeRepresentation(anActor,5);
+ break;
+ case 1132:
+ ChangeRepresentation(anActor,3);
+ break;
+ }
+ }
+ }
+ }
+ if(commandId == 1133)
+ ChangeRepresentation(NULL,4);
+ }
}
//=============================================================================
*
*/
//=============================================================================
-void SMESHGUI::ChangeRepresentation(SMESH_Actor * ac, int type)
-{
- if (ac->DataSource == NULL && type != 4)
- return;
-
- if (type != 4)
- {
- if (ac->getMapper() == NULL)
- {
- return;
- }
- }
- switch (type)
- {
- case 0:
- {
- QApplication::setOverrideCursor(Qt::waitCursor);
- if (ac->getDisplayMode() == 2)
- {
- bool isColored = ac->getMapper()->GetScalarVisibility(); //SAL3899
- vtkDataSetMapper *meshMapper =
- (vtkDataSetMapper *) (ac->getMapper());
- meshMapper->SetInput(ac->DataSource);
- meshMapper->SetScalarVisibility(isColored); //SAL3899
- }
- ac->setDisplayMode(0);
- ac->GetProperty()->SetRepresentationToWireframe();
- // ac->SetActorProperty( ac->GetProperty() );
- QApplication::restoreOverrideCursor();
- break;
- }
- case 1:
- {
- QApplication::setOverrideCursor(Qt::waitCursor);
- if (ac->getDisplayMode() == 2)
- {
- bool isColored = ac->getMapper()->GetScalarVisibility(); //SAL3899
- vtkDataSetMapper *meshMapper =
- (vtkDataSetMapper *) (ac->getMapper());
- meshMapper->SetInput(ac->DataSource);
- meshMapper->SetScalarVisibility(isColored); //SAL3899
- }
- ac->setDisplayMode(1);
- ac->GetProperty()->SetRepresentationToSurface();
- QApplication::restoreOverrideCursor();
- // ac->SetActorProperty( ac->GetProperty() );
- break;
- }
- case 2:
- {
- // if (!(ac->getDisplayMode()==2)) {
- // ChangeRepresentation(ac, 1);
- QApplication::setOverrideCursor(Qt::waitCursor);
- ac->setDisplayMode(2);
- bool isColored = ac->getMapper()->GetScalarVisibility(); //SAL3899
- vtkDataSetMapper *meshMapper = (vtkDataSetMapper *) (ac->getMapper());
- vtkShrinkFilter *shrink = vtkShrinkFilter::New();
- shrink->SetInput(ac->DataSource);
- shrink->SetShrinkFactor(ac->GetShrinkFactor());
-
- meshMapper->SetInput(shrink->GetOutput());
- meshMapper->SetScalarVisibility(isColored); //SAL3899
- ac->SetMapper(meshMapper);
- QApplication::restoreOverrideCursor();
- // }
- break;
- }
- case 3:
- {
- float color[3];
- float edgecolor[3];
- float backfacecolor[3];
- float nodecolor[3];
- ac->GetColor(color[0], color[1], color[2]);
-// QColor c(color[0]*255,color[1]*255,color[2]*255);
- int c0 = int (color[0] * 255);
- int c1 = int (color[1] * 255);
- int c2 = int (color[2] * 255);
- QColor c(c0, c1, c2);
- ac->GetEdgeColor(edgecolor[0], edgecolor[1], edgecolor[2]);
-// QColor e(edgecolor[0]*255,edgecolor[1]*255,edgecolor[2]*255);
- c0 = int (edgecolor[0] * 255);
- c1 = int (edgecolor[1] * 255);
- c2 = int (edgecolor[2] * 255);
- QColor e(c0, c1, c2);
- ac->GetBackfaceProperty()->GetColor(backfacecolor);
-// QColor b(backfacecolor[0]*255,backfacecolor[1]*255,backfacecolor[2]*255);
- c0 = int (backfacecolor[0] * 255);
- c1 = int (backfacecolor[1] * 255);
- c2 = int (backfacecolor[2] * 255);
- QColor b(c0, c1, c2);
- ac->GetNodeColor(nodecolor[0], nodecolor[1], nodecolor[2]);
-// QColor n(nodecolor[0]*255, nodecolor[1]*255, nodecolor[2]*255 ) ;
- c0 = int (nodecolor[0] * 255);
- c1 = int (nodecolor[1] * 255);
- c2 = int (nodecolor[2] * 255);
- QColor n(c0, c1, c2);
-
- int Edgewidth = (int)ac->EdgeDevice->GetProperty()->GetLineWidth();
- if (Edgewidth == 0)
- Edgewidth = 1;
- int intValue = ac->GetNodeSize();
- float Shrink = ac->GetShrinkFactor();
-
- SMESHGUI_Preferences_ColorDlg *aDlg =
- new SMESHGUI_Preferences_ColorDlg(QAD_Application::getDesktop(),
- "");
- aDlg->SetColor(1, c);
- aDlg->SetColor(2, e);
- aDlg->SetColor(3, n);
- aDlg->SetColor(4, b);
- aDlg->SetIntValue(1, Edgewidth);
- aDlg->SetIntValue(2, intValue);
- aDlg->SetIntValue(3, int (Shrink * 100.));
-
- if (aDlg->exec())
- {
- QApplication::setOverrideCursor(Qt::waitCursor);
- QColor color = aDlg->GetColor(1);
- QColor edgecolor = aDlg->GetColor(2);
- QColor nodecolor = aDlg->GetColor(3);
- QColor backfacecolor = aDlg->GetColor(4);
- /* actor color and backface color */
- ac->GetProperty()->SetColor(float (color.red()) / 255.,
- float (color.green()) / 255., float (color.blue()) / 255.);
- ac->SetColor(float (color.red()) / 255.,
- float (color.green()) / 255., float (color.blue()) / 255.);
- ac->GetBackfaceProperty()->SetColor(float (backfacecolor.red()) /
- 255., float (backfacecolor.green()) / 255.,
- float (backfacecolor.blue()) / 255.);
-
- /* edge color */
- ac->EdgeDevice->GetProperty()->SetColor(float (edgecolor.red()) /
- 255., float (edgecolor.green()) / 255.,
- float (edgecolor.blue()) / 255.);
- ac->EdgeShrinkDevice->GetProperty()->SetColor(float (edgecolor.
- red()) / 255., float (edgecolor.green()) / 255.,
- float (edgecolor.blue()) / 255.);
- ac->SetEdgeColor(float (edgecolor.red()) / 255.,
- float (edgecolor.green()) / 255.,
- float (edgecolor.blue()) / 255.);
-
- /* Shrink factor and size edges */
- ac->SetShrinkFactor(aDlg->GetIntValue(3) / 100.);
- ac->EdgeDevice->GetProperty()->SetLineWidth(aDlg->GetIntValue(1));
- ac->EdgeShrinkDevice->GetProperty()->SetLineWidth(aDlg->
- GetIntValue(1));
-
- /* Nodes color and size */
- ac->SetNodeColor(float (nodecolor.red()) / 255.,
- float (nodecolor.green()) / 255.,
- float (nodecolor.blue()) / 255.);
- ac->SetNodeSize(aDlg->GetIntValue(2));
-
- if (ac->getDisplayMode() == 2)
- {
- bool isColored = ac->getMapper()->GetScalarVisibility(); //SAL3899
- vtkDataSetMapper *meshMapper =
- (vtkDataSetMapper *) (ac->getMapper());
- meshMapper->SetInput(ac->DataSource);
- vtkShrinkFilter *shrink = vtkShrinkFilter::New();
- shrink->SetInput(meshMapper->GetInput());
- shrink->SetShrinkFactor(ac->GetShrinkFactor());
-
- meshMapper->SetInput(shrink->GetOutput());
- meshMapper->SetScalarVisibility(isColored); //SAL3899
- ac->SetMapper(meshMapper);
- }
- }
- delete aDlg;
- QApplication::restoreOverrideCursor();
- break;
- }
- case 4:
- {
- EmitSignalDeactivateDialog();
- SALOME_Selection *Sel =
- SALOME_Selection::Selection(myActiveStudy->getSelection());
- SMESHGUI_TransparencyDlg *aDlg =
- new SMESHGUI_TransparencyDlg(QAD_Application::getDesktop(), "",
- Sel);
- break;
- }
- case 5:
- {
- QApplication::setOverrideCursor(Qt::waitCursor);
- ac->GetProperty()->SetRepresentationToPoints();
- QApplication::restoreOverrideCursor();
- break;
- }
- }
-
- QApplication::setOverrideCursor(Qt::waitCursor);
- if (myActiveStudy->getActiveStudyFrame()->getTypeView() == VIEW_VTK)
- { //VTK
- vtkRenderer *theRenderer =
- ((VTKViewer_ViewFrame *) myActiveStudy->getActiveStudyFrame()->
- getRightFrame()->getViewFrame())->getRenderer();
- theRenderer->Render();
- }
- QApplication::restoreOverrideCursor();
+void SMESHGUI::ChangeRepresentation(SMESH_Actor * theActor, int type){
+ switch (type){
+ case 0:{
+ //theActor->UnShrink();
+ theActor->SetRepresentation(SMESH_Actor::eEdge);
+ break;
+ }
+ case 1:{
+ //theActor->UnShrink();
+ theActor->SetRepresentation(SMESH_Actor::eSurface);
+ break;
+ }
+ case 2:{
+ theActor->IsShrunk() ? theActor->UnShrink() : theActor->SetShrink();
+ //theActor->SetRepresentation(SMESH_Actor::eSurface);
+ break;
+ }
+ case 5:{
+ //theActor->UnShrink();
+ theActor->SetRepresentation(SMESH_Actor::ePoint);
+ break;
+ }
+ case 3:{
+ float color[3];
+ theActor->GetSufaceColor(color[0], color[1], color[2]);
+ int c0 = int (color[0] * 255);
+ int c1 = int (color[1] * 255);
+ int c2 = int (color[2] * 255);
+ QColor c(c0, c1, c2);
+
+ float edgecolor[3];
+ theActor->GetEdgeColor(edgecolor[0], edgecolor[1], edgecolor[2]);
+ c0 = int (edgecolor[0] * 255);
+ c1 = int (edgecolor[1] * 255);
+ c2 = int (edgecolor[2] * 255);
+ QColor e(c0, c1, c2);
+
+ float backfacecolor[3];
+ theActor->GetBackSufaceColor(backfacecolor[0], backfacecolor[1], backfacecolor[2]);
+ c0 = int (backfacecolor[0] * 255);
+ c1 = int (backfacecolor[1] * 255);
+ c2 = int (backfacecolor[2] * 255);
+ QColor b(c0, c1, c2);
+
+ float nodecolor[3];
+ theActor->GetNodeColor(nodecolor[0], nodecolor[1], nodecolor[2]);
+ c0 = int (nodecolor[0] * 255);
+ c1 = int (nodecolor[1] * 255);
+ c2 = int (nodecolor[2] * 255);
+ QColor n(c0, c1, c2);
+
+ int Edgewidth = (int)theActor->GetLineWidth();
+ if(Edgewidth == 0)
+ Edgewidth = 1;
+ int intValue = int(theActor->GetNodeSize());
+ float Shrink = theActor->GetShrinkFactor();
+
+ SMESHGUI_Preferences_ColorDlg *aDlg = new SMESHGUI_Preferences_ColorDlg(QAD_Application::getDesktop(),"");
+ aDlg->SetColor(1, c);
+ aDlg->SetColor(2, e);
+ aDlg->SetColor(3, n);
+ aDlg->SetColor(4, b);
+ aDlg->SetIntValue(1, Edgewidth);
+ aDlg->SetIntValue(2, intValue);
+ aDlg->SetIntValue(3, int(Shrink*100.));
+ if(aDlg->exec()){
+ QColor color = aDlg->GetColor(1);
+ QColor edgecolor = aDlg->GetColor(2);
+ QColor nodecolor = aDlg->GetColor(3);
+ QColor backfacecolor = aDlg->GetColor(4);
+ /* actor color and backface color */
+ theActor->SetSufaceColor(float (color.red()) / 255.,
+ float (color.green()) / 255.,
+ float (color.blue()) / 255.);
+ theActor->SetBackSufaceColor(float (backfacecolor.red()) / 255.,
+ float (backfacecolor.green()) / 255.,
+ float (backfacecolor.blue()) / 255.);
+
+ /* edge color */
+ theActor->SetEdgeColor(float (edgecolor.red()) / 255.,
+ float (edgecolor.green()) / 255.,
+ float (edgecolor.blue()) / 255.);
+
+ /* Shrink factor and size edges */
+ theActor->SetShrinkFactor(aDlg->GetIntValue(3) / 100.);
+ theActor->SetLineWidth(aDlg->GetIntValue(1));
+
+ /* Nodes color and size */
+ theActor->SetNodeColor(float (nodecolor.red()) / 255.,
+ float (nodecolor.green()) / 255.,
+ float (nodecolor.blue()) / 255.);
+ theActor->SetNodeSize(aDlg->GetIntValue(2));
+
+ delete aDlg;
+ }
+ break;
+ }
+ case 4:{
+ EmitSignalDeactivateDialog();
+ SMESHGUI_TransparencyDlg *aDlg = new SMESHGUI_TransparencyDlg(QAD_Application::getDesktop(),"",false);
+ break;
+ }
+ }
+ UpdateView();
}
//=============================================================================
*
*/
//=============================================================================
-void SMESHGUI::UpdateView()
-{
- if (myActiveStudy->getActiveStudyFrame()->getTypeView() != VIEW_VTK)
- return;
-
- vtkRenderer *theRenderer =
- ((VTKViewer_ViewFrame *) myActiveStudy->getActiveStudyFrame()->
- getRightFrame()->getViewFrame())->getRenderer();
- theRenderer->Render();
+void SMESHGUI::UpdateView(){
+ ::RepaintCurrentView();
}
//=============================================================================
*
*/
//=============================================================================
-void SMESHGUI::DisplayActor(SMESH_Actor * ac, bool visibility)
-{
- if (myActiveStudy->getActiveStudyFrame()->getTypeView() != VIEW_VTK)
- return;
-
- MESSAGE("DisplayActor(): DataSource = " << ac->DataSource);
-
- vtkRenderer *theRenderer =
- ((VTKViewer_ViewFrame *) myActiveStudy->getActiveStudyFrame()->
- getRightFrame()->getViewFrame())->getRenderer();
- vtkActorCollection *theActors = theRenderer->GetActors();
- theActors->InitTraversal();
- if (theActors->IsItemPresent(ac) == 0)
- {
- vtkProperty *prop = vtkProperty::New();
- prop->SetColor(QAD_CONFIG->getSetting("SMESH:SettingsFillColorRed").
- toFloat() / 255.,
- QAD_CONFIG->getSetting("SMESH:SettingsFillColorGreen").toFloat() /
- 255.,
- QAD_CONFIG->getSetting("SMESH:SettingsFillColorBlue").toFloat() /
- 255.);
-
- prop->SetPointSize(QAD_CONFIG->getSetting("SMESH:SettingsNodesSize").
- toInt());
- prop->SetLineWidth(QAD_CONFIG->getSetting("SMESH:SettingsWidth").
- toInt());
- ac->SetProperty(prop);
- ac->SetColor(QAD_CONFIG->getSetting("SMESH:SettingsFillColorRed").
- toFloat() / 255.,
- QAD_CONFIG->getSetting("SMESH:SettingsFillColorGreen").toFloat() /
- 255.,
- QAD_CONFIG->getSetting("SMESH:SettingsFillColorBlue").toFloat() /
- 255.);
-
- // prop->BackfaceCullingOn();
- vtkProperty *backprop = vtkProperty::New();
- backprop->SetColor(QAD_CONFIG->
- getSetting("SMESH:SettingsBackFaceColorRed").toFloat() / 255.,
- QAD_CONFIG->getSetting("SMESH:SettingsBackFaceColorGreen").
- toFloat() / 255.,
- QAD_CONFIG->getSetting("SMESH:SettingsBackFaceColorBlue").
- toFloat() / 255.);
- ac->SetBackfaceProperty(backprop);
-
- int intValue =
- QAD_CONFIG->getSetting("SMESH:SettingsShrinkCoeff").toInt();
- if (intValue == 0)
- intValue = 80;
- ac->SetShrinkFactor(intValue / 100.);
-
- ac->GetMapper()->SetResolveCoincidentTopologyToShiftZBuffer();
- ac->GetMapper()->SetResolveCoincidentTopologyZShift(0.02);
-
- QString DisplayMode = QAD_CONFIG->getSetting("SMESH:DisplayMode");
- if (DisplayMode.compare("Wireframe") == 0)
- {
- ac->setDisplayMode(0);
- ChangeRepresentation(ac, 0);
- }
- else if (DisplayMode.compare("Shading") == 0)
- {
- ac->setDisplayMode(1);
- ChangeRepresentation(ac, 1);
- }
- else if (DisplayMode.compare("Shrink") == 0)
- {
- ac->setDisplayMode(2);
- ChangeRepresentation(ac, 2);
- }
- theRenderer->AddActor(ac);
- }
- else
- {
- if (ac->GetMapper())
- ac->GetMapper()->Update();
- }
-
-// if ( visibility )
- ac->SetVisibility(visibility);
-// ac->VisibilityOn();
-// else
-// ac->VisibilityOff();
-
- vtkRenderWindow *renWin = theRenderer->GetRenderWindow();
- renWin->Render();
+void SMESHGUI::DisplayActor(SMESH_Actor * theActor, bool theVisibility){
+ theActor->SetVisibility(theVisibility);
+ ::DisplayActor(myActiveStudy->getActiveStudyFrame(),theActor);
}
//=============================================================================
*
*/
//=============================================================================
-void SMESHGUI::EraseActor(SMESH_Actor * ac)
-{
- if (myActiveStudy->getActiveStudyFrame()->getTypeView() != VIEW_VTK)
- return;
-
- vtkRenderer *theRenderer =
- ((VTKViewer_ViewFrame *) myActiveStudy->getActiveStudyFrame()->
- getRightFrame()->getViewFrame())->getRenderer();
-
- //NRI- : 02/12/2002 : Fixed bugId 882
- // ac->EdgeDevice->VisibilityOff();
- // ac->EdgeShrinkDevice->VisibilityOff();
- // ac->VisibilityOff();
- ac->SetVisibility(false);
-
- theRenderer->Render();
+void SMESHGUI::EraseActor(SMESH_Actor * theActor){
+ theActor->SetVisibility(false);
}
//=============================================================================
//=============================================================================
QString SMESHGUI::CheckTypeObject(const Handle(SALOME_InteractiveObject) & IO)
{
- SALOMEDS::SObject_var sobj =
- smeshGUI->myActiveStudy->getStudyDocument()->FindObjectID(IO->
- getEntry());
- if (!sobj->_is_nil())
- {
- SALOMEDS::SComponent_var scomp = sobj->GetFatherComponent();
- if (strcmp(scomp->GetID(), IO->getEntry()) == 0)
- { // component is selected
- return "Component";
- }
- }
-
- SALOME_Selection *Sel =
- SALOME_Selection::Selection(smeshGUI->myActiveStudy->getSelection());
- Sel->ClearIObjects();
-
- Handle(SMESH_TypeFilter) aHypFilter = new SMESH_TypeFilter(HYPOTHESIS);
- Handle(SMESH_TypeFilter) anAlgoFilter = new SMESH_TypeFilter(ALGORITHM);
- Handle(SMESH_TypeFilter) aMeshFilter = new SMESH_TypeFilter(MESH);
- Handle(SMESH_TypeFilter) aSubMeshFilter = new SMESH_TypeFilter(SUBMESH);
- Handle(SMESH_TypeFilter) aMeshOrSubMeshFilter =
- new SMESH_TypeFilter(MESHorSUBMESH);
- Handle(SMESH_TypeFilter) aSubMeshVextexFilter =
- new SMESH_TypeFilter(SUBMESH_VERTEX);
- Handle(SMESH_TypeFilter) aSubMeshEdgeFilter =
- new SMESH_TypeFilter(SUBMESH_EDGE);
- Handle(SMESH_TypeFilter) aSubMeshFaceFilter =
- new SMESH_TypeFilter(SUBMESH_FACE);
- Handle(SMESH_TypeFilter) aSubMeshSolidFilter =
- new SMESH_TypeFilter(SUBMESH_SOLID);
- Handle(SMESH_TypeFilter) aSubMeshCompoundFilter =
- new SMESH_TypeFilter(SUBMESH_COMPOUND);
-
- Sel->AddFilter(aHypFilter);
- if (Sel->AddIObject(IO) != -1)
- {
- Sel->ClearFilters();
- return "Hypothesis";
- }
-
- Sel->ClearFilters();
- Sel->AddFilter(anAlgoFilter);
- if (Sel->AddIObject(IO) != -1)
- {
- Sel->ClearFilters();
- return "Algorithm";
- }
-
- Sel->ClearFilters();
- Sel->AddFilter(aMeshFilter);
- if (Sel->AddIObject(IO) != -1)
- {
- Sel->ClearFilters();
- return "Mesh";
- }
-
- Sel->ClearFilters();
- Sel->AddFilter(aSubMeshFilter);
- if (Sel->AddIObject(IO) != -1)
- {
- Sel->ClearFilters();
- return "SubMesh";
- }
-
- Sel->ClearFilters();
- Sel->AddFilter(aSubMeshVextexFilter);
- if (Sel->AddIObject(IO) != -1)
- {
- Sel->ClearFilters();
- return "SubMeshVertex";
- }
-
- Sel->ClearFilters();
- Sel->AddFilter(aSubMeshEdgeFilter);
- if (Sel->AddIObject(IO) != -1)
- {
- Sel->ClearFilters();
- return "SubMeshEdge";
- }
-
- Sel->ClearFilters();
- Sel->AddFilter(aSubMeshFaceFilter);
- if (Sel->AddIObject(IO) != -1)
- {
- Sel->ClearFilters();
- return "SubMeshFace";
- }
+ SALOMEDS::SObject_var sobj = smeshGUI->myActiveStudy->getStudyDocument()->FindObjectID(IO->getEntry());
+ if (!sobj->_is_nil()) {
+ SALOMEDS::SComponent_var scomp = sobj->GetFatherComponent();
+ if (strcmp(scomp->GetID(), IO->getEntry()) == 0)
+ { // component is selected
+ return "Component";
+ }
+ }
+
+ SALOME_Selection *Sel = SALOME_Selection::Selection(smeshGUI->myActiveStudy->getSelection());
+ Sel->ClearIObjects();
+
+ Handle(SMESH_TypeFilter) aHypFilter = new SMESH_TypeFilter(HYPOTHESIS);
+ Handle(SMESH_TypeFilter) anAlgoFilter = new SMESH_TypeFilter(ALGORITHM);
+ Handle(SMESH_TypeFilter) aMeshFilter = new SMESH_TypeFilter(MESH);
+ Handle(SMESH_TypeFilter) aSubMeshFilter = new SMESH_TypeFilter(SUBMESH);
+ Handle(SMESH_TypeFilter) aGroupFilter = new SMESH_TypeFilter(GROUP);
+ Handle(SMESH_TypeFilter) aMeshOrSubMeshFilter = new SMESH_TypeFilter(MESHorSUBMESH);
+ Handle(SMESH_TypeFilter) aSubMeshVextexFilter = new SMESH_TypeFilter(SUBMESH_VERTEX);
+ Handle(SMESH_TypeFilter) aSubMeshEdgeFilter = new SMESH_TypeFilter(SUBMESH_EDGE);
+ Handle(SMESH_TypeFilter) aSubMeshFaceFilter = new SMESH_TypeFilter(SUBMESH_FACE);
+ Handle(SMESH_TypeFilter) aSubMeshSolidFilter = new SMESH_TypeFilter(SUBMESH_SOLID);
+ Handle(SMESH_TypeFilter) aSubMeshCompoundFilter = new SMESH_TypeFilter(SUBMESH_COMPOUND);
+
+ Sel->AddFilter(aHypFilter);
+ if (Sel->AddIObject(IO) != -1) {
+ Sel->ClearFilters();
+ return "Hypothesis";
+ }
+
+ Sel->ClearFilters();
+ Sel->AddFilter(anAlgoFilter);
+ if (Sel->AddIObject(IO) != -1) {
+ Sel->ClearFilters();
+ return "Algorithm";
+ }
+
+ Sel->ClearFilters();
+ Sel->AddFilter(aMeshFilter);
+ if (Sel->AddIObject(IO) != -1) {
+ Sel->ClearFilters();
+ return "Mesh";
+ }
+
+ Sel->ClearFilters();
+ Sel->AddFilter(aSubMeshFilter);
+ if (Sel->AddIObject(IO) != -1) {
+ Sel->ClearFilters();
+ return "SubMesh";
+ }
+
+ Sel->ClearFilters();
+ Sel->AddFilter(aGroupFilter);
+ if (Sel->AddIObject(IO) != -1) {
+ Sel->ClearFilters();
+ return "Group";
+ }
+
+ Sel->ClearFilters();
+ Sel->AddFilter(aSubMeshVextexFilter);
+ if (Sel->AddIObject(IO) != -1) {
+ Sel->ClearFilters();
+ return "SubMeshVertex";
+ }
+
+ Sel->ClearFilters();
+ Sel->AddFilter(aSubMeshEdgeFilter);
+ if (Sel->AddIObject(IO) != -1) {
+ Sel->ClearFilters();
+ return "SubMeshEdge";
+ }
+
+ Sel->ClearFilters();
+ Sel->AddFilter(aSubMeshFaceFilter);
+ if (Sel->AddIObject(IO) != -1) {
+ Sel->ClearFilters();
+ return "SubMeshFace";
+ }
+
+ Sel->ClearFilters();
+ Sel->AddFilter(aSubMeshSolidFilter);
+ if (Sel->AddIObject(IO) != -1) {
+ Sel->ClearFilters();
+ return "SubMeshSolid";
+ }
+
+ Sel->ClearFilters();
+ Sel->AddFilter(aSubMeshCompoundFilter);
+ if (Sel->AddIObject(IO) != -1) {
+ Sel->ClearFilters();
+ return "SubMeshCompound";
+ }
+
+ Sel->ClearFilters();
+ Sel->AddIObject(IO);
+ return "NoType";
+}
- Sel->ClearFilters();
- Sel->AddFilter(aSubMeshSolidFilter);
- if (Sel->AddIObject(IO) != -1)
- {
- Sel->ClearFilters();
- return "SubMeshSolid";
- }
- Sel->ClearFilters();
- Sel->AddFilter(aSubMeshCompoundFilter);
- if (Sel->AddIObject(IO) != -1)
- {
- Sel->ClearFilters();
- return "SubMeshCompound";
- }
+static int isStudyLocked(const SALOMEDS::Study_var& theStudy){
+ return theStudy->GetProperties()->IsLocked();
+}
- Sel->ClearFilters();
- Sel->AddIObject(IO);
- return "NoType";
+static int checkLock(const SALOMEDS::Study_var& theStudy) {
+ if (isStudyLocked(theStudy)) {
+ QAD_MessageBox::warn1 ( (QWidget*)QAD_Application::getDesktop(),
+ QObject::tr("WRN_WARNING"),
+ QObject::tr("WRN_STUDY_LOCKED"),
+ QObject::tr("BUT_OK") );
+ return true;
+ }
+ return false;
}
//=============================================================================
//=============================================================================
bool SMESHGUI::OnGUIEvent(int theCommandID, QAD_Desktop * parent)
{
- /* Create or retrieve an object SMESHGUI */
- SMESHGUI::GetOrCreateSMESHGUI(parent);
-
- // NRI : Temporary added
- if (smeshGUI->myStudy->GetProperties()->IsLocked())
- {
- return false;
+ SALOMEDS::Study_var aStudy = smeshGUI->myActiveStudy->getStudyDocument(); //Document OCAF de l'etude active
+ // QAD_Viewer3d* v3d;
+ OCCViewer_Viewer3d *v3d;
+
+ Handle(AIS_InteractiveContext) ic;
+ vtkRenderer *Renderer;
+ vtkRenderWindow *RenWin;
+
+ if (smeshGUI->myActiveStudy->getActiveStudyFrame()->getTypeView() == VIEW_OCC) {
+ v3d = ((OCCViewer_ViewFrame *) smeshGUI->myActiveStudy->
+ getActiveStudyFrame()->getRightFrame()->getViewFrame())->getViewer();
+ ic = v3d->getAISContext();
+ }
+ else if (smeshGUI->myActiveStudy->getActiveStudyFrame()->getTypeView() == VIEW_VTK) {
+ Renderer = ((VTKViewer_ViewFrame *) smeshGUI->myActiveStudy->
+ getActiveStudyFrame()->getRightFrame()->getViewFrame())->getRenderer();
+ RenWin = Renderer->GetRenderWindow();
+ }
+
+ switch (theCommandID) {
+ case 33: // DELETE
+ if(checkLock(aStudy)) break;
+ smeshGUI->OnEditDelete();
+ break;
+
+ case 113: // IMPORT
+ case 112:
+ case 111:
+ {
+ if(checkLock(aStudy)) break;
+ //Import_Document(parent, theCommandID); //NBU
+ Import_Mesh(parent,theCommandID);
+ break;
+ }
+
+ case 122: // EXPORT MED
+ case 121:
+ case 123:
+ {
+ Export_Mesh(parent, theCommandID);
+ break;
+ }
+
+ case 200: // SCALAR BAR
+ {
+ SALOME_Selection *Sel = SALOME_Selection::Selection( smeshGUI->myActiveStudy->getSelection() );
+ if( Sel && Sel->IObjectCount() ) {
+ Handle(SALOME_InteractiveObject) anIO = Sel->firstIObject();
+ if( anIO->hasEntry() ) {
+ if( SMESH_Actor* anActor = ::FindActorByEntry( anIO->getEntry() ) ) {
+ anActor->SetControlMode( SMESH_Actor::eNone );
+ }
+ }
+ }
+ break;
+ }
+ case 201:
+ {
+ SALOME_Selection* Sel = SALOME_Selection::Selection( smeshGUI->myActiveStudy->getSelection() );
+ SMESHGUI_Preferences_ScalarBarDlg::ScalarBarProperties( parent, Sel );
+ break;
+ }
+
+ case 1133: // DISPLAY MODE : WireFrame, Surface, Shrink
+ case 1132:
+ case 215:
+ case 213:
+ case 212:
+ case 211:
+ {
+ smeshGUI->SetViewMode(theCommandID);
+ break;
+ }
+
+ case 214: // UPDATE
+ {
+ if(checkLock(aStudy)) break;
+ smeshGUI->Update();
+ break;
+ }
+
+ case 300: // ERASE
+ case 301: // DISPLAY
+ case 302: // DISPLAY ONLY
+ {
+ EDisplaing anAction;
+ switch(theCommandID){
+ case 300: anAction = eErase; break;
+ case 301: anAction = eDisplay; break;
+ case 302: anAction = eDisplayOnly; break;
+ }
+
+ SALOME_Selection *Sel = SALOME_Selection::Selection(smeshGUI->myActiveStudy->getSelection());
+ if (smeshGUI->myActiveStudy->getActiveStudyFrame()->getTypeView() == VIEW_VTK) {
+ SALOME_ListIteratorOfListIO It(Sel->StoredIObjects());
+ for (; It.More(); It.Next()) {
+ Handle(SALOME_InteractiveObject) IOS = It.Value();
+ if (IOS->hasEntry()) {
+ ::UpdateView(anAction,IOS->getEntry());
+ }
+ }
+ }
+ Sel->ClearIObjects();
+ break;
+ }
+
+ case 400: // NODES
+ {
+ if(checkLock(aStudy)) break;
+ if (smeshGUI->myActiveStudy->getActiveStudyFrame()->getTypeView() == VIEW_VTK) {
+ smeshGUI->EmitSignalDeactivateDialog();
+ SALOME_Selection *Sel = SALOME_Selection::Selection(smeshGUI->myActiveStudy->getSelection());
+ Sel->ClearIObjects();
+ smeshGUI->myDesktop->SetSelectionMode(NodeSelection, true);
+ smeshGUI->ViewNodes();
+ SMESHGUI_NodesDlg *aDlg = new SMESHGUI_NodesDlg(parent, "", Sel);
+ }
+ else {
+ QAD_MessageBox::warn1(QAD_Application::getDesktop(),
+ tr("SMESH_WRN_WARNING"),
+ tr("SMESH_WRN_VIEWER_VTK"),
+ tr("SMESH_BUT_OK"));
+ }
+ break;
+ }
+
+ case 2151: // FILTER
+ {
+ if ( smeshGUI->myActiveStudy->getActiveStudyFrame()->getTypeView() == VIEW_VTK )
+ {
+ smeshGUI->EmitSignalDeactivateDialog();
+ SMESHGUI_FilterDlg *aDlg = new SMESHGUI_FilterDlg( parent, SMESH::EDGE );
+ }
+ break;
+ }
+
+ case 405: // MOVE NODE
+ {
+ if(checkLock(aStudy)) break;
+ smeshGUI->myDesktop->SetSelectionMode(NodeSelection, true);
+ SALOME_Selection *Sel = SALOME_Selection::Selection(smeshGUI->myActiveStudy->getSelection());
+ SMESHGUI_MoveNodesDlg *aDlg = new SMESHGUI_MoveNodesDlg(parent, "", Sel);
+ break;
+ }
+
+ case 701: // COMPUTE MESH
+ {
+ if(checkLock(aStudy)) break;
+ if (smeshGUI->myActiveStudy->getActiveStudyFrame()->getTypeView() == VIEW_VTK) {
+ SALOME_Selection *Sel = SALOME_Selection::Selection(smeshGUI->myActiveStudy->getSelection());
+ int nbSel = Sel->IObjectCount();
+ if (nbSel != 1){
+ break;
}
- //NRI
-
- // QAD_Viewer3d* v3d;
- OCCViewer_Viewer3d *v3d;
- Handle(AIS_InteractiveContext) ic;
- vtkRenderer *Renderer;
- vtkRenderWindow *RenWin;
-
- if (smeshGUI->myActiveStudy->getActiveStudyFrame()->getTypeView() ==
- VIEW_OCC)
+ SMESH::SMESH_Mesh_var aMesh;
+ SMESH::SMESH_subMesh_var aSubMesh;
+ Handle(SALOME_InteractiveObject) IObject = Sel->firstIObject();
+ if (IObject->hasEntry()){
+ SALOMEDS::SObject_var aMeshSObj = smeshGUI->myStudy->FindObjectID(IObject->getEntry());
+ GEOM::GEOM_Shape_var aShape = smeshGUI->myStudyAPI.GetShapeOnMeshOrSubMesh( aMeshSObj );
+ if ( aShape->_is_nil() ) {
+ // imported mesh
+ break;
+ }
+ SALOMEDS::GenericAttribute_var anAttr;
+ if(!aMeshSObj->_is_nil() && aMeshSObj->FindAttribute(anAttr, "AttributeIOR")){
+ SALOMEDS::AttributeIOR_var anIOR = SALOMEDS::AttributeIOR::_narrow(anAttr);
+ MESSAGE("SMESHGUI::OnGUIEvent - Compute mesh : IOR = "<< anIOR->Value());
+ CORBA::Object_var anObj;
+ try{
+ anObj = _orb->string_to_object(anIOR->Value());
+ if (CORBA::is_nil(anObj)){
+ MESSAGE("SMESHGUI::OnGUIEvent - Compute mesh : nil object");
+ }
+ }catch(CORBA::COMM_FAILURE & ex){
+ INFOS("SMESHGUI::OnGUIEvent - Compute mesh : exception (1)");
+ }
+ aMesh = SMESH::SMESH_Mesh::_narrow(anObj);
+ aSubMesh = SMESH::SMESH_subMesh::_narrow(anObj);
+ if (!aMesh->_is_nil()){
+ GEOM::GEOM_Shape_var refShape = smeshGUI->myStudyAPI.GetShapeOnMeshOrSubMesh(aMeshSObj);
+ if (!refShape->_is_nil()) {
+ if(!smeshGUI->myComponentMesh->IsReadyToCompute(aMesh,refShape)){
+ QAD_MessageBox::warn1(QAD_Application::getDesktop(),
+ tr("SMESH_WRN_WARNING"),
+ tr("SMESH_WRN_MISSING_PARAMETERS"),
+ tr("SMESH_BUT_OK"));
+ break;
+ }
+ try{
+ if (smeshGUI->myComponentMesh->Compute(aMesh,refShape))
+ smeshGUI->myStudyAPI.ModifiedMesh(aMeshSObj,true);
+ // TO Do : change icon of all submeshes
+ }
+ catch(const SALOME::SALOME_Exception & S_ex){
+ QtCatchCorbaException(S_ex);
+ }
+ }
+ }else if(!aSubMesh->_is_nil()){
+ aMesh = aSubMesh->GetFather();
+ GEOM::GEOM_Shape_var refShape = smeshGUI->myStudyAPI.GetShapeOnMeshOrSubMesh(aMeshSObj);
+ if(!refShape->_is_nil()){
+ bool compute = smeshGUI->myComponentMesh->IsReadyToCompute(aMesh,refShape);
+ if(!compute){
+ QAD_MessageBox::warn1(QAD_Application::getDesktop(),
+ tr("SMESH_WRN_WARNING"),
+ tr("SMESH_WRN_MISSING_PARAMETERS"),
+ tr("SMESH_BUT_OK"));
+ break;
+ }
+ try{
+ if ( smeshGUI->myComponentMesh->Compute(aMesh,refShape) )
+ smeshGUI->myStudyAPI.ModifiedMesh(aMeshSObj,true);
+ // TO Do : change icon of all submeshes
+ }catch(const SALOME::SALOME_Exception & S_ex){
+ QtCatchCorbaException(S_ex);
+ }
+ }
+ }
+ }
+ }
+ CORBA::Long anId = smeshGUI->myStudy->StudyId();
+ TVisualObjPtr aVisualObj = GetVisualObj(anId,IObject->getEntry());
+ if(smeshGUI->myAutomaticUpdate && aVisualObj){
+ aVisualObj->Update();
+ SMESH_Actor* anActor = ::FindActorByEntry(IObject->getEntry());
+ if(!anActor){
+ anActor = ::CreateActor(smeshGUI->myStudy,IObject->getEntry());
+ if(anActor){
+ ::DisplayActor(smeshGUI->myActiveStudy->getActiveStudyFrame(),anActor); //apo
+ ::FitAll();
+ }
+ }
+ }
+ }else{
+ QAD_MessageBox::warn1(QAD_Application::getDesktop(),
+ tr("SMESH_WRN_WARNING"),
+ tr("SMESH_WRN_VIEWER_VTK"),
+ tr("SMESH_BUT_OK"));
+ }
+ break;
+ }
+
+ case 702: // ADD SUB MESH
+ {
+ if(checkLock(aStudy)) break;
+ if (smeshGUI->myActiveStudy->getActiveStudyFrame()->getTypeView() == VIEW_VTK) {
+ smeshGUI->EmitSignalDeactivateDialog();
+ SALOME_Selection *Sel = SALOME_Selection::Selection(smeshGUI->myActiveStudy->getSelection());
+ SMESHGUI_AddSubMeshDlg *aDlg = new SMESHGUI_AddSubMeshDlg(parent, "", Sel);
+ }
+ else {
+ QAD_MessageBox::warn1(QAD_Application::getDesktop(),
+ tr("SMESH_WRN_WARNING"), tr("SMESH_WRN_VIEWER_VTK"),
+ tr("SMESH_BUT_OK"));
+ }
+ break;
+ }
+
+ case 703: // INIT MESH
+ {
+ if(checkLock(aStudy)) break;
+ smeshGUI->EmitSignalDeactivateDialog();
+ SALOME_Selection *Sel = SALOME_Selection::Selection(smeshGUI->myActiveStudy->getSelection());
+ SMESHGUI_InitMeshDlg *aDlg = new SMESHGUI_InitMeshDlg(parent, "", Sel);
+ break;
+ }
+
+ case 704: // EDIT Hypothesis
+ {
+ if(checkLock(aStudy)) break;
+ smeshGUI->EmitSignalDeactivateDialog();
+ SALOME_Selection *Sel = SALOME_Selection::Selection(smeshGUI->myActiveStudy->getSelection());
+ SMESHGUI_EditHypothesesDlg *aDlg = new SMESHGUI_EditHypothesesDlg(parent, "", Sel);
+ break;
+ }
+
+ case 705: // EDIT Global Hypothesis
+ {
+ if(checkLock(aStudy)) break;
+ smeshGUI->EmitSignalDeactivateDialog();
+ SALOME_Selection *Sel = SALOME_Selection::Selection(smeshGUI->myActiveStudy->getSelection());
+ SMESHGUI_EditHypothesesDlg *aDlg = new SMESHGUI_EditHypothesesDlg(parent, "", Sel);
+ break;
+ }
+
+ case 706: // EDIT Local Hypothesis
+ {
+ if(checkLock(aStudy)) break;
+ smeshGUI->EmitSignalDeactivateDialog();
+ SALOME_Selection *Sel = SALOME_Selection::Selection(smeshGUI->myActiveStudy->getSelection());
+ SMESHGUI_EditHypothesesDlg *aDlg = new SMESHGUI_EditHypothesesDlg(parent, "", Sel);
+ break;
+ }
+
+ case 406: // ORIENTATION ELEMENTS
+ {
+ if(checkLock(aStudy)) break;
+ smeshGUI->EmitSignalDeactivateDialog();
+ SALOME_Selection *Sel = SALOME_Selection::Selection(smeshGUI->myActiveStudy->getSelection());
+ smeshGUI->myDesktop->SetSelectionMode(FaceSelection, true);
+ SMESHGUI_OrientationElementsDlg *aDlg = new SMESHGUI_OrientationElementsDlg(parent, "", Sel);
+ break;
+ }
+
+ case 407: // DIAGONAL INVERSION
+ {
+ if(checkLock(aStudy)) break;
+ smeshGUI->EmitSignalDeactivateDialog();
+ SALOME_Selection *Sel = SALOME_Selection::Selection(smeshGUI->myActiveStudy->getSelection());
+ Sel->ClearIObjects();
+ smeshGUI->myDesktop->SetSelectionMode(EdgeOfCellSelection, true);
+ SMESHGUI_DiagonalInversionDlg *aDlg = new SMESHGUI_DiagonalInversionDlg(parent, "", Sel);
+ break;
+ }
+
+ case 801: // CREATE GROUP
+ {
+ if(checkLock(aStudy)) break;
+ smeshGUI->EmitSignalDeactivateDialog();
+ SALOME_Selection *Sel = SALOME_Selection::Selection(smeshGUI->myActiveStudy->getSelection());
+ int nbSel = Sel->IObjectCount();
+ if (nbSel == 1) {
+ // check if mesh is selected
+ Handle(SALOME_InteractiveObject) IObject = Sel->firstIObject();
+ if (IObject->hasEntry()) {
+ SALOMEDS::SObject_var aMeshSObj = smeshGUI->myStudy->FindObjectID(IObject->getEntry());
+ if (!aMeshSObj->_is_nil()) {
+ CORBA::Object_var anObj = aMeshSObj->GetObject();
+ SMESH::SMESH_Mesh_var aMesh = SMESH::SMESH_Mesh::_narrow(anObj);
+ SMESH::SMESH_subMesh_var aSubMesh = SMESH::SMESH_subMesh::_narrow(anObj);
+ if (aMesh->_is_nil() && !aSubMesh->_is_nil()) {
+ aMesh = aSubMesh->GetFather();
+ }
+ if (!aMesh->_is_nil()) {
+ SMESHGUI_GroupDlg *aDlg = new SMESHGUI_GroupDlg(parent, "", Sel, aMesh);
+ aDlg->show();
+ }
+ }
+ }
+ }
+ break;
+ }
+
+ case 802: // CONSTRUCT GROUP
+ {
+ if(checkLock(aStudy)) break;
+ smeshGUI->EmitSignalDeactivateDialog();
+ SALOME_Selection *Sel = SALOME_Selection::Selection(smeshGUI->myActiveStudy->getSelection());
+ int nbSel = Sel->IObjectCount();
+ if (nbSel == 1) {
+ // check if submesh is selected
+ Handle(SALOME_InteractiveObject) IObject = Sel->firstIObject();
+ if (IObject->hasEntry()) {
+ SALOMEDS::SObject_var aSObj = smeshGUI->myStudy->FindObjectID(IObject->getEntry());
+ if(!aSObj->_is_nil()) {
+ SMESH::SMESH_subMesh_var aSubMesh = SMESH::SMESH_subMesh::_narrow(aSObj->GetObject());
+ if (!aSubMesh->_is_nil()) {
+ try {
+ SMESH::SMESH_Mesh_var aMesh = aSubMesh->GetFather();
+ // get submesh elements list by types
+ SMESH::long_array_var aNodes = aSubMesh->GetElementsByType(SMESH::NODE);
+ SMESH::long_array_var aEdges = aSubMesh->GetElementsByType(SMESH::EDGE);
+ SMESH::long_array_var aFaces = aSubMesh->GetElementsByType(SMESH::FACE);
+ SMESH::long_array_var aVolumes = aSubMesh->GetElementsByType(SMESH::VOLUME);
+ // create group for each type o elements
+ QString aName = IObject->getName();
+ MESSAGE("SMESHGUI::OnGUIEvent - Construct group on submesh : "<<aName);
+ MESSAGE(" Number of elements : nodes "<<aNodes->length() << ", edges " << aEdges->length()
+ << ", faces " << aFaces->length() << ", volumes " << aVolumes->length());
+ if (aNodes->length() > 0) {
+ SMESH::SMESH_Group_var aGroup = smeshGUI->AddGroup(aMesh, SMESH::NODE, aName);
+ aGroup->Add(aNodes);
+ }
+ if (aEdges->length() > 0) {
+ SMESH::SMESH_Group_var aGroup = smeshGUI->AddGroup(aMesh, SMESH::EDGE, aName);
+ aGroup->Add(aEdges);
+ }
+ if (aFaces->length() > 0) {
+ SMESH::SMESH_Group_var aGroup = smeshGUI->AddGroup(aMesh, SMESH::FACE, aName);
+ aGroup->Add(aFaces);
+ }
+ if (aVolumes->length() > 0) {
+ SMESH::SMESH_Group_var aGroup = smeshGUI->AddGroup(aMesh, SMESH::VOLUME, aName);
+ aGroup->Add(aVolumes);
+ }
+ smeshGUI->myActiveStudy->updateObjBrowser(true);
+ }catch(const SALOME::SALOME_Exception & S_ex){
+ QtCatchCorbaException(S_ex);
+ }
+ }
+ }
+ }
+ }
+ break;
+ }
+
+ case 803: // EDIT GROUP
+ {
+ if(checkLock(aStudy)) break;
+ smeshGUI->EmitSignalDeactivateDialog();
+ SALOME_Selection *Sel = SALOME_Selection::Selection(smeshGUI->myActiveStudy->getSelection());
+ int nbSel = Sel->IObjectCount();
+ if (nbSel == 1) {
+ // check if group is selected
+ Handle(SALOME_InteractiveObject) IObject = Sel->firstIObject();
+ if (IObject->hasEntry()) {
+ SALOMEDS::SObject_var aSObj = smeshGUI->myStudy->FindObjectID(IObject->getEntry());
+ if(!aSObj->_is_nil()) {
+ SMESH::SMESH_Group_var aGroup = SMESH::SMESH_Group::_narrow(aSObj->GetObject());
+ if (!aGroup->_is_nil()) {
+ SMESHGUI_GroupDlg *aDlg = new SMESHGUI_GroupDlg(parent, "", Sel, aGroup);
+ aDlg->show();
+ }
+ }
+ }
+ }
+ break;
+ }
+
+ case 804: // Add elements to group
+ {
+ if(checkLock(aStudy)) break;
+ if (smeshGUI->myState == 800) {
+ SMESHGUI_GroupDlg *aDlg = (SMESHGUI_GroupDlg*) smeshGUI->myActiveDialogBox;
+ if (aDlg) aDlg->onAdd();
+ }
+ break;
+ }
+
+ case 805: // Remove elements from group
+ {
+ if(checkLock(aStudy)) break;
+ if (smeshGUI->myState == 800) {
+ SMESHGUI_GroupDlg *aDlg = (SMESHGUI_GroupDlg*) smeshGUI->myActiveDialogBox;
+ if (aDlg) aDlg->onRemove();
+ }
+ break;
+ }
+
+ case 900: // MESH INFOS
+ {
+ smeshGUI->EmitSignalDeactivateDialog();
+ SMESHGUI_MeshInfosDlg *aDlg = new SMESHGUI_MeshInfosDlg(parent, "", false);
+ break;
+ }
+
+ case 1001: // AUTOMATIC UPDATE PREFERENCES
+ {
+ parent->menuBar()->setItemChecked(1001, !parent->menuBar()->isItemChecked(1001));
+ if (parent->menuBar()->isItemChecked(1001)) {
+ QAD_CONFIG->addSetting("SMESH:AutomaticUpdate", "true");
+ smeshGUI->myAutomaticUpdate = true;
+ }
+ else {
+ QAD_CONFIG->addSetting("SMESH:AutomaticUpdate", "false");
+ smeshGUI->myAutomaticUpdate = false;
+ }
+ break;
+ }
+
+ case 1003: // MESH PREFERENCES
+ {
+ smeshGUI->SetDisplaySettings();
+ break;
+ }
+
+ case 1005:
+ {
+ SMESHGUI_Preferences_ScalarBarDlg::ScalarBarPreferences( parent );
+ break;
+ }
+
+ case 1006:
+ {
+ SMESHGUI_Preferences_SelectionDlg* aDlg =
+ new SMESHGUI_Preferences_SelectionDlg(parent);
+
+ QColor aColor;
+ QString SCr, SCg, SCb;
+ SCr = QAD_CONFIG->getSetting("SMESH:SettingsPreSelectColorRed");
+ SCg = QAD_CONFIG->getSetting("SMESH:SettingsPreSelectColorGreen");
+ SCb = QAD_CONFIG->getSetting("SMESH:SettingsPreSelectColorBlue");
+ if (!SCr.isEmpty() && !SCg.isEmpty() && !SCb.isEmpty())
+ aColor = QColor(SCr.toInt(), SCg.toInt(), SCb.toInt());
+ else aColor = Qt::cyan;
+ aDlg->SetColor(1, aColor);
+
+ SCr = QAD_CONFIG->getSetting("SMESH:SettingsItemSelectColorRed");
+ SCg = QAD_CONFIG->getSetting("SMESH:SettingsItemSelectColorGreen");
+ SCb = QAD_CONFIG->getSetting("SMESH:SettingsItemSelectColorBlue");
+ if (!SCr.isEmpty() && !SCg.isEmpty() && !SCb.isEmpty())
+ aColor = QColor(SCr.toInt(), SCg.toInt(), SCb.toInt());
+ else aColor = Qt::yellow;
+ aDlg->SetColor(2, aColor);
+
+ SCr = QAD_CONFIG->getSetting("SMESH:SettingsSelectColorRed");
+ SCg = QAD_CONFIG->getSetting("SMESH:SettingsSelectColorGreen");
+ SCb = QAD_CONFIG->getSetting("SMESH:SettingsSelectColorBlue");
+ if (!SCr.isEmpty() && !SCg.isEmpty() && !SCb.isEmpty())
+ aColor = QColor(SCr.toInt(), SCg.toInt(), SCb.toInt());
+ else aColor = Qt::white;
+ aDlg->SetColor(3, aColor);
+
+ QString SW1 = QAD_CONFIG->getSetting("SMESH:SettingsPreSelectWidth");
+ if (SW1.isEmpty()) SW1 = "5";
+ aDlg->SetWidth(1, SW1.toInt());
+
+ QString SW2 = QAD_CONFIG->getSetting("SMESH:SettingsItemSelectWidth");
+ if (SW2.isEmpty()) SW2 = "5";
+ aDlg->SetWidth(2, SW2.toInt());
+
+ QString SP1 = QAD_CONFIG->getSetting("SMESH:SettingsNodeSelectTol");
+ if (SP1.isEmpty()) SP1 = "0.025";
+ aDlg->SetPrecision(1, SP1.toDouble());
+
+ QString SP2 = QAD_CONFIG->getSetting("SMESH:SettingsElementsSelectTol");
+ if (SP2.isEmpty()) SP2 = "0.001";
+ aDlg->SetPrecision(2, SP2.toDouble());
+
+ if (aDlg->exec()) {
+ QColor aPreColor = aDlg->GetColor(1);
+ QAD_CONFIG->addSetting("SMESH:SettingsPreSelectColorRed", aPreColor.red());
+ QAD_CONFIG->addSetting("SMESH:SettingsPreSelectColorGreen", aPreColor.green());
+ QAD_CONFIG->addSetting("SMESH:SettingsPreSelectColorBlue", aPreColor.blue());
+
+ QColor aSelColor = aDlg->GetColor(2);
+ QAD_CONFIG->addSetting("SMESH:SettingsItemSelectColorRed", aSelColor.red());
+ QAD_CONFIG->addSetting("SMESH:SettingsItemSelectColorGreen", aSelColor.green());
+ QAD_CONFIG->addSetting("SMESH:SettingsItemSelectColorBlue", aSelColor.blue());
+
+ QColor aHiColor = aDlg->GetColor(3);
+ QAD_CONFIG->addSetting("SMESH:SettingsSelectColorRed", aHiColor.red());
+ QAD_CONFIG->addSetting("SMESH:SettingsSelectColorGreen", aHiColor.green());
+ QAD_CONFIG->addSetting("SMESH:SettingsSelectColorBlue", aHiColor.blue());
+
+ int aPreWidth = aDlg->GetWidth(1);
+ QAD_CONFIG->addSetting("SMESH:SettingsPreSelectWidth", aPreWidth);
+ int aSelWidth = aDlg->GetWidth(2);
+ QAD_CONFIG->addSetting("SMESH:SettingsItemSelectWidth", aSelWidth);
+
+ double aTolNodes = aDlg->GetPrecision(1);
+ QAD_CONFIG->addSetting("SMESH:SettingsNodeSelectTol", aTolNodes);
+ double aTolItems = aDlg->GetPrecision(2);
+ QAD_CONFIG->addSetting("SMESH:SettingsElementsSelectTol", aTolItems);
+
+ // update current study settings
+ ::UpdateSelectionProp();
+
+ QAD_StudyFrame* studyFrame = smeshGUI->myActiveStudy->getActiveStudyFrame();
+ if (studyFrame->getTypeView() == VIEW_VTK) {
+ VTKViewer_ViewFrame* aViewFrame = GetVtkViewFrame(studyFrame);
+ // update VTK viewer properties
+ VTKViewer_RenderWindowInteractor* anInteractor = aViewFrame->getRWInteractor();
+ if (anInteractor) {
+ anInteractor->SetSelectionProp(aSelColor.red()/255., aSelColor.green()/255.,
+ aSelColor.blue()/255., aSelWidth);
+ anInteractor->SetSelectionTolerance(aTolNodes, aTolItems);
+ VTKViewer_InteractorStyleSALOME* aStyle = anInteractor->GetInteractorStyleSALOME();
+ if (aStyle)
+ aStyle->setPreselectionProp(aPreColor.red()/255., aPreColor.green()/255.,
+ aPreColor.blue()/255., aPreWidth);
+ }
+ // update actors
+ vtkRenderer* aRenderer = aViewFrame->getRenderer();
+ vtkActorCollection *aCollection = aRenderer->GetActors();
+ aCollection->InitTraversal();
+ while(vtkActor *anAct = aCollection->GetNextActor()){
+ if(SMESH_Actor *anActor = dynamic_cast<SMESH_Actor*>(anAct)){
+ anActor->SetHighlightColor(aHiColor.red()/255., aHiColor.green()/255.,
+ aHiColor.blue()/255.);
+ anActor->SetPreHighlightColor(aPreColor.red()/255., aPreColor.green()/255.,
+ aPreColor.blue()/255.);
+ }
+ }
+ }
+ }
+
+ break;
+ }
+
+ case 1100: // EDIT HYPOTHESIS
+ {
+ if(checkLock(aStudy)) break;
+ SALOME_Selection *Sel =
+ SALOME_Selection::Selection(smeshGUI->myActiveStudy->getSelection());
+ int nbSel = Sel->IObjectCount();
+
+ if (nbSel == 1) {
+ Standard_Boolean res;
+ SMESH::SMESH_Hypothesis_var Hyp =
+ smeshGUI->ConvertIOinSMESHHypothesis(Sel->firstIObject(), res);
+
+ /* Look for all mesh objects that have this hypothesis affected in order to flag as ModifiedMesh */
+ /* At end below '...->updateObjBrowser(true)' will change icon of mesh objects */
+ /* Warning : however by internal mechanism all subMeshes icons are changed ! */
+ if ( res )
+ {
+ char* sName = Hyp->GetName();
+ SMESHGUI_GenericHypothesisCreator* aCreator = smeshGUI->GetHypothesisCreator(sName);
+ if (aCreator)
+ {
+ aCreator->EditHypothesis(Hyp);
+ }
+ else
+ {
+ // report error
+ }
+ }
+ }
+ break;
+ }
+
+ case 1101: // RENAME
+ {
+ if(checkLock(aStudy)) break;
+ SALOME_Selection *Sel = SALOME_Selection::Selection(smeshGUI->myActiveStudy->getSelection());
+ SALOME_ListIteratorOfListIO It(Sel->StoredIObjects());
+ for (; It.More(); It.Next()) {
+ Handle(SALOME_InteractiveObject) IObject = It.Value();
+
+ SALOMEDS::SObject_var obj = smeshGUI->myStudy->FindObjectID(IObject->getEntry());
+ SALOMEDS::GenericAttribute_var anAttr;
+ SALOMEDS::AttributeName_var aName;
+ if (!obj->_is_nil()) {
+ if (obj->FindAttribute(anAttr, "AttributeName")) {
+ aName = SALOMEDS::AttributeName::_narrow(anAttr);
+ QString newName = QString(aName->Value());
+ newName = SALOMEGUI_NameDlg::getName(QAD_Application::getDesktop(), newName);
+ if (!newName.isEmpty()) {
+ smeshGUI->myActiveStudy->renameIObject(IObject, newName);
+ }
+ }
+ }
+ }
+ break;
+ }
+
+ case 1102: // REMOVE HYPOTHESIS / ALGORITHMS
+ {
+ if(checkLock(aStudy)) break;
+ QAD_WaitCursor wc;
+ SALOME_Selection *Sel = SALOME_Selection::Selection(smeshGUI->myActiveStudy->getSelection());
+ SALOME_ListIteratorOfListIO It(Sel->StoredIObjects());
+ for (int i = 0; It.More(); It.Next(), i++) {
+ Handle(SALOME_InteractiveObject) IObject = It.Value();
+ smeshGUI->RemoveHypothesisOrAlgorithmOnMesh(IObject);
+ }
+ Sel->ClearIObjects();
+ smeshGUI->myActiveStudy->updateObjBrowser(true);
+ break;
+ }
+
+ case 401: // GEOM::EDGE
+ {
+ if(checkLock(aStudy)) break;
+ if (smeshGUI->myActiveStudy->getActiveStudyFrame()->getTypeView() == VIEW_VTK) {
+ smeshGUI->EmitSignalDeactivateDialog();
+ SALOME_Selection *Sel = SALOME_Selection::Selection(smeshGUI->myActiveStudy->getSelection());
+ Sel->ClearIObjects();
+ smeshGUI->myDesktop->SetSelectionMode(NodeSelection, true);
+ smeshGUI->ViewNodes();
+ SMESHGUI_AddEdgeDlg *aDlg = new SMESHGUI_AddEdgeDlg(parent, "", Sel);
+ }
+ else {
+ QAD_MessageBox::warn1(QAD_Application::getDesktop(),
+ tr("SMESH_WRN_WARNING"), tr("SMESH_WRN_VIEWER_VTK"),
+ tr("SMESH_BUT_OK"));
+ }
+ break;
+ }
+ case 4021: // TRIANGLE
+ {
+ if(checkLock(aStudy)) break;
+ if (smeshGUI->myActiveStudy->getActiveStudyFrame()->getTypeView() == VIEW_VTK) {
+ smeshGUI->EmitSignalDeactivateDialog();
+ SALOME_Selection *Sel = SALOME_Selection::Selection(smeshGUI->myActiveStudy->getSelection());
+ Sel->ClearIObjects();
+ smeshGUI->myDesktop->SetSelectionMode(NodeSelection, true);
+ smeshGUI->ViewNodes();
+ SMESHGUI_AddFaceDlg *aDlg = new SMESHGUI_AddFaceDlg(parent, "", Sel, 3);
+ }
+ else {
+ QAD_MessageBox::warn1(QAD_Application::getDesktop(),
+ tr("SMESH_WRN_WARNING"), tr("SMESH_WRN_VIEWER_VTK"),
+ tr("SMESH_BUT_OK"));
+ }
+ break;
+ }
+ case 4022: // QUAD
+ {
+ if(checkLock(aStudy)) break;
+ if (smeshGUI->myActiveStudy->getActiveStudyFrame()->getTypeView() == VIEW_VTK) {
+ smeshGUI->EmitSignalDeactivateDialog();
+ SALOME_Selection *Sel = SALOME_Selection::Selection(smeshGUI->myActiveStudy->getSelection());
+ Sel->ClearIObjects();
+ smeshGUI->myDesktop->SetSelectionMode(NodeSelection, true);
+ smeshGUI->ViewNodes();
+ SMESHGUI_AddFaceDlg *aDlg = new SMESHGUI_AddFaceDlg(parent, "", Sel, 4);
+ }
+ else
{
- v3d =
- ((OCCViewer_ViewFrame *) smeshGUI->myActiveStudy->
- getActiveStudyFrame()->getRightFrame()->getViewFrame())->
- getViewer();
- ic = v3d->getAISContext();
- }
- else if (smeshGUI->myActiveStudy->getActiveStudyFrame()->getTypeView() ==
- VIEW_VTK)
+ QAD_MessageBox::warn1(QAD_Application::getDesktop(),
+ tr("SMESH_WRN_WARNING"), tr("SMESH_WRN_VIEWER_VTK"),
+ tr("SMESH_BUT_OK"));
+ }
+ break;
+ }
+ case 4031: // TETRA
+ {
+ if(checkLock(aStudy)) break;
+ if (smeshGUI->myActiveStudy->getActiveStudyFrame()->getTypeView() == VIEW_VTK) {
+ smeshGUI->EmitSignalDeactivateDialog();
+ SALOME_Selection *Sel = SALOME_Selection::Selection(smeshGUI->myActiveStudy->getSelection());
+ Sel->ClearIObjects();
+ smeshGUI->myDesktop->SetSelectionMode(NodeSelection, true);
+ smeshGUI->ViewNodes();
+ SMESHGUI_AddVolumeDlg *aDlg = new SMESHGUI_AddVolumeDlg(parent, "", Sel, 4);
+ }
+ else {
+ QAD_MessageBox::warn1(QAD_Application::getDesktop(),
+ tr("SMESH_WRN_WARNING"), tr("SMESH_WRN_VIEWER_VTK"),
+ tr("SMESH_BUT_OK"));
+ }
+ break;
+ }
+ case 4032: // HEXA
+ {
+ if(checkLock(aStudy)) break;
+ if (smeshGUI->myActiveStudy->getActiveStudyFrame()->getTypeView() == VIEW_VTK) {
+ smeshGUI->EmitSignalDeactivateDialog();
+ SALOME_Selection *Sel = SALOME_Selection::Selection(smeshGUI->myActiveStudy->getSelection());
+ Sel->ClearIObjects();
+ smeshGUI->myDesktop->SetSelectionMode(NodeSelection, true);
+ smeshGUI->ViewNodes();
+ SMESHGUI_AddVolumeDlg *aDlg = new SMESHGUI_AddVolumeDlg(parent, "", Sel, 8);
+ }
+ else {
+ QAD_MessageBox::warn1(QAD_Application::getDesktop(),
+ tr("SMESH_WRN_WARNING"), tr("SMESH_WRN_VIEWER_VTK"),
+ tr("SMESH_BUT_OK"));
+ }
+ break;
+ }
+
+ case 4041: // REMOVES NODES
+ {
+ if(checkLock(aStudy)) break;
+ if (smeshGUI->myActiveStudy->getActiveStudyFrame()->getTypeView() == VIEW_VTK) {
+ smeshGUI->EmitSignalDeactivateDialog();
+ SALOME_Selection *Sel = SALOME_Selection::Selection(smeshGUI->myActiveStudy->getSelection());
+ Sel->ClearIObjects();
+ smeshGUI->myDesktop->SetSelectionMode(NodeSelection, true);
+ smeshGUI->ViewNodes();
+ SMESHGUI_RemoveNodesDlg *aDlg = new SMESHGUI_RemoveNodesDlg(parent, "", Sel);
+ }
+ else {
+ QAD_MessageBox::warn1(QAD_Application::getDesktop(),
+ tr("SMESH_WRN_WARNING"), tr("SMESH_WRN_VIEWER_VTK"),
+ tr("SMESH_BUT_OK"));
+ }
+ break;
+ }
+ case 4042: // REMOVES ELEMENTS
+ {
+ if(checkLock(aStudy)) break;
+ if (smeshGUI->myActiveStudy->getActiveStudyFrame()->getTypeView() == VIEW_VTK) {
+ smeshGUI->EmitSignalDeactivateDialog();
+ SALOME_Selection *Sel = SALOME_Selection::Selection(smeshGUI->myActiveStudy->getSelection());
+ Sel->ClearIObjects();
+ smeshGUI->myDesktop->SetSelectionMode(CellSelection, true);
+ SMESHGUI_RemoveElementsDlg *aDlg = new SMESHGUI_RemoveElementsDlg(parent, "", Sel);
+ }
+ else
{
- Renderer =
- ((VTKViewer_ViewFrame *) smeshGUI->myActiveStudy->
- getActiveStudyFrame()->getRightFrame()->getViewFrame())->
- getRenderer();
- RenWin = Renderer->GetRenderWindow();
- }
-
- switch (theCommandID)
- {
- case 33: // DELETE
- smeshGUI->OnEditDelete();
- break;
-
- case 113: // IMPORT
- case 112:
- case 111:
- {
- smeshGUI->Import_Document(parent, theCommandID);
- break;
- }
-
- case 122: // EXPORT MED
- case 121:
- case 123:
- {
- Export_Mesh(parent, theCommandID);
- break;
- }
-
- case 200: // SCALAR BAR
- {
- smeshGUI->DisplayScalarBar(false);
- break;
- }
- case 201:
- {
- SMESHGUI_EditScalarBarDlg *aDlg =
- new SMESHGUI_EditScalarBarDlg(parent, "", false);
- aDlg->show();
- break;
- }
- case 202:
- {
- smeshGUI->DisplayScalarBar(true);
- break;
- }
-
- case 1133: // DISPLAY MODE : WireFrame, Surface, Shrink
- case 1132:
- case 213:
- case 212:
- case 211:
- {
- smeshGUI->SetViewMode(theCommandID);
- break;
- }
-
- case 214: // UPDATE
- {
- smeshGUI->Update();
- break;
- }
-
- case 300: // ERASE
- {
- SALOME_Selection *Sel =
- SALOME_Selection::Selection(smeshGUI->myActiveStudy->
- getSelection());
- if (smeshGUI->myActiveStudy->getActiveStudyFrame()->getTypeView() ==
- VIEW_VTK)
- {
- // VTK
- SALOME_ListIteratorOfListIO It(Sel->StoredIObjects());
- for (; It.More(); It.Next())
- {
- Handle(SALOME_InteractiveObject) IOS = It.Value();
- if (IOS->hasEntry())
- {
- Standard_Boolean res;
- SMESH_Actor *ac =
- smeshGUI->FindActorByEntry(IOS->getEntry(), res, true);
- if (res)
- smeshGUI->EraseActor(ac);
- }
- }
- }
- Sel->ClearIObjects();
- smeshGUI->myActiveStudy->updateObjBrowser(true);
- }
-
- case 301: // DISPLAY
- {
- if (smeshGUI->myActiveStudy->getActiveStudyFrame()->getTypeView() ==
- VIEW_VTK)
- {
- // VTK
- QApplication::setOverrideCursor(Qt::waitCursor);
- SALOMEDS::SObject_var fatherSF =
- smeshGUI->myStudy->FindObjectID(smeshGUI->myActiveStudy->
- getActiveStudyFrame()->entry());
-
- SALOME_Selection *Sel =
- SALOME_Selection::Selection(smeshGUI->myActiveStudy->
- getSelection());
- SALOME_ListIteratorOfListIO It(Sel->StoredIObjects());
-
- for (; It.More(); It.Next())
- {
- Handle(SALOME_InteractiveObject) IObject = It.Value();
- if (IObject->hasEntry())
- {
- Standard_Boolean res;
- SMESH_Actor *ac =
- smeshGUI->FindActorByEntry(IObject->getEntry(), res,
- false);
- if (res)
- {
- smeshGUI->DisplayActor(ac, true);
- smeshGUI->DisplayEdges(ac);
- smeshGUI->ChangeRepresentation(ac,
- ac->getDisplayMode());
- }
- }
- }
- QApplication::restoreOverrideCursor();
- }
- break;
- }
-
- case 302: // DISPLAY ONLY
- {
- if (smeshGUI->myActiveStudy->getActiveStudyFrame()->getTypeView() ==
- VIEW_VTK)
- {
- QApplication::setOverrideCursor(Qt::waitCursor);
- vtkActorCollection *theActors = Renderer->GetActors();
- theActors->InitTraversal();
- vtkActor *ac = theActors->GetNextActor();
- while (!(ac == NULL))
- {
- if (ac->IsA("SMESH_Actor"))
- {
- SMESH_Actor *anActor = SMESH_Actor::SafeDownCast(ac);
- if (!anActor->isHighlighted())
- {
- //anActor->VisibilityOff();
- //NRI- : 02/12/2002 : Fixed bugId 882
- // anActor->EdgeDevice->VisibilityOff();
- // anActor->EdgeShrinkDevice->VisibilityOff();
- anActor->SetVisibility(false);
- }
- }
- ac = theActors->GetNextActor();
- }
-
- // Display selection
- SALOMEDS::SObject_var fatherSF =
- smeshGUI->myStudy->FindObjectID(smeshGUI->myActiveStudy->
- getActiveStudyFrame()->entry());
-
- SALOME_Selection *Sel =
- SALOME_Selection::Selection(smeshGUI->myActiveStudy->
- getSelection());
- SALOME_ListIteratorOfListIO It(Sel->StoredIObjects());
-
- for (; It.More(); It.Next())
- {
- Handle(SALOME_InteractiveObject) IObject = It.Value();
- SALOMEDS::SObject_var obj =
- smeshGUI->myStudy->FindObjectID(IObject->getEntry());
-
- VTKViewer_RenderWindowInteractor *myRenderInter =
- ((VTKViewer_ViewFrame *) smeshGUI->myActiveStudy->
- getActiveStudyFrame()->getRightFrame()->getViewFrame())->
- getRWInteractor();
- // vtkQGLRenderWindowInteractor* myRenderInter= smeshGUI->myActiveStudy->getActiveStudyFrame()->getRightFrame()->getVTKView()->getRWInteractor();
-
- if (myRenderInter->isInViewer(IObject))
- {
- if (IObject->hasEntry())
- {
- Standard_Boolean res;
- SMESH_Actor *ac =
- smeshGUI->FindActorByEntry(IObject->getEntry(), res,
- true);
- if (res)
- {
- smeshGUI->DisplayActor(ac, true);
- smeshGUI->DisplayEdges(ac);
- smeshGUI->ChangeRepresentation(ac,
- ac->getDisplayMode());
- }
- }
- }
- }
- smeshGUI->myActiveStudy->updateObjBrowser(true);
- QApplication::restoreOverrideCursor();
- }
- break;
- }
-
- case 400: // NODES
- {
- if (smeshGUI->myActiveStudy->getActiveStudyFrame()->getTypeView() ==
- VIEW_VTK)
- { //VTK
- smeshGUI->EmitSignalDeactivateDialog();
- SALOME_Selection *Sel =
- SALOME_Selection::Selection(smeshGUI->myActiveStudy->
- getSelection());
- Sel->ClearIObjects();
- smeshGUI->myDesktop->SetSelectionMode(1, true);
- parent->menuBar()->setItemChecked(9010, false);
- parent->menuBar()->setItemChecked(9011, false);
- smeshGUI->ViewNodes();
- SMESHGUI_NodesDlg *aDlg = new SMESHGUI_NodesDlg(parent, "", Sel);
- }
- else
- {
- QApplication::restoreOverrideCursor();
- QAD_MessageBox::warn1(QAD_Application::getDesktop(),
- tr("SMESH_WRN_WARNING"), tr("SMESH_WRN_VIEWER_VTK"),
- tr("SMESH_BUT_YES"));
- }
- break;
- }
-
- case 405: // MOVE NODE
- {
- smeshGUI->myDesktop->SetSelectionMode(1, true);
- SALOME_Selection *Sel =
- SALOME_Selection::Selection(smeshGUI->myActiveStudy->
- getSelection());
- SMESHGUI_MoveNodesDlg *aDlg =
- new SMESHGUI_MoveNodesDlg(parent, "", Sel);
- break;
- }
-
- case 701: // COMPUTE MESH
- {
- if (smeshGUI->myActiveStudy->getActiveStudyFrame()->getTypeView() ==
- VIEW_VTK)
- { //VTK
- SALOME_Selection *Sel =
- SALOME_Selection::Selection(smeshGUI->myActiveStudy->
- getSelection());
- int nbSel = Sel->IObjectCount();
- if (nbSel != 1)
- {
- QApplication::restoreOverrideCursor();
- break;
- }
-
- SMESH::SMESH_Mesh_var aM;
- SMESH::SMESH_subMesh_var aSubM;
- Handle(SALOME_InteractiveObject) IObject = Sel->firstIObject();
- if (IObject->hasEntry())
- {
- SALOMEDS::SObject_var aMorSM =
- smeshGUI->myStudy->FindObjectID(IObject->getEntry());
- SALOMEDS::GenericAttribute_var anAttr;
- SALOMEDS::AttributeIOR_var anIOR;
- if (!aMorSM->_is_nil())
- {
- if (aMorSM->FindAttribute(anAttr, "AttributeIOR"))
- {
- anIOR = SALOMEDS::AttributeIOR::_narrow(anAttr);
- MESSAGE("SMESHGUI::OnGUIEvent - Compute mesh : IOR = "
- << anIOR->Value())CORBA::Object_var cobj;
- try
- {
- cobj = _orb->string_to_object(anIOR->Value());
- if (CORBA::is_nil(cobj))
- {
- MESSAGE
- ("SMESHGUI::OnGUIEvent - Compute mesh : nil object")}
- }
- catch(CORBA::COMM_FAILURE & ex)
- {
- MESSAGE
- ("SMESHGUI::OnGUIEvent - Compute mesh : exception (1)")}
- aM = SMESH::SMESH_Mesh::_narrow(cobj);
- //aM = SMESH::SMESH_Mesh::_narrow( _orb->string_to_object(anIOR->Value()) );
- aSubM =
- SMESH::SMESH_subMesh::_narrow(_orb->
- string_to_object(anIOR->Value()));
- if (!aM->_is_nil())
- {
- GEOM::GEOM_Shape_var refShape =
- smeshGUI->myStudyAPI.
- GetShapeOnMeshOrSubMesh(aMorSM);
- if (!refShape->_is_nil())
- {
- bool compute =
- smeshGUI->myComponentMesh->
- IsReadyToCompute(aM, refShape);
- if (!compute)
- {
- QApplication::restoreOverrideCursor();
- QAD_MessageBox::warn1(QAD_Application::
- getDesktop(), tr("SMESH_WRN_WARNING"),
- tr("SMESH_WRN_MISSING_PARAMETERS"),
- tr("SMESH_BUT_YES"));
- break;
- }
- try
- {
- smeshGUI->myComponentMesh->Compute(aM,
- refShape);
- smeshGUI->myStudyAPI.ModifiedMesh(aMorSM,
- true);
- // TO Do : change icon of all submeshes
- }
- catch(const SALOME::SALOME_Exception & S_ex)
- {
- QtCatchCorbaException(S_ex);
- }
- }
- }
- else if (!aSubM->_is_nil())
- {
- aM = aSubM->GetFather();
- GEOM::GEOM_Shape_var refShape =
- smeshGUI->myStudyAPI.
- GetShapeOnMeshOrSubMesh(aMorSM);
- if (!refShape->_is_nil())
- {
- bool compute =
- smeshGUI->myComponentMesh->
- IsReadyToCompute(aM, refShape);
- if (!compute)
- {
- QApplication::restoreOverrideCursor();
- QAD_MessageBox::warn1(QAD_Application::
- getDesktop(), tr("SMESH_WRN_WARNING"),
- tr("SMESH_WRN_MISSING_PARAMETERS"),
- tr("SMESH_BUT_YES"));
- break;
- }
- try
- {
- smeshGUI->myComponentMesh->Compute(aM,
- refShape);
- smeshGUI->myStudyAPI.ModifiedMesh(aMorSM,
- true);
- // TO Do : change icon of all submeshes
- }
- catch(const SALOME::SALOME_Exception & S_ex)
- {
- QtCatchCorbaException(S_ex);
- }
- }
- }
- }
- }
- }
-
- // Check whether the actor for the mesh exists at least in one view
- Standard_Boolean res;
- SMESH_Actor *ac =
- smeshGUI->FindActorByEntry(IObject->getEntry(), res, false);
- if (!res)
- smeshGUI->InitActor(aM);
- else
- {
- // Check whether the actor belongs to the active view
- VTKViewer_RenderWindowInteractor *rwInter =
- ((VTKViewer_ViewFrame *) smeshGUI->myActiveStudy->
- getActiveStudyFrame()->getRightFrame()->getViewFrame())->
- getRWInteractor();
-
- // The actor belongs to inactive view -> create a copy and add it in the active view
- if (!rwInter->isInViewer(IObject))
- {
- SMESH_Actor *acCopy = SMESH_Actor::New();
- acCopy->ShallowCopy(ac);
-
- smeshGUI->DisplayActor(acCopy, false);
- }
- }
-
- if (smeshGUI->myAutomaticUpdate)
- {
- SMESH_Actor *Mesh = smeshGUI->ReadScript(aM);
- if (Mesh != NULL)
- {
-#ifdef TRACE
- Dump(Mesh);
-#endif
- smeshGUI->DisplayActor(Mesh, true);
- smeshGUI->DisplayEdges(Mesh, true);
- smeshGUI->ChangeRepresentation(Mesh,
- Mesh->getDisplayMode());
- }
- }
- }
- else
- {
- QApplication::restoreOverrideCursor();
- QAD_MessageBox::warn1(QAD_Application::getDesktop(),
- tr("SMESH_WRN_WARNING"), tr("SMESH_WRN_VIEWER_VTK"),
- tr("SMESH_BUT_YES"));
- }
- QApplication::restoreOverrideCursor();
- break;
- }
-
- case 702: // ADD SUB MESH
- {
- if (smeshGUI->myActiveStudy->getActiveStudyFrame()->getTypeView() ==
- VIEW_VTK)
- { //VTK
- smeshGUI->EmitSignalDeactivateDialog();
- SALOME_Selection *Sel =
- SALOME_Selection::Selection(smeshGUI->myActiveStudy->
- getSelection());
- SMESHGUI_AddSubMeshDlg *aDlg =
- new SMESHGUI_AddSubMeshDlg(parent, "", Sel);
- }
- else
- {
- QApplication::restoreOverrideCursor();
- QAD_MessageBox::warn1(QAD_Application::getDesktop(),
- tr("SMESH_WRN_WARNING"), tr("SMESH_WRN_VIEWER_VTK"),
- tr("SMESH_BUT_YES"));
- }
- break;
- }
-
- case 703: // INIT MESH
- {
- smeshGUI->EmitSignalDeactivateDialog();
- SALOME_Selection *Sel =
- SALOME_Selection::Selection(smeshGUI->myActiveStudy->
- getSelection());
- SMESHGUI_InitMeshDlg *aDlg = new SMESHGUI_InitMeshDlg(parent, "", Sel);
- break;
- }
-
- case 704: // EDIT Hypothesis
- {
- smeshGUI->EmitSignalDeactivateDialog();
- SALOME_Selection *Sel =
- SALOME_Selection::Selection(smeshGUI->myActiveStudy->
- getSelection());
- SMESHGUI_EditHypothesesDlg *aDlg =
- new SMESHGUI_EditHypothesesDlg(parent, "", Sel);
- break;
- }
-
- case 705: // EDIT Global Hypothesis
- {
- smeshGUI->EmitSignalDeactivateDialog();
- SALOME_Selection *Sel =
- SALOME_Selection::Selection(smeshGUI->myActiveStudy->
- getSelection());
- SMESHGUI_EditHypothesesDlg *aDlg =
- new SMESHGUI_EditHypothesesDlg(parent, "", Sel);
- break;
- }
-
- case 706: // EDIT Local Hypothesis
- {
- smeshGUI->EmitSignalDeactivateDialog();
- SALOME_Selection *Sel =
- SALOME_Selection::Selection(smeshGUI->myActiveStudy->
- getSelection());
- SMESHGUI_EditHypothesesDlg *aDlg =
- new SMESHGUI_EditHypothesesDlg(parent, "", Sel);
- break;
- }
-
- case 806: // ORIENTATION ELEMENTS
- {
- smeshGUI->EmitSignalDeactivateDialog();
- SALOME_Selection *Sel =
- SALOME_Selection::Selection(smeshGUI->myActiveStudy->
- getSelection());
- smeshGUI->myDesktop->SetSelectionMode(3, true);
- SMESHGUI_OrientationElementsDlg *aDlg =
- new SMESHGUI_OrientationElementsDlg(parent, "", Sel);
- break;
- }
-
- case 807: // DIAGONAL INVERSION
- {
- smeshGUI->EmitSignalDeactivateDialog();
- SALOME_Selection *Sel =
- SALOME_Selection::Selection(smeshGUI->myActiveStudy->
- getSelection());
- Sel->ClearIObjects();
- smeshGUI->myDesktop->SetSelectionMode(2, true);
- SMESHGUI_DiagonalInversionDlg *aDlg =
- new SMESHGUI_DiagonalInversionDlg(parent, "", Sel);
- break;
- }
-
- case 900: // MESH INFOS
- {
- smeshGUI->EmitSignalDeactivateDialog();
- SALOME_Selection *Sel =
- SALOME_Selection::Selection(smeshGUI->myActiveStudy->
- getSelection());
- SMESHGUI_MeshInfosDlg *aDlg =
- new SMESHGUI_MeshInfosDlg(parent, "", Sel);
- break;
- }
-
- case 1001: // AUTOMATIC UPDATE PREFERENCES
- {
- parent->menuBar()->setItemChecked(1001,
- !parent->menuBar()->isItemChecked(1001));
- if (parent->menuBar()->isItemChecked(1001))
- {
- QAD_CONFIG->addSetting("SMESH:AutomaticUpdate", "true");
- smeshGUI->myAutomaticUpdate = true;
- }
- else
- {
- QAD_CONFIG->addSetting("SMESH:AutomaticUpdate", "false");
- smeshGUI->myAutomaticUpdate = false;
- }
- break;
- }
-
- case 1003: // MESH PREFERENCES
- {
- smeshGUI->SetDisplaySettings();
- break;
- }
-
- case 1005:
- {
- QString Bold = QAD_CONFIG->getSetting("ScalarBar:Bold");
- QString Italic = QAD_CONFIG->getSetting("ScalarBar:Italic");
- QString Shadow = QAD_CONFIG->getSetting("ScalarBar:Shadow");
- QString FontFamily = QAD_CONFIG->getSetting("ScalarBar:FontFamily");
- QString Orientation = QAD_CONFIG->getSetting("ScalarBar:Orientation");
- float Width = QAD_CONFIG->getSetting("ScalarBar:Width").toFloat();
- float Height = QAD_CONFIG->getSetting("ScalarBar:Height").toFloat();
- int NumberOfLabels =
- QAD_CONFIG->getSetting("ScalarBar:NumberOfLabels").toInt();
- int NumberOfColors =
- QAD_CONFIG->getSetting("ScalarBar:NumberOfColors").toInt();
-
- if (Width == 0)
- Width = 0.17;
- if (Height == 0)
- Height = 0.8;
- if (NumberOfLabels == 0)
- NumberOfLabels = 5;
- if (NumberOfColors == 0)
- NumberOfColors = 64;
-
- SMESHGUI_Preferences_ScalarBarDlg *aDlg =
- new SMESHGUI_Preferences_ScalarBarDlg(parent, "", true);
-
- if (Bold.compare("true") == 0)
- aDlg->Bold->setChecked(true);
- else
- aDlg->Bold->setChecked(false);
- if (Italic.compare("true") == 0)
- aDlg->Italic->setChecked(true);
- else
- aDlg->Italic->setChecked(false);
- if (Shadow.compare("true") == 0)
- aDlg->Shadow->setChecked(true);
- else
- aDlg->Shadow->setChecked(false);
-
- if (Orientation.compare("Horizontal") == 0)
- aDlg->RadioHoriz->setChecked(true);
- else
- aDlg->RadioVert->setChecked(true);
-
- int NbItems = aDlg->ComboBox1->count();
- int i = 0;
- aDlg->ComboBox1->setCurrentItem(i);
- while (i < NbItems)
- {
- if (FontFamily.compare(aDlg->ComboBox1->text(i)) == 0)
- aDlg->ComboBox1->setCurrentItem(i);
- i++;
- }
-
- aDlg->LineEditWidth->setText(QString("%1").arg(Width));
- aDlg->LineEditHeight->setText(QString("%1").arg(Height));
-
- aDlg->SpinBoxLabels->setValue(NumberOfLabels);
- aDlg->SpinBoxColors->setValue(NumberOfColors);
-
- aDlg->show();
- if (aDlg->result())
- {
- if (aDlg->RadioHoriz->isChecked())
- Orientation = "Horizontal";
- else
- Orientation = "Vertical";
- if (aDlg->Bold->isChecked())
- Bold = "true";
- else
- Bold = "false";
- if (aDlg->Italic->isChecked())
- Italic = "true";
- else
- Italic = "false";
- if (aDlg->Shadow->isChecked())
- Shadow = "true";
- else
- Shadow = "false";
-
- FontFamily = aDlg->ComboBox1->currentText();
- Width = aDlg->LineEditWidth->text().toFloat();
- Height = aDlg->LineEditHeight->text().toFloat();
- NumberOfColors = aDlg->SpinBoxColors->text().toInt();
- NumberOfLabels = aDlg->SpinBoxLabels->text().toInt();
-
- vtkScalarBarActor *aScalarBar = smeshGUI->GetScalarBar();
- if (aScalarBar != NULL)
- {
- smeshGUI->SetSettingsScalarBar(aScalarBar, Bold, Italic, Shadow,
- FontFamily, Orientation,
- Width, Height, NumberOfColors, NumberOfLabels);
- }
-
- QAD_CONFIG->addSetting("ScalarBar:Bold", Bold);
- QAD_CONFIG->addSetting("ScalarBar:Italic", Italic);
- QAD_CONFIG->addSetting("ScalarBar:Shadow", Shadow);
- QAD_CONFIG->addSetting("ScalarBar:FontFamily", FontFamily);
- QAD_CONFIG->addSetting("ScalarBar:Orientation", Orientation);
- QAD_CONFIG->addSetting("ScalarBar:Width", Width);
- QAD_CONFIG->addSetting("ScalarBar:Height", Height);
- QAD_CONFIG->addSetting("ScalarBar:NumberOfLabels", NumberOfLabels);
- QAD_CONFIG->addSetting("ScalarBar:NumberOfColors", NumberOfColors);
- }
- break;
- }
-
- case 1100: // EDIT HYPOTHESIS
- {
- SALOME_Selection *Sel =
- SALOME_Selection::Selection(smeshGUI->myActiveStudy->
- getSelection());
- int nbSel = Sel->IObjectCount();
-
- if (nbSel == 1)
- {
- Standard_Boolean res;
- SMESH::SMESH_Hypothesis_var Hyp =
- smeshGUI->ConvertIOinSMESHHypothesis(Sel->firstIObject(), res);
-
- /* Look for all mesh objects that have this hupothesis affected in order to flag as ModifiedMesh */
- /* At end below '...->updateObjBrowser(true)' will change icon of mesh objects */
- /* Warning : however by internal mechanism all subMeshes icons are changed ! */
- SALOMEDS::Study::ListOfSObject_var listSOmesh =
- smeshGUI->GetMeshesUsingAlgoOrHypothesis(Hyp);
-
- if (res)
- {
- QString Name = Hyp->GetName();
-
- if (Name.compare("LocalLength") == 0)
- {
- SMESH::SMESH_LocalLength_var LL =
- SMESH::SMESH_LocalLength::_narrow(Hyp);
- double beforeLength = LL->GetLength();
- double Length = smeshGUI->Parameter(res,
- beforeLength,
- tr("SMESH_LOCAL_LENGTH_HYPOTHESIS"),
- tr("SMESH_VALUE"),
- 1.0E-5, 1E6, 6);
- if (res && Length != beforeLength)
- {
- LL->SetLength(Length);
- for (int i = 0; i < listSOmesh->length(); i++)
- {
- smeshGUI->GetStudyAPI().ModifiedMesh(listSOmesh[i],
- false);
- }
- break;
- }
-
- }
- else if (Name.compare("NumberOfSegments") == 0)
- {
- SMESH::SMESH_NumberOfSegments_var NOS =
- SMESH::SMESH_NumberOfSegments::_narrow(Hyp);
- int beforeNbSeg = NOS->GetNumberOfSegments();
- int NbSeg = smeshGUI->Parameter(res,
- beforeNbSeg,
- tr("SMESH_NB_SEGMENTS_HYPOTHESIS"),
- tr("SMESH_VALUE"),
- 1, 1000000);
-
- if (res && NbSeg != beforeNbSeg)
- {
- NOS->SetNumberOfSegments(NbSeg);
- for (int i = 0; i < listSOmesh->length(); i++)
- {
- SALOMEDS::SObject_var SO = listSOmesh[i];
- smeshGUI->GetStudyAPI().ModifiedMesh(listSOmesh[i],
- false);
- }
- break;
- }
-
- }
- else if (Name.compare("MaxElementArea") == 0)
- {
- SMESH::SMESH_MaxElementArea_var MEA =
- SMESH::SMESH_MaxElementArea::_narrow(Hyp);
- double beforeMaxArea = MEA->GetMaxElementArea();
- double MaxArea = smeshGUI->Parameter(res,
- beforeMaxArea,
- tr("SMESH_MAX_ELEMENT_AREA_HYPOTHESIS"),
- tr("SMESH_VALUE"),
- 1.0E-5, 1E6, 6);
- if (res && MaxArea != beforeMaxArea)
- {
- MEA->SetMaxElementArea(MaxArea);
- for (int i = 0; i < listSOmesh->length(); i++)
- {
- smeshGUI->GetStudyAPI().ModifiedMesh(listSOmesh[i],
- false);
- }
- break;
- }
-
- }
- else if (Name.compare("MaxElementVolume") == 0)
- {
- SMESH::SMESH_MaxElementVolume_var MEV =
- SMESH::SMESH_MaxElementVolume::_narrow(Hyp);
- double beforeMaxVolume = MEV->GetMaxElementVolume();
- double MaxVolume = smeshGUI->Parameter(res,
- beforeMaxVolume,
- tr("SMESH_MAX_ELEMENT_VOLUME_HYPOTHESIS"),
- tr("SMESH_VALUE"),
- 1.0E-5, 1E6, 6);
- if (res && MaxVolume != beforeMaxVolume)
- {
- MEV->SetMaxElementVolume(MaxVolume);
- for (int i = 0; i < listSOmesh->length(); i++)
- {
- smeshGUI->GetStudyAPI().ModifiedMesh(listSOmesh[i],
- false);
- }
- break;
- }
-
- }
- else if (Name.compare("Regular_1D") == 0)
- {
- }
- else if (Name.compare("MEFISTO_2D") == 0)
- {
- }
- else
- {
- }
-
- }
- }
- break;
- }
-
- case 1101: // RENAME
- {
- SALOME_Selection *Sel =
- SALOME_Selection::Selection(smeshGUI->myActiveStudy->
- getSelection());
- SALOME_ListIteratorOfListIO It(Sel->StoredIObjects());
- for (; It.More(); It.Next())
- {
- Handle(SALOME_InteractiveObject) IObject = It.Value();
-
- SALOMEDS::SObject_var obj =
- smeshGUI->myStudy->FindObjectID(IObject->getEntry());
- SALOMEDS::GenericAttribute_var anAttr;
- SALOMEDS::AttributeName_var aName;
- if (!obj->_is_nil())
- {
- if (obj->FindAttribute(anAttr, "AttributeName"))
- {
- aName = SALOMEDS::AttributeName::_narrow(anAttr);
- QString newName = QString(aName->Value());
- newName =
- SALOMEGUI_NameDlg::getName(QAD_Application::
- getDesktop(), newName);
- if (!newName.isEmpty())
- {
- QApplication::setOverrideCursor(Qt::waitCursor);
- smeshGUI->myActiveStudy->renameIObject(IObject,
- newName);
- }
- QApplication::restoreOverrideCursor();
- }
- }
- }
- break;
- }
-
- case 1102: // REMOVE HYPOTHESIS / ALGORITHMS
- {
- QApplication::setOverrideCursor(Qt::waitCursor);
- SALOME_Selection *Sel =
- SALOME_Selection::Selection(smeshGUI->myActiveStudy->
- getSelection());
- SALOME_ListIteratorOfListIO It(Sel->StoredIObjects());
- for (int i = 0; It.More(); It.Next(), i++)
- {
- Handle(SALOME_InteractiveObject) IObject = It.Value();
- smeshGUI->RemoveHypothesisOrAlgorithmOnMesh(IObject);
- }
- Sel->ClearIObjects();
- smeshGUI->myActiveStudy->updateObjBrowser(true);
- QApplication::restoreOverrideCursor();
- break;
- }
-
- case 401: // GEOM::EDGE
- {
- if (smeshGUI->myActiveStudy->getActiveStudyFrame()->getTypeView() ==
- VIEW_VTK)
- { //VTK
- smeshGUI->EmitSignalDeactivateDialog();
- SALOME_Selection *Sel =
- SALOME_Selection::Selection(smeshGUI->myActiveStudy->
- getSelection());
- Sel->ClearIObjects();
- smeshGUI->myDesktop->SetSelectionMode(1, true);
- parent->menuBar()->setItemChecked(9010, false);
- parent->menuBar()->setItemChecked(9011, false);
- smeshGUI->ViewNodes();
- SMESHGUI_AddEdgeDlg *aDlg =
- new SMESHGUI_AddEdgeDlg(parent, "", Sel);
- }
- else
- {
- QApplication::restoreOverrideCursor();
- QAD_MessageBox::warn1(QAD_Application::getDesktop(),
- tr("SMESH_WRN_WARNING"), tr("SMESH_WRN_VIEWER_VTK"),
- tr("SMESH_BUT_YES"));
- }
- break;
- }
- case 4021: // TRIANGLE
- {
- if (smeshGUI->myActiveStudy->getActiveStudyFrame()->getTypeView() ==
- VIEW_VTK)
- { //VTK
- smeshGUI->EmitSignalDeactivateDialog();
- SALOME_Selection *Sel =
- SALOME_Selection::Selection(smeshGUI->myActiveStudy->
- getSelection());
- Sel->ClearIObjects();
- smeshGUI->myDesktop->SetSelectionMode(1, true);
- parent->menuBar()->setItemChecked(9010, false);
- parent->menuBar()->setItemChecked(9011, false);
- smeshGUI->ViewNodes();
- SMESHGUI_AddFaceDlg *aDlg =
- new SMESHGUI_AddFaceDlg(parent, "", Sel, 3);
- }
- else
- {
- QApplication::restoreOverrideCursor();
- QAD_MessageBox::warn1(QAD_Application::getDesktop(),
- tr("SMESH_WRN_WARNING"), tr("SMESH_WRN_VIEWER_VTK"),
- tr("SMESH_BUT_YES"));
- }
- break;
- }
- case 4022: // QUAD
- {
- if (smeshGUI->myActiveStudy->getActiveStudyFrame()->getTypeView() ==
- VIEW_VTK)
- { //VTK
- smeshGUI->EmitSignalDeactivateDialog();
- SALOME_Selection *Sel =
- SALOME_Selection::Selection(smeshGUI->myActiveStudy->
- getSelection());
- Sel->ClearIObjects();
- smeshGUI->myDesktop->SetSelectionMode(1, true);
- parent->menuBar()->setItemChecked(9010, false);
- parent->menuBar()->setItemChecked(9011, false);
- smeshGUI->ViewNodes();
- SMESHGUI_AddFaceDlg *aDlg =
- new SMESHGUI_AddFaceDlg(parent, "", Sel, 4);
- }
- else
- {
- QApplication::restoreOverrideCursor();
- QAD_MessageBox::warn1(QAD_Application::getDesktop(),
- tr("SMESH_WRN_WARNING"), tr("SMESH_WRN_VIEWER_VTK"),
- tr("SMESH_BUT_YES"));
- }
- break;
- }
- case 4031: // TETRA
- {
- if (smeshGUI->myActiveStudy->getActiveStudyFrame()->getTypeView() ==
- VIEW_VTK)
- { //VTK
- smeshGUI->EmitSignalDeactivateDialog();
- SALOME_Selection *Sel =
- SALOME_Selection::Selection(smeshGUI->myActiveStudy->
- getSelection());
- Sel->ClearIObjects();
- smeshGUI->myDesktop->SetSelectionMode(1, true);
- parent->menuBar()->setItemChecked(9010, false);
- parent->menuBar()->setItemChecked(9011, false);
- smeshGUI->ViewNodes();
- SMESHGUI_AddVolumeDlg *aDlg =
- new SMESHGUI_AddVolumeDlg(parent, "", Sel, 4);
- }
- else
- {
- QApplication::restoreOverrideCursor();
- QAD_MessageBox::warn1(QAD_Application::getDesktop(),
- tr("SMESH_WRN_WARNING"), tr("SMESH_WRN_VIEWER_VTK"),
- tr("SMESH_BUT_YES"));
- }
- break;
- }
- case 4032: // HEXA
- {
- if (smeshGUI->myActiveStudy->getActiveStudyFrame()->getTypeView() ==
- VIEW_VTK)
- { //VTK
- smeshGUI->EmitSignalDeactivateDialog();
- SALOME_Selection *Sel =
- SALOME_Selection::Selection(smeshGUI->myActiveStudy->
- getSelection());
- Sel->ClearIObjects();
- smeshGUI->myDesktop->SetSelectionMode(1, true);
- parent->menuBar()->setItemChecked(9010, false);
- parent->menuBar()->setItemChecked(9011, false);
- smeshGUI->ViewNodes();
- SMESHGUI_AddVolumeDlg *aDlg =
- new SMESHGUI_AddVolumeDlg(parent, "", Sel, 8);
- }
- else
- {
- QApplication::restoreOverrideCursor();
- QAD_MessageBox::warn1(QAD_Application::getDesktop(),
- tr("SMESH_WRN_WARNING"), tr("SMESH_WRN_VIEWER_VTK"),
- tr("SMESH_BUT_YES"));
- }
- break;
- }
-
- case 4041: // REMOVES NODES
- {
- if (smeshGUI->myActiveStudy->getActiveStudyFrame()->getTypeView() ==
- VIEW_VTK)
- { //VTK
- smeshGUI->EmitSignalDeactivateDialog();
- SALOME_Selection *Sel =
- SALOME_Selection::Selection(smeshGUI->myActiveStudy->
- getSelection());
- Sel->ClearIObjects();
- smeshGUI->myDesktop->SetSelectionMode(1, true);
- parent->menuBar()->setItemChecked(9010, false);
- parent->menuBar()->setItemChecked(9011, false);
- smeshGUI->ViewNodes();
- SMESHGUI_RemoveNodesDlg *aDlg =
- new SMESHGUI_RemoveNodesDlg(parent, "", Sel);
- }
- else
- {
- QApplication::restoreOverrideCursor();
- QAD_MessageBox::warn1(QAD_Application::getDesktop(),
- tr("SMESH_WRN_WARNING"), tr("SMESH_WRN_VIEWER_VTK"),
- tr("SMESH_BUT_YES"));
- }
- break;
- }
- case 4042: // REMOVES ELEMENTS
- {
- if (smeshGUI->myActiveStudy->getActiveStudyFrame()->getTypeView() ==
- VIEW_VTK)
- { //VTK
- smeshGUI->EmitSignalDeactivateDialog();
- SALOME_Selection *Sel =
- SALOME_Selection::Selection(smeshGUI->myActiveStudy->
- getSelection());
- Sel->ClearIObjects();
- smeshGUI->myDesktop->SetSelectionMode(3, true);
- SMESHGUI_RemoveElementsDlg *aDlg =
- new SMESHGUI_RemoveElementsDlg(parent, "", Sel);
- }
- else
- {
- QApplication::restoreOverrideCursor();
- QAD_MessageBox::warn1(QAD_Application::getDesktop(),
- tr("SMESH_WRN_WARNING"), tr("SMESH_WRN_VIEWER_VTK"),
- tr("SMESH_BUT_YES"));
- }
- break;
- }
-
- case 5000: // HYPOTHESIS - ALGO
- {
- smeshGUI->CreateAlgorithm("Regular_1D", "Wire Discretisation");
- break;
- }
- case 5010:
- {
- smeshGUI->CreateAlgorithm("MEFISTO_2D", "Triangle (Mefisto)");
- break;
- }
- case 5011:
- {
- smeshGUI->CreateAlgorithm("Quadrangle_2D", "Quadrangle (Mapping)");
- break;
- }
- case 5020:
- {
- smeshGUI->CreateAlgorithm("Hexa_3D", "Hexahedron (i,j,k)");
- break;
- }
- case 5021:
- {
- smeshGUI->CreateAlgorithm("NETGEN_3D", "Tetrahedron (Netgen)");
- break;
- }
-
- case 5030: // HYPOTHESIS - LOCAL LENGTH
- {
- smeshGUI->EmitSignalDeactivateDialog();
- SALOME_Selection *Sel =
- SALOME_Selection::Selection(smeshGUI->myActiveStudy->
- getSelection());
- SMESHGUI_LocalLengthDlg *aDlg = new SMESHGUI_LocalLengthDlg(parent, "");
- break;
- }
- case 5031: // HYPOTHESIS - NB SEGMENTS
- {
- smeshGUI->EmitSignalDeactivateDialog();
- SALOME_Selection *Sel =
- SALOME_Selection::Selection(smeshGUI->myActiveStudy->
- getSelection());
- SMESHGUI_NbSegmentsDlg *aDlg = new SMESHGUI_NbSegmentsDlg(parent, "");
- break;
- }
-
- case 5032: // HYPOTHESIS - MAX ELEMENT AREA
- {
- smeshGUI->EmitSignalDeactivateDialog();
- SALOME_Selection *Sel =
- SALOME_Selection::Selection(smeshGUI->myActiveStudy->
- getSelection());
- SMESHGUI_MaxElementAreaDlg *aDlg =
- new SMESHGUI_MaxElementAreaDlg(parent, "");
- break;
- }
-
- case 5033: // HYPOTHESIS - MAX ELEMENT VOLUME
- {
- smeshGUI->EmitSignalDeactivateDialog();
- SALOME_Selection *Sel =
- SALOME_Selection::Selection(smeshGUI->myActiveStudy->
- getSelection());
- SMESHGUI_MaxElementVolumeDlg *aDlg =
- new SMESHGUI_MaxElementVolumeDlg(parent, "");
- break;
- }
-
- case 5034: // HYPOTHESIS - LENGTH FROM EDGES
- {
- SMESH::SMESH_Hypothesis_var Hyp;
- try
- {
- Hyp = smeshGUI->myComponentMesh->CreateHypothesis("LengthFromEdges", smeshGUI->myStudyId);
-
- if (!Hyp->_is_nil())
- {
- SALOMEDS::SObject_var SHyp = smeshGUI->myStudyAPI.AddNewHypothesis(Hyp);
- smeshGUI->myStudyAPI.SetName(SHyp, "LengthFromEdges");
- }
- }
- catch(const SALOME::SALOME_Exception & S_ex)
- {
- QtCatchCorbaException(S_ex);
- }
- smeshGUI->myActiveStudy->updateObjBrowser(true);
-
- break;
- }
-
- case 6016: // CONTROLS
- case 6015:
- case 6014:
- case 6013:
- case 6012:
- case 6011:
- case 6001:
- {
- SALOME_Selection *Sel =
- SALOME_Selection::Selection(smeshGUI->myActiveStudy->
- getSelection());
- int nbSel = Sel->IObjectCount();
- if (nbSel != 1)
- break;
- smeshGUI->Control(theCommandID);
- break;
- }
-
- case 6002:
- {
- if (smeshGUI->myActiveStudy->getActiveStudyFrame()->getTypeView() ==
- VIEW_VTK)
- { //VTK
- SALOME_Selection *Sel =
- SALOME_Selection::Selection(smeshGUI->myActiveStudy->
- getSelection());
- SMESHGUI_EdgesConnectivityDlg *Dlg =
- new SMESHGUI_EdgesConnectivityDlg(parent, "", Sel);
- }
- else
- {
- QApplication::restoreOverrideCursor();
- QAD_MessageBox::warn1(QAD_Application::getDesktop(),
- tr("SMESH_WRN_WARNING"), tr("SMESH_WRN_VIEWER_VTK"),
- tr("SMESH_BUT_YES"));
- }
- break;
- }
-
- case 9010:
- {
- if (!parent->menuBar()->isItemChecked(9010))
- {
- QApplication::setOverrideCursor(Qt::waitCursor);
- parent->menuBar()->setItemChecked(9011, false);
-
- smeshGUI->EraseSimulationActors();
- smeshGUI->mySimulationActors2D = vtkActor2DCollection::New();
-
- SALOME_Selection *Sel =
- SALOME_Selection::Selection(smeshGUI->myActiveStudy->
- getSelection());
- int nbSel = Sel->IObjectCount();
- if (nbSel == 1)
- {
- Standard_Boolean res;
- SMESH_Actor *MeshActor =
- smeshGUI->FindActorByEntry(Sel->firstIObject()->getEntry(),
- res, true);
- if (res)
- {
- parent->menuBar()->setItemChecked(9010,
- !parent->menuBar()->isItemChecked(9010));
-
- // It's necessary to display SMDS IDs instead of VTK ones, so
- // vtkIdFilter is unacceptable here. We have to do it manually :(
- vtkUnstructuredGrid *ptGrid = vtkUnstructuredGrid::New();
- ptGrid->CopyStructure(MeshActor->DataSource);
-
- int numPts = MeshActor->DataSource->GetNumberOfPoints();
-
- // Loop over points and generate ids
- vtkIntArray *ptIds = vtkIntArray::New();
- ptIds->SetNumberOfValues(numPts);
-
- for (int id = 0; id < numPts; id++)
- {
- int idSMDS = MeshActor->GetIdSMESHDSNode(id);
- ptIds->SetValue(id, idSMDS);
- }
-
-// mpv porting vtk4.2.2
- // vtkScalars* newScalars = vtkScalars::New();
- // newScalars->SetData(ptIds);
- // ptGrid->GetPointData()->SetScalars(newScalars);
- ptGrid->GetPointData()->SetScalars(ptIds);
- // newScalars->Delete();
-// mpv
- ptIds->Delete();
-
- vtkMaskPoints *mask = vtkMaskPoints::New();
- mask->SetInput(ptGrid);
- mask->SetOnRatio(1);
- // mask->SetMaximumNumberOfPoints( 50 );
- // mask->RandomModeOn();
-
- vtkSelectVisiblePoints *visPts =
- vtkSelectVisiblePoints::New();
- visPts->SetInput(mask->GetOutput());
- visPts->SetRenderer(((VTKViewer_ViewFrame *) smeshGUI->
- myActiveStudy->getActiveStudyFrame()->
- getRightFrame()->getViewFrame())->getRenderer());
- //visPts->SetSelectInvisible(1);
- visPts->SelectInvisibleOff();
- visPts->SetTolerance(0.1);
-
- vtkLabeledDataMapper *ldm = vtkLabeledDataMapper::New();
- ldm->SetInput(visPts->GetOutput());
- ldm->SetLabelFormat("%g");
- ldm->SetLabelModeToLabelScalars();
- //ldm->SetLabelModeToLabelFieldData();
-
- ldm->SetFontFamilyToTimes();
- ldm->SetFontSize(6 * parent->font().pointSize() / 5);
- ldm->SetBold(1);
- ldm->SetItalic(0);
- ldm->SetShadow(0);
-
- vtkActor2D *pointLabels = vtkActor2D::New();
- pointLabels->SetMapper(ldm);
- pointLabels->GetProperty()->SetColor(0, 1, 0);
-
- visPts->Delete();
- ldm->Delete();
- smeshGUI->mySimulationActors2D->AddItem(pointLabels);
- ((VTKViewer_ViewFrame *) smeshGUI->myActiveStudy->
- getActiveStudyFrame()->getRightFrame()->
- getViewFrame())->getRenderer()->AddActor2D(pointLabels);
- }
- }
- }
- else
- {
- QApplication::setOverrideCursor(Qt::waitCursor);
- parent->menuBar()->setItemChecked(9010,
- !parent->menuBar()->isItemChecked(9010));
- smeshGUI->EraseSimulationActors();
- smeshGUI->ScalarVisibilityOff();
- }
- QApplication::restoreOverrideCursor();
- break;
- }
- case 9011:
- {
- if (!parent->menuBar()->isItemChecked(9011))
- {
- QApplication::setOverrideCursor(Qt::waitCursor);
- parent->menuBar()->setItemChecked(9010, false);
-
- smeshGUI->EraseSimulationActors();
- smeshGUI->mySimulationActors2D = vtkActor2DCollection::New();
-
- SALOME_Selection *Sel =
- SALOME_Selection::Selection(smeshGUI->myActiveStudy->
- getSelection());
- int nbSel = Sel->IObjectCount();
- if (nbSel == 1)
- {
- Standard_Boolean res;
- SMESH_Actor *MeshActor =
- smeshGUI->FindActorByEntry(Sel->firstIObject()->getEntry(),
- res, true);
- if (res)
- {
- parent->menuBar()->setItemChecked(9011,
- !parent->menuBar()->isItemChecked(9011));
-
- // It's necessary to display SMDS IDs instead of VTK ones, so
- // vtkIdFilter is unacceptable here. We have to do it manually :(
- vtkUnstructuredGrid *elGrid = vtkUnstructuredGrid::New();
- elGrid->CopyStructure(MeshActor->DataSource);
-
- int numCells = MeshActor->DataSource->GetNumberOfCells();
-
- // Loop over points and generate ids
- vtkIntArray *cellIds = vtkIntArray::New();
- cellIds->SetNumberOfValues(numCells);
-
- for (int id = 0; id < numCells; id++)
- {
- int idSMDS = MeshActor->GetIdSMESHDSElement(id);
- cellIds->SetValue(id, idSMDS);
- }
-
-// mpv porting vk4.2.2
- // vtkScalars* newScalars = vtkScalars::New();
- // newScalars->SetData(cellIds);
- elGrid->GetCellData()->SetScalars(cellIds);
- // elGrid->GetCellData()->SetScalars(newScalars);
- // newScalars->Delete();
-//mpv
-
- cellIds->Delete();
-
- vtkCellCenters *cc = vtkCellCenters::New();
- cc->SetInput(elGrid);
-
- vtkSelectVisiblePoints *visCells =
- vtkSelectVisiblePoints::New();
- visCells->SetInput(cc->GetOutput());
- visCells->SetRenderer(((VTKViewer_ViewFrame *) smeshGUI->
- myActiveStudy->getActiveStudyFrame()->
- getRightFrame()->getViewFrame())->getRenderer());
- visCells->SelectInvisibleOff();
- visCells->SetTolerance(0.1);
- // visCells->SetSelectInvisible(1);
-
- vtkLabeledDataMapper *ldm = vtkLabeledDataMapper::New();
- ldm->SetInput(visCells->GetOutput());
- ldm->SetLabelFormat("%g");
- ldm->SetLabelModeToLabelScalars();
-
- ldm->SetFontFamilyToTimes();
- ldm->SetFontSize(6 * parent->font().pointSize() / 5);
- ldm->SetBold(1);
- ldm->SetItalic(0);
- ldm->SetShadow(0);
-
- vtkActor2D *cellLabels = vtkActor2D::New();
- cellLabels->SetMapper(ldm);
- cellLabels->GetProperty()->SetColor(1, 0, 0);
-
- cc->Delete();
- visCells->Delete();
- ldm->Delete();
- smeshGUI->mySimulationActors2D->AddItem(cellLabels);
- ((VTKViewer_ViewFrame *) smeshGUI->myActiveStudy->
- getActiveStudyFrame()->getRightFrame()->
- getViewFrame())->getRenderer()->AddActor2D(cellLabels);
- }
- }
- }
- else
- {
- QApplication::setOverrideCursor(Qt::waitCursor);
- parent->menuBar()->setItemChecked(9011,
- !parent->menuBar()->isItemChecked(9011));
- smeshGUI->EraseSimulationActors();
- smeshGUI->ScalarVisibilityOff();
- }
- QApplication::restoreOverrideCursor();
- break;
- }
-
- case 10001: // DISPLAY MODE PREFERENCE
- {
- parent->menuBar()->setItemChecked(10001,
- !parent->menuBar()->isItemChecked(10001));
- parent->menuBar()->setItemChecked(10002, false);
- parent->menuBar()->setItemChecked(10003, false);
- QAD_CONFIG->addSetting("SMESH:DisplayMode", "Wireframe");
- break;
- }
- case 10002:
- {
- parent->menuBar()->setItemChecked(10002,
- !parent->menuBar()->isItemChecked(10002));
- parent->menuBar()->setItemChecked(10001, false);
- parent->menuBar()->setItemChecked(10003, false);
- QAD_CONFIG->addSetting("SMESH:DisplayMode", "Shading");
- break;
- }
- case 10003:
- {
- parent->menuBar()->setItemChecked(10003,
- !parent->menuBar()->isItemChecked(10003));
- parent->menuBar()->setItemChecked(10002, false);
- parent->menuBar()->setItemChecked(10001, false);
- QAD_CONFIG->addSetting("SMESH:DisplayMode", "Shrink");
- break;
- }
-
- }
-
- smeshGUI->myActiveStudy->updateObjBrowser(true);
- return true;
-}
-
-//=============================================================================
-/*! function : GetMeshesUsingAlgoOrHypothesis()
- * purpose : return a list of Study objects (mesh kind) that have 'AlgoOrHyp' affected.
- * : However is supposed here that father of father of an hypothesis is a Mesh Object.
- */
-//=============================================================================
-SALOMEDS::Study::ListOfSObject *
- SMESHGUI::GetMeshesUsingAlgoOrHypothesis(SMESH::
- SMESH_Hypothesis_ptr AlgoOrHyp)
-{
- SALOMEDS::Study::ListOfSObject_var listSOmesh =
- new SALOMEDS::Study::ListOfSObject;
- listSOmesh->length(0);
- unsigned int index = 0;
- if (!AlgoOrHyp->_is_nil())
- {
- SALOMEDS::SObject_var SO_Hypothesis =
- smeshGUI->GetStudyAPI().FindHypothesisOrAlgorithms(AlgoOrHyp);
- if (!SO_Hypothesis->_is_nil())
- {
- SALOMEDS::Study::ListOfSObject_var listSO =
- smeshGUI->myStudy->FindDependances(SO_Hypothesis);
- for (unsigned int i = 0; i < listSO->length(); i++)
- {
- SALOMEDS::SObject_var SO = listSO[i];
- if (!SO->_is_nil())
- {
- SALOMEDS::SObject_var SOfatherFather =
- SO->GetFather()->GetFather();
- if (!SOfatherFather->_is_nil())
- {
- index++;
- listSOmesh->length(index);
- listSOmesh[index - 1] = SOfatherFather;
- }
- }
- }
- }
- }
- return listSOmesh._retn();
-}
-
-//=============================================================================
-/*!
- *
- */
-//=============================================================================
-void SMESHGUI::Export_Mesh(QAD_Desktop * parent, int theCommandID)
-{
- SALOME_Selection *Sel =
- SALOME_Selection::Selection(smeshGUI->myActiveStudy->getSelection());
- int nbSel = Sel->IObjectCount();
- if (nbSel == 1)
- {
- Standard_Boolean res;
- Handle(SALOME_InteractiveObject) IObject = Sel->firstIObject();
- SMESH::SMESH_Mesh_var aMesh = smeshGUI->ConvertIOinMesh(IObject, res);
- if (res)
- {
- QString filename;
- if (theCommandID == 122)
- { // EXPORT MED
- QString filename = QAD_FileDlg::getFileName(parent,
- "",
- tr("MED files (*.med)"),
- tr("Export mesh"),
- false);
- if (!filename.isEmpty())
- {
- QApplication::setOverrideCursor(Qt::waitCursor);
- aMesh->Export(filename.latin1(), "MED");
- QApplication::restoreOverrideCursor();
- }
- }
- else if (theCommandID == 121)
- { // EXPORT DAT
- QString filename = QAD_FileDlg::getFileName(parent,
- "",
- tr("DAT files (*.dat)"),
- tr("Export mesh"),
- false);
- if (!filename.isEmpty())
- {
- QApplication::setOverrideCursor(Qt::waitCursor);
- aMesh->Export(filename.latin1(), "DAT");
- QApplication::restoreOverrideCursor();
- }
- }
- else if (theCommandID == 123)
- { // EXPORT UNV
- QString filename = QAD_FileDlg::getFileName(parent,
- "",
- tr("IDEAS files (*.unv)"),
- tr("Export mesh"),
- false);
- if (!filename.isEmpty())
- {
- QApplication::setOverrideCursor(Qt::waitCursor);
- aMesh->Export(filename.latin1(), "UNV");
- QApplication::restoreOverrideCursor();
- }
- }
- else
- aMesh->Export(filename.latin1(), "DAT");
-
- if (IObject->hasEntry())
- {
- MESSAGE("---");
- SALOMEDS::SObject_var SO =
- smeshGUI->myStudy->FindObjectID(IObject->getEntry());
- SALOMEDS::GenericAttribute_var anAttr;
- SALOMEDS::AttributeComment_var aFileName;
-
- SALOMEDS::StudyBuilder_var aStudyBuilder =
- smeshGUI->myStudy->NewBuilder();
-
- anAttr =
- aStudyBuilder->FindOrCreateAttribute(SO, "AttributeComment");
- aFileName = SALOMEDS::AttributeComment::_narrow(anAttr);
- aFileName->SetValue(filename.latin1());
-
- // Add a MEDFILE attribute to make selection in Efficas
- if (theCommandID == 122)
- { // EXPORT MED
- QString medfilename="FICHIERMED"+filename;
- anAttr = aStudyBuilder->FindOrCreateAttribute(SO, "AttributeComment");
- SALOMEDS::AttributeComment_var MEDFileName;
- MEDFileName = SALOMEDS::AttributeComment::_narrow(anAttr);
- MEDFileName->SetValue(medfilename.latin1());
- } // EXPORT MED
- }
-
- QApplication::restoreOverrideCursor();
- }
- }
-}
-
-//=============================================================================
-/*!
- *
- */
-//=============================================================================
-void SMESHGUI::Import_Document(QAD_Desktop * parent, int theCommandID)
-{
- QString filter;
- string myExtension;
-
- if (theCommandID == 113)
- {
- filter = tr("MED files (*.med)");
- myExtension = string("MED");
- }
- else if (theCommandID == 112)
- {
- filter = tr("IDEAS files (*.unv)");
- myExtension = string("UNV");
- }
- else if (theCommandID == 111)
- {
- filter = tr("DAT files (*.dat)");
- myExtension = string("DAT");
- }
-
- QString filename = QAD_FileDlg::getFileName(parent, "", filter,
- tr("Import document"), true);
-
- if (!filename.isEmpty())
- {
- QApplication::setOverrideCursor(Qt::waitCursor);
- try
- {
- if (!myComponentMesh->_is_nil())
- {
- SMESH::SMESH_Mesh_var aMesh =
- myComponentMesh->Import(myStudyId, filename.latin1(),
- myExtension.c_str());
-
- if (!aMesh->_is_nil())
- {
- SALOMEDS::SObject_var SM = myStudyAPI.AddNewMesh(aMesh);
- myStudyAPI.SetName(SM, filename);
- }
- }
- }
- catch(const SALOME::SALOME_Exception & S_ex)
- {
- QtCatchCorbaException(S_ex);
- }
- myActiveStudy->updateObjBrowser(true);
- QApplication::restoreOverrideCursor();
- }
-}
-
-//=============================================================================
-/*!
- *
- */
-//=============================================================================
-bool SMESHGUI::OnMousePress(QMouseEvent * pe, QAD_Desktop * parent,
- QAD_StudyFrame * studyFrame)
-{
- SMESHGUI::GetOrCreateSMESHGUI(parent);
- return false;
-}
-
-//=============================================================================
-/*!
- *
- */
-//=============================================================================
-bool SMESHGUI::OnMouseMove(QMouseEvent * pe, QAD_Desktop * parent,
- QAD_StudyFrame * studyFrame)
-{
- SMESHGUI::GetOrCreateSMESHGUI(parent);
-
- return true;
-}
-
-//=============================================================================
-/*!
- *
- */
-//=============================================================================
-bool SMESHGUI::OnKeyPress(QKeyEvent * pe, QAD_Desktop * parent,
- QAD_StudyFrame * studyFrame)
-{
- SMESHGUI::GetOrCreateSMESHGUI(parent);
-
- return true;
-}
-
-//=============================================================================
-/*!
- *
- */
-//=============================================================================
-bool SMESHGUI::SetSettings(QAD_Desktop * parent)
-{
- SMESHGUI::GetOrCreateSMESHGUI(parent);
-
- /* Display mode */
- QString DisplayMode = QAD_CONFIG->getSetting("SMESH:DisplayMode");
- if (DisplayMode.compare("") == 0)
- {
- DisplayMode = "Shading";
- QAD_CONFIG->addSetting("SMESH:DisplayMode", "Shading");
- }
-
- if (DisplayMode.compare("Wireframe") == 0)
- {
- parent->menuBar()->setItemChecked(10003, false);
- parent->menuBar()->setItemChecked(10002, false);
- parent->menuBar()->setItemChecked(10001, true);
- }
- else if (DisplayMode.compare("Shading") == 0)
- {
- parent->menuBar()->setItemChecked(10003, false);
- parent->menuBar()->setItemChecked(10002, true);
- parent->menuBar()->setItemChecked(10001, false);
- }
- else if (DisplayMode.compare("Shrink") == 0)
- {
- parent->menuBar()->setItemChecked(10003, true);
- parent->menuBar()->setItemChecked(10002, false);
- parent->menuBar()->setItemChecked(10001, false);
- }
-
- /* Automatic Update */
- QString AutoUpdate = QAD_CONFIG->getSetting("SMESH:AutomaticUpdate");
- if (AutoUpdate.compare("true") == 0)
- {
- parent->menuBar()->setItemChecked(1001, true);
- smeshGUI->myAutomaticUpdate = true;
- }
- else
- {
- parent->menuBar()->setItemChecked(1001, false);
- smeshGUI->myAutomaticUpdate = false;
- }
-
- return true;
-}
-
-//=============================================================================
-/*!
- *
- */
-//=============================================================================
-void SMESHGUI::DefinePopup(QString & theContext, QString & theParent,
- QString & theObject)
-{
- /* Create or retrieve an object SMESHGUI */
- SMESHGUI::GetOrCreateSMESHGUI(QAD_Application::getDesktop());
-
- // NRI : Temporary added
- // if ( smeshGUI->myStudy->GetProperties()->IsLocked() ) {
- // theObject = "NothingSelected";
- // theContext = "NothingSelected";
- // }
- // NRI
-
- SALOME_Selection *Sel =
- SALOME_Selection::Selection(smeshGUI->myActiveStudy->getSelection());
- int nbSel = Sel->IObjectCount();
- if (nbSel == 0)
- {
- if (smeshGUI->myActiveStudy->getActiveStudyFrame()->getTypeView() ==
- VIEW_VTK)
- {
- vtkScalarBarActor *aScalarBar = smeshGUI->GetScalarBar();
- if ((aScalarBar != NULL) && (aScalarBar->GetVisibility() == 1))
- {
- theObject = "ScalarBar";
- theContext = "";
- }
- else
- {
- theObject = "NothingSelected";
- theContext = "NothingSelected";
- }
- }
- else
- {
- theObject = "NothingSelected";
- theContext = "NothingSelected";
- }
- }
- else if (nbSel == 1)
- {
- theObject = smeshGUI->CheckTypeObject(Sel->firstIObject());
- theContext = "";
- }
- else
- {
- theObject = smeshGUI->CheckHomogeneousSelection();
- theContext = "";
- }
-}
-
-//=============================================================================
-/*!
- *
- */
-//=============================================================================
-bool SMESHGUI::CustomPopup(QAD_Desktop * parent,
- QPopupMenu * popup,
- const QString & theContext,
- const QString & theParent, const QString & theObject)
-{
- // Popup should be customized for any viewer since some meaningless commands may be present in the popup
- //if (smeshGUI->myActiveStudy->getActiveStudyFrame()->getTypeView() != VIEW_VTK) //Test du type de viewer true=OCC false=VTK
- // return false;
- /* Create or retrieve an object SMESHGUI */
- SMESHGUI::GetOrCreateSMESHGUI(parent);
-
- // NRI : Temporary added
- // if ( smeshGUI->myStudy->GetProperties()->IsLocked() ) {
- // return false;
- // }
- // NRI
-
- SALOME_Selection *Sel =
- SALOME_Selection::Selection(smeshGUI->myActiveStudy->getSelection());
- QAD_StudyFrame *studyFrame = smeshGUI->myActiveStudy->getActiveStudyFrame();
- int nbSel = Sel->IObjectCount();
-
- if (nbSel == 0)
- {
- if (studyFrame->getTypeView() != VIEW_VTK)
- popup->clear();
- return false;
- }
- else if (nbSel == 1)
- {
- QString parentComp =
- ((SALOMEGUI_Desktop *) parent)->getComponentFromSelection();
- // First check type of active viewer (VTK required)
- if ( /*studyFrame->getTypeView() != VIEW_VTK || */ parentComp !=
- parent->getActiveComponent())
- {
- //MESSAGE("CustomPopup(): VTK viewer required, removing all SMESH-specific popup menu items")
- while (1)
- {
- int id = popup->idAt(0);
- if (id <= QAD_TopLabel_Popup_ID)
- popup->removeItemAt(0);
- else
- break;
- }
- if (theObject.compare("Component") == 0)
- {
- popup->removeItem(QAD_DisplayOnly_Popup_ID);
- }
- return false;
- }
-
- // Remove common popup items for Submesh, Hypothesis and Algorithm
- if (theObject.compare("SubMesh") == 0 ||
- theObject.compare("Hypothesis") == 0 ||
- theObject.compare("Algorithm") == 0)
- {
- popup->removeItem(QAD_Display_Popup_ID);
- popup->removeItem(QAD_DisplayOnly_Popup_ID);
- popup->removeItem(QAD_Erase_Popup_ID);
- int id = popup->idAt(popup->count() - 1); // last item
- if (id < 0 && id != -1)
- popup->removeItem(id); // separator
- }
-
- if (theObject.compare("Component") == 0)
- {
- popup->removeItem(QAD_DisplayOnly_Popup_ID);
- return true;
- }
-
- int id = QAD_TopLabel_Popup_ID; //popup->idAt(0);
- QFont f = QApplication::font();
- f.setBold(TRUE);
-
- Handle(SALOME_InteractiveObject) IObject = Sel->firstIObject();
-
- if (theParent.compare("Viewer") == 0)
- {
- if (popup->idAt(0) == id)
- {
- popup->removeItem(id);
- popup->insertItem(new CustomItem(QString(IObject->getName()),
- f), id, 0);
- }
-
- Standard_Boolean res;
- SMESH_Actor *ac =
- smeshGUI->FindActorByEntry(IObject->getEntry(), res, false);
- if (res && studyFrame->getTypeView() == VIEW_VTK)
- {
- VTKViewer_RenderWindowInteractor *myRenderInter =
- ((VTKViewer_ViewFrame *) studyFrame->getRightFrame()->
- getViewFrame())->getRWInteractor();
- if (myRenderInter->isVisible(IObject))
- {
- popup->removeItem(QAD_Display_Popup_ID);
- }
- else
- {
- popup->removeItem(QAD_Erase_Popup_ID);
- }
- }
- else
- {
- popup->removeItem(QAD_Erase_Popup_ID);
- if (!res)
- { // mesh not computed -> can't display it
- popup->removeItem(QAD_Display_Popup_ID);
- popup->removeItem(QAD_DisplayOnly_Popup_ID);
- popup->removeItemAt(popup->count() - 1); //separator
- }
- }
- }
- else if (theParent.compare("ObjectBrowser") == 0)
- {
- if (theObject.compare("Mesh") == 0 ||
- theObject.compare("SubMesh") == 0 ||
- theObject.compare("Hypothesis") == 0 ||
- theObject.compare("Algorithm") == 0)
- {
- popup->removeItemAt(0);
- }
- else
- {
- if (popup->idAt(0) == id)
- {
- popup->removeItem(id);
- popup->removeItemAt(0); //separator
- }
- }
-
- Standard_Boolean res;
- SMESH_Actor *ac =
- smeshGUI->FindActorByEntry(IObject->getEntry(), res, false);
- if (res && studyFrame->getTypeView() == VIEW_VTK)
- {
- VTKViewer_RenderWindowInteractor *myRenderInter =
- ((VTKViewer_ViewFrame *) studyFrame->getRightFrame()->
- getViewFrame())->getRWInteractor();
- if (myRenderInter->isVisible(IObject))
- {
- popup->removeItem(QAD_Display_Popup_ID);
- }
- else
- {
- popup->removeItem(QAD_Erase_Popup_ID);
- }
- }
- else
- {
- if (theObject.compare("Mesh") == 0 ||
- theObject.compare("SubMesh") == 0 ||
- theObject.compare("Hypothesis") == 0 ||
- theObject.compare("Algorithm") == 0)
- {
- }
- else
- {
- popup->removeItem(QAD_Erase_Popup_ID);
- if (!res)
- { // mesh not computed -> can't display it
- popup->removeItem(QAD_Display_Popup_ID);
- popup->removeItem(QAD_DisplayOnly_Popup_ID);
- popup->removeItemAt(popup->count() - 1); //separator
- }
- }
- }
- }
- }
- else
- {
- QString parentComp =
- ((SALOMEGUI_Desktop *) parent)->getComponentFromSelection();
- QAD_StudyFrame *studyFrame =
- smeshGUI->myActiveStudy->getActiveStudyFrame();
- if ( /*studyFrame->getTypeView() != VIEW_VTK || */ parentComp !=
- parent->getActiveComponent())
- {
- //MESSAGE("CustomPopup(): VTK viewer required, removing all SMESH-specific popup menu items")
- while (1)
- {
- int id = popup->idAt(0);
- if (id <= QAD_TopLabel_Popup_ID && id != -1)
- popup->removeItemAt(0);
- else
- break;
- }
- if (parentComp.isNull())
- { // objects from several components are selected
- popup->removeItem(QAD_DisplayOnly_Popup_ID);
- popup->removeItem(QAD_Display_Popup_ID);
- popup->removeItem(QAD_Erase_Popup_ID);
- int id = popup->idAt(popup->count() - 1); // last item
- if (id < 0 && id != -1)
- popup->removeItem(id); // separator
- }
- return false;
- }
-
- QString type = smeshGUI->CheckHomogeneousSelection();
- if (type.compare("Heterogeneous Selection") != 0)
- {
- int id = QAD_TopLabel_Popup_ID; //popup->idAt(0);
- QFont f = QApplication::font();
- f.setBold(TRUE);
- popup->removeItem(id);
- popup->insertItem(new CustomItem(QString("%1 ").arg(nbSel) + type +
- " (s) ", f), id, 0);
- }
- }
- return false;
-}
-
-/**
- * Ensures that the actor for the given <theIO> exists in the active VTK view
- * @TODO Handle multiple selection.
- */
-void SMESHGUI::BuildPresentation(const Handle(SALOME_InteractiveObject) & theIO)
-{
- MESSAGE("SMESHGUI::BuildPresentation("<<theIO->getEntry()<<")");
- /* Create or retrieve an object SMESHGUI */
- SMESHGUI::GetOrCreateSMESHGUI(QAD_Application::getDesktop());
-
- QAD_StudyFrame *activeFrame =
- smeshGUI->myActiveStudy->getActiveStudyFrame();
- if (activeFrame->getTypeView() == VIEW_VTK)
- {
- // VTK
- // Some ideas to handle multiple selection...
- /*SALOMEDS::SObject_var fatherSF =
- smeshGUI->myStudy->FindObjectID(activeFrame->entry());
-
- SALOME_Selection *Sel =
- SALOME_Selection::Selection(smeshGUI->myActiveStudy->
- getSelection());
- SALOME_ListIteratorOfListIO It(Sel->StoredIObjects());
-
- for(;It.More();It.Next()) {
- Handle(SALOME_InteractiveObject) IObject = It.Value();*/
- Handle(SALOME_InteractiveObject) IObject = theIO;
- if (IObject->hasEntry())
- {
- // Look for the actor in all views
- Standard_Boolean res;
- SMESH_Actor *ac =
- smeshGUI->FindActorByEntry(IObject->getEntry(), res, false);
-
- if (!res)
- {
- SALOMEDS::SObject_var aMorSM=smeshGUI->myStudy->FindObjectID( IObject->getEntry());
- SALOMEDS::GenericAttribute_var anAttr;
- SALOMEDS::AttributeIOR_var anIOR;
- if(aMorSM->FindAttribute(anAttr, "AttributeIOR"))
- {
- anIOR = SALOMEDS::AttributeIOR::_narrow(anAttr);
- SMESH::SMESH_Mesh_var aM =
- SMESH::SMESH_Mesh::_narrow( _orb->string_to_object(anIOR->Value()));
- if(!aM->_is_nil())
- {
- smeshGUI->InitActor(aM);
- ac = smeshGUI->ReadScript(aM);
- smeshGUI->DisplayActor( ac, true );
- smeshGUI->DisplayEdges( ac );
- smeshGUI->ChangeRepresentation( ac, ac->getDisplayMode() );
- }
- else
- {
- MESSAGE("Do not know how to display something which is not a SMESH_Mesh");
- }
- }
- else
- {
- MESSAGE("The object "<<theIO->getEntry()<<
- " do not have \"AttributeIOR\" attribute");
- }
- }
- else
- {
- // The actor exists in some view
- // Check whether the actor belongs to the active view
- VTKViewer_RenderWindowInteractor *rwInter =
- ((VTKViewer_ViewFrame *) activeFrame->getRightFrame()->
- getViewFrame())->getRWInteractor();
-
- // The actor belongs to inactive view -> create a copy and display it in the active view
- if (!rwInter->isInViewer(IObject))
- {
- if(ac->GetMapper()==NULL)
- {
- SMESH::SMESH_Mesh_var aMesh = smeshGUI->ConvertIOinMesh(theIO, res);
- ac=smeshGUI->ReadScript(aMesh);
- }
- SMESH_Actor *acCopy = SMESH_Actor::New();
- acCopy->ShallowCopy(ac);
- ac = acCopy;
- }
- smeshGUI->DisplayActor(ac, false);
- smeshGUI->DisplayEdges(ac);
- smeshGUI->ChangeRepresentation(ac, ac->getDisplayMode());
- }
- }
- }
- else
- {
- MESSAGE("BuildPresentation() must not be called while non-VTK view is active");
- }
-}
-
-//=============================================================================
-/*!
- *
- */
-//=============================================================================
-void SMESHGUI::setOrb()
-{
- try
- {
- ORB_INIT & init = *SINGLETON_ < ORB_INIT >::Instance();
- ASSERT(SINGLETON_ < ORB_INIT >::IsAlreadyExisting());
- _orb = init(0, 0);
- } catch(...)
- {
- INFOS("internal error : orb not found");
- _orb = 0;
- }
- ASSERT(!CORBA::is_nil(_orb));
-}
-
-/**
- * Get the history of all commands made in the SMESH server. This list of command
- * is used to display the mesh in the VTK view
- * @TODO Handle the REMOVE_ALL command.
- */
-SMESH_Actor *SMESHGUI::ReadScript(SMESH::SMESH_Mesh_ptr aMesh)
-{
- MESSAGE("SMESHGUI::ReadScript");
- SMESH_Actor *MeshActor;
- if (!aMesh->_is_nil())
- {
- Standard_Boolean result;
- MeshActor = FindActor(aMesh, result, false);
- if (result)
- {
- SMESH::log_array_var aSeq = aMesh->GetLog(true);
- MESSAGE("SMESHGUI::ReadScript: The log contains "<<aSeq->length()
- <<" commands.");
-
- for (unsigned int ind = 0; ind < aSeq->length(); ind++)
- {
- switch (aSeq[ind].commandType)
- {
- case SMESH::ADD_NODE:
- {
- AddNodes(MeshActor, aSeq[ind].number, aSeq[ind].coords,
- aSeq[ind].indexes);
- break;
- }
- case SMESH::ADD_EDGE:
- {
- AddEdges( MeshActor, aSeq[ind].number, aSeq[ind].coords, aSeq[ind].indexes );
- break;
- }
- case SMESH::ADD_TRIANGLE:
- {
- AddTriangles(MeshActor, aSeq[ind].number, aSeq[ind].coords,
- aSeq[ind].indexes);
- break;
- }
- case SMESH::ADD_QUADRANGLE:
- {
- AddQuadrangles(MeshActor, aSeq[ind].number,
- aSeq[ind].coords, aSeq[ind].indexes);
- break;
- }
- case SMESH::ADD_TETRAHEDRON:
- {
- AddTetras(MeshActor, aSeq[ind].number, aSeq[ind].coords,
- aSeq[ind].indexes);
- break;
- }
- case SMESH::ADD_PYRAMID:
- {
- break;
- }
- case SMESH::ADD_PRISM:
- {
- break;
- }
- case SMESH::ADD_HEXAHEDRON:
- {
- AddHexaedres(MeshActor, aSeq[ind].number, aSeq[ind].coords,
- aSeq[ind].indexes);
- break;
- }
- case SMESH::REMOVE_NODE:
- {
- RemoveNodes(MeshActor, aSeq[ind].number, aSeq[ind].coords,
- aSeq[ind].indexes);
- break;
- }
- case SMESH::REMOVE_ELEMENT:
- {
- RemoveElements(MeshActor, aSeq[ind].number,
- aSeq[ind].coords, aSeq[ind].indexes);
- break;
- }
- case SMESH::REMOVE_ALL:
- MESSAGE("REMOVE_ALL command not yet implemented");
- break;
- default: MESSAGE("Warning: Unknown script command.");
- }
- }
- return MeshActor;
- }
- }
- return NULL;
-}
-
-//=============================================================================
-/*!
- *
- */
-//=============================================================================
-void SMESHGUI::Dump(SMESH_Actor * Mactor)
-{
- vtkUnstructuredGrid *ugrid =
- vtkUnstructuredGrid::SafeDownCast(Mactor->DataSource);
- vtkPoints *Pts = ugrid->GetPoints();
- int nbPts = Pts->GetNumberOfPoints();
- int nbCells = ugrid->GetNumberOfCells();
-
- FILE *In;
- int i, j;
- In = fopen("/tmp/dumpMesh", "w+");
- fprintf(In, "%d %d\n", nbPts, nbCells);
- for (int i = 0; i < nbPts; i++)
- {
- float *p = ugrid->GetPoint(i);
- fprintf(In, "%d %e %e %e\n", i, p[0], p[1], p[2]);
- }
-
- for (int i = 0; i < nbCells; i++)
- {
- fprintf(In, "%d %d", i, ugrid->GetCell(i)->GetCellType());
- vtkIdList *Id = ugrid->GetCell(i)->GetPointIds();
- for (j = 0; j < Id->GetNumberOfIds(); j++)
- {
- fprintf(In, " %d", Id->GetId(j));
- }
- fprintf(In, "\n");
- }
- fclose(In);
-}
-
-//=============================================================================
-/*!
- *
- */
-//=============================================================================
-void SMESHGUI::AddNodes(SMESH_Actor * Mactor, int number,
- const SMESH::double_array & coords, const SMESH::long_array & indexes)
-{
- //MESSAGE("SMESHGUI::AddNodes(number="<<number<<", indexes.length()="<<indexes.length()<<")");
- QApplication::setOverrideCursor(Qt::waitCursor);
- if (Mactor->GetMapper() == NULL)
- {
- vtkPoints *Pts = vtkPoints::New();
- SMESH_Grid *ugrid = SMESH_Grid::New();
- ugrid->Allocate();
-
- int i = 1;
- int j = 1;
- while (i <= number)
- {
- int idVTK =
- Pts->InsertNextPoint(coords[j - 1], coords[j], coords[j + 1]);
- //Mactor->AddNode( indexes[i-1], idVTK );
- ugrid->AddNode(indexes[i - 1], idVTK);
- i++;
- j = j + 3;
- }
- //vtkUnstructuredGrid *ugrid = vtkUnstructuredGrid::New();
- ugrid->SetPoints(Pts);
- vtkDataSetMapper *PtsMapper = vtkDataSetMapper::New();
- PtsMapper->SetInput(ugrid);
- Mactor->DataSource = PtsMapper->GetInput();
- Mactor->SetMapper(PtsMapper);
- }
- else
- {
- //vtkUnstructuredGrid* ugrid = vtkUnstructuredGrid::SafeDownCast( Mactor->DataSource );
- SMESH_Grid *ugrid = SMESH_Grid::SafeDownCast(Mactor->DataSource);
- int i = 1;
- int j = 1;
- while (i <= number)
- {
- int idVTK =
- ugrid->GetPoints()->InsertNextPoint(coords[j - 1], coords[j],
- coords[j + 1]);
- ugrid->AddNode(indexes[i - 1], idVTK);
- i++;
- j = j + 3;
- }
- vtkDataSetMapper *PtsMapper = vtkDataSetMapper::New();
- PtsMapper->SetInput(ugrid);
- Mactor->DataSource = PtsMapper->GetInput();
- Mactor->SetMapper(PtsMapper);
- }
- QApplication::restoreOverrideCursor();
-}
-
-//=============================================================================
-/*!
- *
- */
-//=============================================================================
-void SMESHGUI::AddNode(SMESH_Actor * Mactor, int idnode, float x, float y,
- float z)
-{
- QApplication::setOverrideCursor(Qt::waitCursor);
- MESSAGE("SMESHGUI::AddNode " << idnode << " : " << x << ";" << y << ";" << z);
-
- if (Mactor->GetMapper() == NULL)
- {
- vtkPoints *Pts = vtkPoints::New();
- int idVTK = Pts->InsertNextPoint(x, y, z);
- //Mactor->AddNode( idnode, idVTK );
- //vtkUnstructuredGrid *ugrid = vtkUnstructuredGrid::New();
- SMESH_Grid *ugrid = SMESH_Grid::New();
- ugrid->Allocate();
- ugrid->AddNode(idnode, idVTK);
- ugrid->SetPoints(Pts);
- vtkDataSetMapper *PtsMapper = vtkDataSetMapper::New();
- PtsMapper->SetInput(ugrid);
- Mactor->DataSource = PtsMapper->GetInput();
- Mactor->SetMapper(PtsMapper);
- }
- else
- {
- //vtkUnstructuredGrid* ugrid = vtkUnstructuredGrid::SafeDownCast( Mactor->DataSource );
- SMESH_Grid *ugrid = SMESH_Grid::SafeDownCast(Mactor->DataSource);
- int idVTK = ugrid->GetPoints()->InsertNextPoint(x, y, z);
- //Mactor->AddNode( idnode, idVTK );
- ugrid->AddNode(idnode, idVTK);
- vtkDataSetMapper *PtsMapper = vtkDataSetMapper::New();
- PtsMapper->SetInput(ugrid);
- Mactor->DataSource = PtsMapper->GetInput();
- Mactor->SetMapper(PtsMapper);
- }
- QApplication::restoreOverrideCursor();
-}
-
-//=============================================================================
-/*!
- *
- */
-//=============================================================================
-void SMESHGUI::RemoveNode(SMESH_Actor * Mactor, int idnode)
-{
- MESSAGE(" OLD RemoveNode method ")
-// int id = Mactor->GetIdVTKNode( idnode );
-// MESSAGE ( " RemoveNode id VTK " << id )
-// if ( Mactor->GetMapper() != NULL ) {
-// vtkUnstructuredGrid* ugrid = vtkUnstructuredGrid::SafeDownCast( Mactor->DataSource );
-// vtkUnstructuredGrid* newUgrid = vtkUnstructuredGrid::New();
-// vtkPoints *Pts = ugrid->GetPoints();
-// vtkPoints *newPts = vtkPoints::New();
-// int nbPts = Pts->GetNumberOfPoints();
-// bool findPt = false;
-// for ( int i = 0; i < nbPts; i++ ) {
-// if ( id != i ) {
-// if ( !findPt)
-// newPts->InsertPoint(i, Pts->GetPoint(i) );
-// else
-// newPts->InsertPoint(i-1, Pts->GetPoint(i) );
-// } else {
-// findPt = true;
-// Mactor->RemoveNode( idnode );
-// }
-// }
-// newUgrid->SetPoints(newPts);
-// int nbCells = ugrid->GetNumberOfCells();
-// for ( int i = 0; i < nbCells; i++ ) {
-// vtkIdList *Ids = ugrid->GetCell(i)->GetPointIds();
-// vtkIdList *newIds = vtkIdList::New();
-// int nbIds = Ids->GetNumberOfIds();
-// newIds->SetNumberOfIds(nbIds);
-// for ( int j = 0; j < nbIds; j++ ) {
-// int theid = Ids->GetId(j);
-// if ( theid > id ) {
-// newIds->SetId( j, theid-1 );
-// } else
-// newIds->SetId( j, theid );
-// }
-// int idSMDSel = Mactor->GetIdSMESHDSElement( i );
-// Mactor->RemoveElement( idSMDSel, false );
-// int idVTKel = newUgrid->InsertNextCell( ugrid->GetCell(i)->GetCellType(), newIds );
-// Mactor->AddElement( idSMDSel, idVTKel );
-// }
-// vtkDataSetMapper *Mapper = vtkDataSetMapper::New();
-// Mapper->SetInput( newUgrid );
-// Mactor->DataSource = Mapper->GetInput();
-// Mactor->SetMapper(Mapper);
-// UpdateView();
-// }
-}
-
-//=============================================================================
-/*!
- *
- */
-//=============================================================================
-void SMESHGUI::RemoveNodes(SMESH_Actor * Mactor, int number,
- const SMESH::double_array & coords, const SMESH::long_array & indexes)
-{
- QApplication::setOverrideCursor(Qt::waitCursor);
- int i = 1;
- while (i <= number)
- {
- Mactor->RemoveNode(indexes[i - 1]);
- i++;
- }
-
- TColStd_DataMapOfIntegerInteger newMapVTKNodes;
- TColStd_DataMapOfIntegerInteger newMapSMESHDSNodes;
- TColStd_DataMapOfIntegerInteger MapOldNodesToNewNodes;
-
- if (Mactor->GetMapper() != NULL)
- {
- SMESH_Grid *ugrid = SMESH_Grid::SafeDownCast(Mactor->DataSource);
- SMESH_Grid *newUgrid = SMESH_Grid::New();
- newUgrid->CopyMaps(ugrid);
-
- vtkPoints *Pts = ugrid->GetPoints();
- vtkPoints *newPts = vtkPoints::New();
- int nbPts = Pts->GetNumberOfPoints();
- int j = 0;
- for (int i = 0; i < nbPts; i++)
- {
- int idSMESHDSNode = Mactor->GetIdSMESHDSNode(i);
- if (idSMESHDSNode != -1)
- {
- newPts->InsertPoint(j, Pts->GetPoint(i));
-
- newMapVTKNodes.Bind(j, idSMESHDSNode);
- newMapSMESHDSNodes.Bind(idSMESHDSNode, j);
-
- MapOldNodesToNewNodes.Bind(i, j);
- j++;
- }
- }
-
- newUgrid->SetIdsVTKNode(newMapVTKNodes);
- newUgrid->SetIdsSMESHDSNode(newMapSMESHDSNodes);
- newUgrid->SetPoints(newPts);
-
- TColStd_DataMapOfIntegerInteger newMapElementSMDStoVTK;
- TColStd_DataMapOfIntegerInteger newMapElementVTKtoSMDS;
-
- int nbCells = ugrid->GetNumberOfCells();
- for (int i = 0; i < nbCells; i++)
- {
- vtkIdList *Ids = ugrid->GetCell(i)->GetPointIds();
- vtkIdList *newIds = vtkIdList::New();
- int nbIds = Ids->GetNumberOfIds();
- newIds->SetNumberOfIds(nbIds);
- bool isGood = true;
- for (int j = 0; j < nbIds; j++)
- {
- int theid = Ids->GetId(j);
- if (MapOldNodesToNewNodes.IsBound(theid))
- {
- newIds->SetId(j, MapOldNodesToNewNodes.Find(theid));
- }
- else
- {
- isGood = false;
- break;
- }
- }
-
- // Filtering out cells based on non-existing nodes
- if (isGood)
- {
- int idSMDSel = Mactor->GetIdSMESHDSElement(i);
- int idVTKel =
- newUgrid->InsertNextCell(ugrid->GetCell(i)->GetCellType(),
- newIds);
-
- newMapElementSMDStoVTK.Bind(idSMDSel, idVTKel);
- newMapElementVTKtoSMDS.Bind(idVTKel, idSMDSel);
- }
- }
-
- newUgrid->SetIdsVTKElement(newMapElementVTKtoSMDS);
- newUgrid->SetIdsSMESHDSElement(newMapElementSMDStoVTK);
-
- // Copy new data to the old DatSource: keep the single DataSource for all actors
- ugrid->DeepCopy(newUgrid);
-
- vtkDataSetMapper *Mapper = vtkDataSetMapper::New();
- Mapper->SetInput(ugrid);
- Mactor->SetMapper(Mapper);
-
- // Commented to avoid multiple viewer updates when called by ReadScript()
- //UpdateView();
-
- }
- QApplication::restoreOverrideCursor();
-}
+ QAD_MessageBox::warn1(QAD_Application::getDesktop(),
+ tr("SMESH_WRN_WARNING"), tr("SMESH_WRN_VIEWER_VTK"),
+ tr("SMESH_BUT_OK"));
+ }
+ break;
+ }
+
+ case 5000: // HYPOTHESIS
+ {
+ if(checkLock(aStudy)) break;
+ smeshGUI->EmitSignalDeactivateDialog();
+ SMESHGUI_CreateHypothesesDlg *aDlg =
+ new SMESHGUI_CreateHypothesesDlg (parent, "", FALSE, false);
+ break;
+ }
+ case 5010: // ALGO
+ {
+ if(checkLock(aStudy)) break;
+ smeshGUI->EmitSignalDeactivateDialog();
+ SMESHGUI_CreateHypothesesDlg *aDlg =
+ new SMESHGUI_CreateHypothesesDlg (parent, "", FALSE, true);
+ break;
+ }
+
+ case 6016: // CONTROLS
+ case 6015:
+ case 6014:
+ case 6013:
+ case 6012:
+ case 6011:
+ case 6001:
+ case 6003:
+ case 6004:
+ if ( smeshGUI->myActiveStudy->getActiveStudyFrame()->getTypeView() == VIEW_VTK ) {
+ SALOME_Selection *Sel = SALOME_Selection::Selection(smeshGUI->myActiveStudy->getSelection());
+ if ( Sel->IObjectCount() == 1 && Sel->firstIObject()->hasEntry() ) {
+ SALOMEDS::SObject_var SO = smeshGUI->myStudy->FindObjectID( Sel->firstIObject()->getEntry() );
+ if ( !SO->_is_nil() ) {
+ CORBA::Object_var aObject = SO->GetObject();
+ SMESH::SMESH_Mesh_var aMesh = SMESH::SMESH_Mesh::_narrow( aObject );
+ SMESH::SMESH_subMesh_var aSubMesh = SMESH::SMESH_subMesh::_narrow( aObject );
+ SMESH::SMESH_Group_var aGroup = SMESH::SMESH_Group::_narrow( aObject );
+ if ( !aMesh->_is_nil() || !aSubMesh->_is_nil() || !aGroup->_is_nil() ) {
+ smeshGUI->Control( theCommandID );
+ break;
+ }
+ }
+ }
+ QAD_MessageBox::warn1(smeshGUI->GetDesktop(),
+ tr( "SMESH_WRN_WARNING" ),
+ tr( "SMESH_BAD_SELECTION" ),
+ tr( "SMESH_BUT_OK" ) );
+ break;
+ }
+ else {
+ QAD_MessageBox::warn1(smeshGUI->GetDesktop(),
+ tr( "SMESH_WRN_WARNING" ),
+ tr( "NOT_A_VTK_VIEWER" ),
+ tr( "SMESH_BUT_OK" ) );
+ }
+ break;
+ case 9010:
+ {
+ SALOME_Selection *Sel = SALOME_Selection::Selection(smeshGUI->myActiveStudy->getSelection());
+ if (Sel->IObjectCount() == 1) {
+ Handle(SALOME_InteractiveObject) anIObject = Sel->firstIObject();
+ if(anIObject->hasEntry())
+ if(SMESH_Actor *anActor = ::FindActorByEntry(anIObject->getEntry())){
+ anActor->SetPointsLabeled( !anActor->GetPointsLabeled() );
+ }
+ }
+ break;
+ }
+ case 9011:
+ {
+ SALOME_Selection *Sel = SALOME_Selection::Selection(smeshGUI->myActiveStudy->getSelection());
+ if (Sel->IObjectCount() == 1) {
+ Handle(SALOME_InteractiveObject) anIObject = Sel->firstIObject();
+ if(anIObject->hasEntry())
+ if(SMESH_Actor *anActor = ::FindActorByEntry(anIObject->getEntry())){
+ anActor->SetCellsLabeled( !anActor->GetCellsLabeled() );
+ }
+ }
+ break;
+ }
+ case 10001: // DISPLAY MODE PREFERENCE
+ {
+ // Wireframe
+ parent->menuBar()->setItemChecked(10001, true);
+ parent->menuBar()->setItemChecked(10002, false);
+ parent->menuBar()->setItemChecked(10004, false);
+ parent->menuBar()->setItemEnabled(10003, true);
+ QAD_CONFIG->addSetting("SMESH:DisplayMode", "Wireframe");
+ break;
+ }
+ case 10002:
+ {
+ parent->menuBar()->setItemChecked(10002, true);
+ parent->menuBar()->setItemChecked(10001, false);
+ parent->menuBar()->setItemChecked(10004, false);
+ parent->menuBar()->setItemEnabled(10003, true);
+ QAD_CONFIG->addSetting("SMESH:DisplayMode", "Shading");
+ break;
+ }
+ case 10003:
+ {
+ parent->menuBar()->setItemChecked(10003,!parent->menuBar()->isItemChecked(10003));
+ QAD_CONFIG->addSetting("SMESH:Shrink", parent->menuBar()->isItemChecked(10003) ? "yes" : "no");
+ break;
+ }
+ case 10004:
+ {
+ parent->menuBar()->setItemChecked(10001, false);
+ parent->menuBar()->setItemChecked(10004, true);
+ parent->menuBar()->setItemChecked(10002, false);
+ parent->menuBar()->setItemEnabled(10003, false);
+ QAD_CONFIG->addSetting("SMESH:DisplayMode", "Nodes");
+ break;
+ }
+
+ }
+
+ smeshGUI->myActiveStudy->updateObjBrowser(true);
+ return true;
+}
//=============================================================================
-/*!
- *
+/*! function : GetMeshesUsingAlgoOrHypothesis()
+ * purpose : return a list of Study objects (mesh kind) that have 'AlgoOrHyp' affected.
+ * : However is supposed here that father of father of an hypothesis is a Mesh Object.
*/
-//=============================================================================
-void SMESHGUI::RemoveNodes(SMESH::SMESH_Mesh_ptr aMesh,
- const TColStd_MapOfInteger & MapIndex)
+//=============================================================================
+SALOMEDS::Study::ListOfSObject *
+ SMESHGUI::GetMeshesUsingAlgoOrHypothesis(SMESH::
+ SMESH_Hypothesis_ptr AlgoOrHyp)
{
- QApplication::setOverrideCursor(Qt::waitCursor);
- Standard_Boolean result;
- SMESH_Actor *ac = FindActor(aMesh, result, true);
- if (result)
- {
- SMESH::long_array_var anArrayOfIdeces = new SMESH::long_array;
- anArrayOfIdeces->length(MapIndex.Extent());
- TColStd_MapIteratorOfMapOfInteger ite(MapIndex);
- int i = 0;
- for (; ite.More(); ite.Next())
- {
- // MESSAGE ( " RemoveNode : id " << ac->GetIdSMESHDSNode(ite.Key()) )
- anArrayOfIdeces[i] = ac->GetIdSMESHDSNode(ite.Key());
- i++;
- }
- SMESH::SMESH_MeshEditor_var aMeshEditor = aMesh->GetMeshEditor();
- aMeshEditor->RemoveNodes(anArrayOfIdeces);
-
- }
- if (myAutomaticUpdate)
- {
- SMESH_Actor *Mesh = smeshGUI->ReadScript(aMesh);
- if (Mesh != NULL)
- {
- smeshGUI->DisplayActor(Mesh);
- smeshGUI->DisplayEdges(Mesh);
- smeshGUI->ChangeRepresentation(Mesh, Mesh->getDisplayMode());
- AddActorInSelection(Mesh);
- }
+ SALOMEDS::Study::ListOfSObject_var listSOmesh =
+ new SALOMEDS::Study::ListOfSObject;
+ listSOmesh->length(0);
+ unsigned int index = 0;
+ if (!AlgoOrHyp->_is_nil()) {
+ SALOMEDS::SObject_var SO_Hypothesis =
+ smeshGUI->GetStudyAPI().FindObject(AlgoOrHyp);
+ if (!SO_Hypothesis->_is_nil()) {
+ SALOMEDS::Study::ListOfSObject_var listSO =
+ smeshGUI->myStudy->FindDependances(SO_Hypothesis);
+ MESSAGE("SMESHGUI::GetMeshesUsingAlgoOrHypothesis(): dependency number ="<<listSO->length());
+ for (unsigned int i = 0; i < listSO->length(); i++) {
+ SALOMEDS::SObject_ptr SO = listSO[i];
+ if (!SO->_is_nil()) {
+ SALOMEDS::SObject_var aFather = SO->GetFather();
+ if (!aFather->_is_nil()) {
+ SALOMEDS::SObject_var SOfatherFather = aFather->GetFather();
+ if (!SOfatherFather->_is_nil()) {
+ MESSAGE("SMESHGUI::GetMeshesUsingAlgoOrHypothesis(): dependency added to list");
+ index++;
+ listSOmesh->length(index);
+ listSOmesh[index - 1] = SOfatherFather;
+ }
+ }
}
- QApplication::restoreOverrideCursor();
-}
-
-//=============================================================================
-/*!
- *
- */
-//=============================================================================
-void SMESHGUI::RemoveElement(SMESH_Actor * Mactor, int idelement)
-{
- MESSAGE(" OLD RemoveElement method ")
-// int id = Mactor->GetIdVTKElement( idelement );
-// MESSAGE ( " RemoveElement id VTK : " << id )
-// if ( Mactor->GetMapper() != NULL ) {
-// vtkUnstructuredGrid* ugrid = vtkUnstructuredGrid::SafeDownCast( Mactor->DataSource );
-// vtkUnstructuredGrid* newUgrid = vtkUnstructuredGrid::New();
-// int nbCells = ugrid->GetNumberOfCells();
-// for ( int i = 0; i < nbCells; i++ ) {
-// if ( id != i ) {
-// newUgrid->InsertNextCell( ugrid->GetCell(i)->GetCellType(),
-// ugrid->GetCell(i)->GetPointIds() );
-// } else
-// Mactor->RemoveElement( idelement );
-// }
-// newUgrid->SetPoints(ugrid->GetPoints());
-// vtkDataSetMapper *Mapper = vtkDataSetMapper::New();
-// Mapper->SetInput( newUgrid );
-// Mactor->DataSource = Mapper->GetInput();
-// Mactor->SetMapper(Mapper);
-// UpdateView();
-// }
+ }
+ }
+ }
+ MESSAGE("SMESHGUI::GetMeshesUsingAlgoOrHypothesis(): completed");
+ return listSOmesh._retn();
}
//=============================================================================
-/*!
- *
- */
-//=============================================================================
-void SMESHGUI::RemoveElements(SMESH_Actor * Mactor, int number,
- const SMESH::double_array & coords, const SMESH::long_array & indexes)
-{
- QApplication::setOverrideCursor(Qt::waitCursor);
- int i = 1;
- while (i <= number)
- {
- Mactor->RemoveElement(indexes[i - 1]);
- i++;
- }
- TColStd_DataMapOfIntegerInteger newMapElementSMDStoVTK;
- TColStd_DataMapOfIntegerInteger newMapElementVTKtoSMDS;
-
- if (Mactor->GetMapper() != NULL)
- {
- SMESH_Grid *ugrid = SMESH_Grid::SafeDownCast(Mactor->DataSource);
- SMESH_Grid *newUgrid = SMESH_Grid::New();
- newUgrid->CopyMaps(ugrid);
-
- int nbCells = ugrid->GetNumberOfCells();
- for (int i = 0; i < nbCells; i++)
- {
- int idSMESHDSElement = Mactor->GetIdSMESHDSElement(i);
- if (idSMESHDSElement != -1)
- {
- int newId =
- newUgrid->InsertNextCell(ugrid->GetCell(i)->GetCellType(),
- ugrid->GetCell(i)->GetPointIds());
- newMapElementSMDStoVTK.Bind(idSMESHDSElement, newId);
- newMapElementVTKtoSMDS.Bind(newId, idSMESHDSElement);
- }
- }
-
- newUgrid->SetIdsVTKElement(newMapElementVTKtoSMDS);
- newUgrid->SetIdsSMESHDSElement(newMapElementSMDStoVTK);
-
- newUgrid->SetPoints(ugrid->GetPoints());
-
- // Copy new data to the old DatSource: keep the single DataSource for all actors
- ugrid->DeepCopy(newUgrid);
-
- vtkDataSetMapper *Mapper = vtkDataSetMapper::New();
- Mapper->SetInput(ugrid);
- Mactor->SetMapper(Mapper);
-
- // Commented to avoid multiple viewer updates when called by ReadScript()
- //UpdateView();
- }
- QApplication::restoreOverrideCursor();
+/*!
+ *
+ */
+//=============================================================================
+void SMESHGUI::Import_Mesh(QAD_Desktop * parent, int theCommandID){
+ QString filter;
+ string myExtension;
+
+ if(theCommandID == 113){
+ filter = tr("MED files (*.med)");
+ }else if (theCommandID == 112){
+ filter = tr("IDEAS files (*.unv)");
+ }else if (theCommandID == 111){
+ filter = tr("DAT files (*.dat)");
+ }
+ QString filename = QAD_FileDlg::getFileName(parent,
+ "",
+ filter,
+ tr("Import mesh"),
+ true);
+ if(!filename.isEmpty()){
+ QAD_WaitCursor wc;
+ SMESH::mesh_array_var aMeshes;
+ try {
+ SMESH::DriverMED_ReadStatus res;
+ aMeshes = smeshGUI->myComponentMesh->CreateMeshesFromMED(filename.latin1(),
+ res);
+ if ( res > SMESH::DRS_OK ) {
+ wc.stop();
+ QAD_MessageBox::warn1(QAD_Application::getDesktop(),
+ tr("SMESH_WRN_WARNING"),
+ tr(QString("SMESH_DRS_%1").arg(res)),
+ tr("SMESH_BUT_OK"));
+ wc.start();
+
+ }
+ }
+ catch (const SALOME::SALOME_Exception& S_ex)
+ {
+ wc.stop();
+ QtCatchCorbaException(S_ex);
+ wc.start();
+ }
+ for ( int i = 0, n = aMeshes->length(); i < n; i++ ) {
+ SALOMEDS::SObject_var aMeshSO = smeshGUI->myStudyAPI.FindObject( aMeshes[i] );
+ if ( !aMeshSO->_is_nil() ) {
+ SALOMEDS::StudyBuilder_var aBuilder = smeshGUI->myStudy->NewBuilder();
+ SALOMEDS::AttributePixMap_var aPixmap = SALOMEDS::AttributePixMap::_narrow( aBuilder->FindOrCreateAttribute( aMeshSO, "AttributePixMap" ) );
+ aPixmap->SetPixMap( "ICON_SMESH_TREE_MESH_IMPORTED" );
+ }
+ }
+ }
}
//=============================================================================
*
*/
//=============================================================================
-void SMESHGUI::RemoveElements(SMESH::SMESH_Mesh_ptr aMesh,
- const TColStd_MapOfInteger & MapIndex)
+void SMESHGUI::Export_Mesh(QAD_Desktop * parent, int theCommandID)
{
- QApplication::setOverrideCursor(Qt::waitCursor);
- Standard_Boolean result;
- SMESH_Actor *ac = FindActor(aMesh, result, true);
- if (result)
- {
- SMESH::long_array_var anArrayOfIdeces = new SMESH::long_array;
- anArrayOfIdeces->length(MapIndex.Extent());
- TColStd_MapIteratorOfMapOfInteger ite(MapIndex);
- int i = 0;
- for (; ite.More(); ite.Next())
- {
- // MESSAGE ( " RemoveElement : id " << ite.Key() << "," << ac->GetIdSMESHDSElement(ite.Key()) )
- anArrayOfIdeces[i] = ac->GetIdSMESHDSElement(ite.Key());
- i++;
- }
-
- SMESH::SMESH_MeshEditor_var aMeshEditor = aMesh->GetMeshEditor();
- aMeshEditor->RemoveElements(anArrayOfIdeces);
- }
-
- if (myAutomaticUpdate)
- {
- SMESH_Actor *Mesh = smeshGUI->ReadScript(aMesh);
- if (Mesh != NULL)
- {
- smeshGUI->DisplayActor(Mesh);
- smeshGUI->DisplayEdges(Mesh);
- smeshGUI->ChangeRepresentation(Mesh, Mesh->getDisplayMode());
- AddActorInSelection(Mesh);
-#ifdef TRACE
- Dump(Mesh);
-#endif
- }
- }
- QApplication::restoreOverrideCursor();
+ SALOME_Selection *Sel =
+ SALOME_Selection::Selection(smeshGUI->myActiveStudy->getSelection());
+ int nbSel = Sel->IObjectCount();
+ if ( !nbSel )
+ return;
+ Standard_Boolean res;
+ Handle(SALOME_InteractiveObject) IObject = Sel->firstIObject();
+ SMESH::SMESH_Mesh_var aMesh = smeshGUI->ConvertIOinMesh(IObject, res);
+ if ( res && ( nbSel == 1 || theCommandID == 122 ) ) {// MED export supports multiple meshes
+ QString aFilter, aTitle = tr("Export mesh");
+ switch ( theCommandID ) {
+ case 122:
+ aFilter = tr("MED files (*.med)");
+ break;
+ case 121:
+ aFilter = tr("DAT files (*.dat)");
+ break;
+ case 123:
+ aFilter = tr("IDEAS files (*.unv)");
+ break;
+ default:
+ break;
+ }
+
+ QString filename = QAD_FileDlg::getFileName(parent, "", aFilter, aTitle, false);
+
+ if ( !filename.isEmpty() ) {
+ // Check whether the file already exists and delete it if yes
+ QFile aFile( filename );
+ if ( aFile.exists() )
+ aFile.remove();
+
+ QAD_WaitCursor wc;
+ for ( SALOME_ListIteratorOfListIO it( Sel->StoredIObjects() ); it.More(); it.Next() ) {
+ aMesh = smeshGUI->ConvertIOinMesh( it.Value(), res );
+ if ( res ) {
+ switch ( theCommandID ) {
+ case 122:
+ aMesh->ExportMED( filename.latin1(), true ); // currently, automatic groups are always created
+ break;
+ case 121:
+ aMesh->ExportDAT( filename.latin1() );
+ break;
+ case 123:
+ aMesh->ExportUNV( filename.latin1() );
+ break;
+ default:
+ break;
+ }
+ }
+ }
+ }
+ }
}
//=============================================================================
*
*/
//=============================================================================
-void SMESHGUI::OrientationElements(SMESH::SMESH_Mesh_ptr aMesh,
- const TColStd_MapOfInteger & MapIndex)
+bool SMESHGUI::OnMousePress(QMouseEvent * pe, QAD_Desktop * parent,
+ QAD_StudyFrame * studyFrame)
{
- if (myActiveStudy->getActiveStudyFrame()->getTypeView() != VIEW_VTK)
- return;
-
- vtkRenderer *theRenderer =
- ((VTKViewer_ViewFrame *) myActiveStudy->getActiveStudyFrame()->
- getRightFrame()->getViewFrame())->getRenderer();
- Standard_Boolean result;
- SMESH_Actor *ac = FindActor(aMesh, result, true);
- if (result)
- {
- //vtkUnstructuredGrid* UGrid = vtkUnstructuredGrid::New();
- SMESH_Grid *UGrid = SMESH_Grid::New();
- SMESH_Grid *oldGrid = SMESH_Grid::SafeDownCast(ac->DataSource);
- UGrid->CopyMaps(oldGrid);
-
- vtkGeometryFilter *gf = vtkGeometryFilter::New();
- gf->SetInput(ac->DataSource);
-
- vtkPolyDataMapper *Mapper = vtkPolyDataMapper::New();
- Mapper->SetInput(gf->GetOutput());
- Mapper->Update();
-
- TColStd_MapIteratorOfMapOfInteger ite(MapIndex);
- for (; ite.More(); ite.Next())
- {
- Mapper->GetInput()->ReverseCell(ite.Key());
- }
-
- UGrid->SetPoints(Mapper->GetInput()->GetPoints());
- int nbCells = Mapper->GetInput()->GetNumberOfCells();
- for (int i = 0; i < nbCells; i++)
- {
- UGrid->InsertNextCell(Mapper->GetInput()->GetCellType(i),
- Mapper->GetInput()->GetCell(i)->GetPointIds());
- }
-
- // Copy new data to the old DatSource: keep the single DataSource for all actors
- oldGrid->DeepCopy(UGrid);
-
- vtkDataSetMapper *NewMapper = vtkDataSetMapper::New();
- //NewMapper->SetInput( UGrid );
- NewMapper->SetInput(oldGrid);
- NewMapper->Update();
-
- //ac->DataSource = NewMapper->GetInput();
- ac->SetMapper(NewMapper);
- }
- vtkRenderWindow *renWin = theRenderer->GetRenderWindow();
- renWin->Render();
- QApplication::restoreOverrideCursor();
+ return false;
}
//=============================================================================
*
*/
//=============================================================================
-void SMESHGUI::DiagonalInversion(SMESH::SMESH_Mesh_ptr aMesh,
- const TColStd_MapOfInteger & MapIndex)
+bool SMESHGUI::OnMouseMove(QMouseEvent * pe, QAD_Desktop * parent,
+ QAD_StudyFrame * studyFrame)
{
- if (myActiveStudy->getActiveStudyFrame()->getTypeView() != VIEW_VTK)
- return;
-
- QApplication::setOverrideCursor(Qt::waitCursor);
- vtkRenderer *theRenderer =
- ((VTKViewer_ViewFrame *) myActiveStudy->getActiveStudyFrame()->
- getRightFrame()->getViewFrame())->getRenderer();
- Standard_Boolean result;
-
- SMESH_Actor *ac = FindActor(aMesh, result, true);
- if (result)
- {
- //vtkUnstructuredGrid* UGrid = vtkUnstructuredGrid::New();
- SMESH_Grid *UGrid = SMESH_Grid::New();
- vtkGeometryFilter *gf = vtkGeometryFilter::New();
- gf->SetInput(ac->DataSource);
-
- vtkExtractEdges *edges = vtkExtractEdges::New();
- edges->SetInput(ac->DataSource);
-
- vtkPolyDataMapper *Mapper = vtkPolyDataMapper::New();
- Mapper->SetInput(edges->GetOutput());
- Mapper->Update();
-
- int nb = Mapper->GetInput()->GetNumberOfCells();
- //MESSAGE ( "nb : " << nb )
-
- TColStd_MapIteratorOfMapOfInteger ite(MapIndex);
- for (; ite.More(); ite.Next())
- {
- vtkCell *StartEdge = Mapper->GetInput()->GetCell(ite.Key());
- //MESSAGE( "DCQ : Edge Id = " << ite.Key())
- int CellType = StartEdge->GetCellType();
- //MESSAGE( "DCQ : Cell Type = " << CellType)
- int nbPoints = StartEdge->GetNumberOfPoints();
-
- //MESSAGE( "DCQ : Nb Point = " << nbPoints)
- if (nbPoints == 2)
- {
- vtkUnstructuredGrid *StartUGrid =
- vtkUnstructuredGrid::SafeDownCast(ac->DataSource);
-
- vtkIdList *IdCells = vtkIdList::New();
- vtkIdList *IdPoints = StartEdge->GetPointIds();
- float p1[3];
- float p2[3];
-
- Mapper->GetInput()->GetPoints()->GetPoint(IdPoints->GetId(0),
- p1);
- Mapper->GetInput()->GetPoints()->GetPoint(IdPoints->GetId(1),
- p2);
-
- int idp1 = StartUGrid->FindPoint(p1);
- int idp2 = StartUGrid->FindPoint(p2);
-
- StartUGrid->GetPointCells(idp1, IdCells);
-
- //MESSAGE ( " pt 0 : " << IdPoints->GetId(0) )
- //MESSAGE ( " pt 1 : " << IdPoints->GetId(1) )
-
- //MESSAGE ( " pt 0 : " << idp1 )
- //MESSAGE ( " pt 1 : " << idp2 )
-
- vtkIdList *IdPts = vtkIdList::New();
- if (IdCells->GetNumberOfIds() >= 2)
- {
- int nbCells = IdCells->GetNumberOfIds();
- //MESSAGE ( " nbCells : " << nbCells )
- for (int j = 0; j < nbCells; j++)
- {
- StartUGrid->GetCellPoints(IdCells->GetId(j), IdPts);
- if (IdPts->IsId(idp2) == -1)
- {
- IdCells->DeleteId(IdCells->GetId(j));
- }
- }
-
- //MESSAGE ( " IdCells " << IdCells->GetNumberOfIds() )
-
- vtkIdList *IdPts0 = vtkIdList::New();
- vtkIdList *IdPts1 = vtkIdList::New();
-
- if (IdCells->GetNumberOfIds() == 2)
- {
- StartUGrid->GetCellPoints(IdCells->GetId(0), IdPts0);
- StartUGrid->GetCellPoints(IdCells->GetId(1), IdPts1);
-
- //Create new faces
- TColStd_MapOfInteger EndMapIndex;
- for (int j = 0; j < 3; j++)
- {
- if (IdPts0->GetId(j) != idp1 &&
- IdPts0->GetId(j) != idp2)
- {
- EndMapIndex.Add(IdPts0->GetId(j));
- }
- if (IdPts1->GetId(j) != idp1 &&
- IdPts1->GetId(j) != idp2)
- {
- EndMapIndex.Add(IdPts1->GetId(j));
- }
- }
-
- bool MyAU = myAutomaticUpdate;
- myAutomaticUpdate = false;
-
- EndMapIndex.Add(idp1);
- TColStd_MapIteratorOfMapOfInteger ite1(EndMapIndex);
- int i = 1;
- while (ite1.More())
- {
- if (ite1.Key() == idp1)
- break;
- i++;
- ite1.Next();
- }
- bool reverse1 = (i == 2);
- this->AddFace(aMesh, EndMapIndex, reverse1);
-
- EndMapIndex.Remove(idp1);
- EndMapIndex.Add(idp2);
- TColStd_MapIteratorOfMapOfInteger ite2(EndMapIndex);
- i = 1;
- while (ite2.More())
- {
- if (ite2.Key() == idp2)
- break;
- i++;
- ite2.Next();
- }
- bool reverse2 = (i == 2);
- this->AddFace(aMesh, EndMapIndex,
- !(reverse1 == reverse2));
-
- myAutomaticUpdate = MyAU;
- //MESSAGE ( " myAutomaticUpdate = " << MyAU )
- Mapper->Update();
- //Remove old faces
- TColStd_MapOfInteger StartMapIndex;
- StartMapIndex.Add(IdCells->GetId(0));
- StartMapIndex.Add(IdCells->GetId(1));
- this->RemoveElements(aMesh, StartMapIndex);
-
- Mapper->Update();
- }
- }
- }
- }
-
- // UGrid->SetPoints( Mapper->GetInput()->GetPoints() );
- // int nbCells = Mapper->GetInput()->GetNumberOfCells();
- // for ( int i = 0; i < nbCells; i++ ) {
- // UGrid->InsertNextCell( Mapper->GetInput()->GetCellType(i), Mapper->GetInput()->GetCell(i)->GetPointIds() );
- // }
-
- // vtkDataSetMapper *NewMapper = vtkDataSetMapper::New();
- // NewMapper->SetInput( UGrid );
- // NewMapper->Update();
-
- // ac->DataSource = NewMapper->GetInput();
- // ac->SetMapper( NewMapper );
- }
- vtkRenderWindow *renWin = theRenderer->GetRenderWindow();
- renWin->Render();
- QApplication::restoreOverrideCursor();
+ return true;
}
//=============================================================================
*
*/
//=============================================================================
-void SMESHGUI::AddEdges(SMESH_Actor * Mactor, int number,
- const SMESH::double_array & coords, const SMESH::long_array & indexes)
+bool SMESHGUI::OnKeyPress(QKeyEvent * pe, QAD_Desktop * parent,
+ QAD_StudyFrame * studyFrame)
{
- QApplication::setOverrideCursor(Qt::waitCursor);
- //vtkUnstructuredGrid* ugrid = vtkUnstructuredGrid::SafeDownCast( Mactor->DataSource );
- SMESH_Grid *ugrid = SMESH_Grid::SafeDownCast(Mactor->DataSource);
- int i = 1;
- int j = 1;
- while (i <= number)
- {
- vtkIdList *Ids = vtkIdList::New();
- Ids->InsertNextId(Mactor->GetIdVTKNode(indexes[j]));
- Ids->InsertNextId(Mactor->GetIdVTKNode(indexes[j + 1]));
- int id = ugrid->InsertNextCell(VTK_LINE, Ids);
- Mactor->AddElement(indexes[j - 1], id);
- i++;
- j = j + 3;
- }
- vtkDataSetMapper *EdgeMapper = vtkDataSetMapper::New();
- EdgeMapper->SetInput(ugrid);
- Mactor->DataSource = EdgeMapper->GetInput();
- Mactor->SetMapper(EdgeMapper);
- QApplication::restoreOverrideCursor();
+ return true;
}
//=============================================================================
*
*/
//=============================================================================
-void SMESHGUI::AddEdge(SMESH_Actor * Mactor, int idedge, int idnode1,
- int idnode2)
+bool SMESHGUI::SetSettings(QAD_Desktop * parent)
{
- QApplication::setOverrideCursor(Qt::waitCursor);
- MESSAGE("SMESHGUI::AddEdge " << idedge << " : " << idnode1 << ";" <<
- idnode2) vtkIdList *Ids = vtkIdList::New();
- Ids->InsertNextId(Mactor->GetIdVTKNode(idnode1));
- Ids->InsertNextId(Mactor->GetIdVTKNode(idnode2));
-
- //vtkUnstructuredGrid* ugrid = vtkUnstructuredGrid::SafeDownCast( Mactor->DataSource );
- SMESH_Grid *ugrid = SMESH_Grid::SafeDownCast(Mactor->DataSource);
- int id = ugrid->InsertNextCell(VTK_LINE, Ids);
- Mactor->AddElement(idedge, id);
-
- MESSAGE(" Edge VTK id " << id)
- vtkDataSetMapper *EdgeMapper = vtkDataSetMapper::New();
- EdgeMapper->SetInput(ugrid);
- Mactor->DataSource = EdgeMapper->GetInput();
- Mactor->SetMapper(EdgeMapper);
- QApplication::restoreOverrideCursor();
+ MESSAGE("SMESHGUI::SetSettings.");
+ SMESHGUI::GetOrCreateSMESHGUI(parent);
+
+ /* Display mode */
+ QString DisplayMode = "Shading";
+ if ( QAD_CONFIG->hasSetting("SMESH:DisplayMode") )
+ DisplayMode = QAD_CONFIG->getSetting("SMESH:DisplayMode");
+ else
+ QAD_CONFIG->addSetting("SMESH:DisplayMode", "Shading");
+
+ bool Shrink = false;
+ if ( QAD_CONFIG->hasSetting("SMESH:Shrink") )
+ Shrink = QAD_CONFIG->getSetting("SMESH:Shrink") == "yes";
+
+ if (DisplayMode == "Wireframe") {
+ // wireframe
+ parent->menuBar()->setItemChecked(10004, false);
+ parent->menuBar()->setItemChecked(10002, false);
+ parent->menuBar()->setItemChecked(10001, true);
+ parent->menuBar()->setItemEnabled(10003, true);
+ }
+ else if (DisplayMode == "Nodes") {
+ // poins
+ parent->menuBar()->setItemChecked(10004, true);
+ parent->menuBar()->setItemChecked(10002, false);
+ parent->menuBar()->setItemChecked(10001, false);
+ parent->menuBar()->setItemEnabled(10003, false);
+ }
+ else {
+ // default is shading
+ parent->menuBar()->setItemChecked(10004, false);
+ parent->menuBar()->setItemChecked(10002, true);
+ parent->menuBar()->setItemChecked(10001, false);
+ parent->menuBar()->setItemEnabled(10003, true);
+ }
+ parent->menuBar()->setItemChecked(10003, Shrink);
+
+ /* Automatic Update */
+ QString AutoUpdate = QAD_CONFIG->getSetting("SMESH:AutomaticUpdate");
+ if (AutoUpdate.compare("true") == 0) {
+ parent->menuBar()->setItemChecked(1001, true);
+ smeshGUI->myAutomaticUpdate = true;
+ }
+ else {
+ parent->menuBar()->setItemChecked(1001, false);
+ smeshGUI->myAutomaticUpdate = false;
+ }
+
+ /* Selection */
+ ::UpdateSelectionProp();
+
+ /* menus disable */
+ parent->menuBar()->setItemEnabled(111, false); // IMPORT DAT
+ parent->menuBar()->setItemEnabled(112, false); // IMPORT UNV
+
+ return true;
}
//=============================================================================
*
*/
//=============================================================================
-void SMESHGUI::AddTriangles(SMESH_Actor * Mactor, int number,
- const SMESH::double_array & coords, const SMESH::long_array & indexes)
-{
-// MESSAGE("SMESHGUI::AddTriangles(number="<<number<<", indexes.length="
-// <<indexes.length()<<")");
-
- QApplication::setOverrideCursor(Qt::waitCursor);
- //vtkUnstructuredGrid* ugrid = vtkUnstructuredGrid::SafeDownCast( Mactor->DataSource );
- SMESH_Grid *ugrid = SMESH_Grid::SafeDownCast(Mactor->DataSource);
- int i = 1;
- int j = 1;
- while (i <= number)
- {
- vtkIdList *Ids = vtkIdList::New();
- Ids->InsertNextId(Mactor->GetIdVTKNode(indexes[j]));
- Ids->InsertNextId(Mactor->GetIdVTKNode(indexes[j + 1]));
- Ids->InsertNextId(Mactor->GetIdVTKNode(indexes[j + 2]));
- int id = ugrid->InsertNextCell(VTK_TRIANGLE, Ids);
- Mactor->AddElement(indexes[j - 1], id);
- i++;
- j = j + 4;
- }
- vtkDataSetMapper *TriMapper = vtkDataSetMapper::New();
- TriMapper->SetInput(ugrid);
- Mactor->DataSource = TriMapper->GetInput();
- Mactor->SetMapper(TriMapper);
- QApplication::restoreOverrideCursor();
-}
-void SMESHGUI::AddTriangle(SMESH_Actor * Mactor, int idtri, int idnode1,
- int idnode2, int idnode3)
+void SMESHGUI::DefinePopup(QString & theContext, QString & theParent, QString & theObject)
{
- QApplication::setOverrideCursor(Qt::waitCursor);
- vtkIdList *Ids = vtkIdList::New();
- Ids->InsertNextId(Mactor->GetIdVTKNode(idnode1));
- Ids->InsertNextId(Mactor->GetIdVTKNode(idnode2));
- Ids->InsertNextId(Mactor->GetIdVTKNode(idnode3));
-
- //vtkUnstructuredGrid* ugrid = vtkUnstructuredGrid::SafeDownCast( Mactor->DataSource );
- SMESH_Grid *ugrid = SMESH_Grid::SafeDownCast(Mactor->DataSource);
- int id = ugrid->InsertNextCell(VTK_TRIANGLE, Ids);
- Mactor->AddElement(idtri, id);
-
- vtkDataSetMapper *TriMapper = vtkDataSetMapper::New();
- TriMapper->SetInput(ugrid);
- Mactor->DataSource = TriMapper->GetInput();
- Mactor->SetMapper(TriMapper);
- QApplication::restoreOverrideCursor();
+ // NRI : Temporary added
+ // if ( smeshGUI->myStudy->GetProperties()->IsLocked() ) {
+ // theObject = "NothingSelected";
+ // theContext = "NothingSelected";
+ // }
+ // NRI
+
+ SALOME_Selection *Sel = SALOME_Selection::Selection( smeshGUI->myActiveStudy->getSelection() );
+ int nbSel = Sel->IObjectCount();
+ switch ( nbSel ) {
+ case 0:
+ theObject = "NothingSelected";
+ theContext = "NothingSelected";
+ break;
+ case 1:
+ if ( smeshGUI->myState == 800 && Sel->HasIndex( Sel->firstIObject() ) )
+ theObject = "Elements";
+ else
+ theObject = smeshGUI->CheckTypeObject( Sel->firstIObject() );
+ theContext = "";
+ break;
+ default:
+ theObject = smeshGUI->CheckHomogeneousSelection();
+ theContext = "";
+ }
}
//=============================================================================
*
*/
//=============================================================================
-void SMESHGUI::AddQuadrangles(SMESH_Actor * Mactor, int number,
- const SMESH::double_array & coords, const SMESH::long_array & indexes)
+bool SMESHGUI::CustomPopup(QAD_Desktop* parent, QPopupMenu* popup, const QString& theContext,
+ const QString& theParent, const QString& theObject)
{
- QApplication::setOverrideCursor(Qt::waitCursor);
- //vtkUnstructuredGrid* ugrid = vtkUnstructuredGrid::SafeDownCast( Mactor->DataSource );
- SMESH_Grid *ugrid = SMESH_Grid::SafeDownCast(Mactor->DataSource);
- int i = 1;
- int j = 1;
- while (i <= number)
- {
- vtkIdList *Ids = vtkIdList::New();
- Ids->InsertNextId(Mactor->GetIdVTKNode(indexes[j]));
- Ids->InsertNextId(Mactor->GetIdVTKNode(indexes[j + 1]));
- Ids->InsertNextId(Mactor->GetIdVTKNode(indexes[j + 2]));
- Ids->InsertNextId(Mactor->GetIdVTKNode(indexes[j + 3]));
- int id = ugrid->InsertNextCell(VTK_QUAD, Ids);
- Mactor->AddElement(indexes[j - 1], id);
- i++;
- j = j + 5;
- }
- vtkDataSetMapper *QuadMapper = vtkDataSetMapper::New();
- QuadMapper->SetInput(ugrid);
- Mactor->DataSource = QuadMapper->GetInput();
- Mactor->SetMapper(QuadMapper);
- QApplication::restoreOverrideCursor();
+ // get active study frame
+ QAD_StudyFrame* studyFrame = smeshGUI->myActiveStudy->getActiveStudyFrame();
+
+ // get parent component which selected object(s) belongs to
+ QString parentComp = ( (SALOMEGUI_Desktop*)parent )->getComponentFromSelection();
+
+ // get selection
+ SALOME_Selection* Sel = SALOME_Selection::Selection( smeshGUI->myActiveStudy->getSelection() );
+ int nbSel = Sel->IObjectCount();
+
+ if ( nbSel == 0 ) {
+ popup->clear();
+ }
+ else if ( nbSel == 1 ) {
+ if ( parentComp != parent->getActiveComponent() ) {
+ // object not belongs to SMESH module - remove all commands except common Display/Erase...
+ while ( 1 ) {
+ int id = popup->idAt( 0 );
+ if ( id <= QAD_TopLabel_Popup_ID )
+ popup->removeItemAt( 0 );
+ else
+ break;
+ }
+ }
+ else {
+ // get selected interactive object
+ Handle(SALOME_InteractiveObject) IObject = Sel->firstIObject();
+ SALOMEDS::SObject_var SO = smeshGUI->myStudy->FindObjectID( IObject->getEntry() );
+ // find popup menu's TopLabel item
+ int topItem = popup->indexOf( QAD_TopLabel_Popup_ID );
+ if ( topItem >= 0 ) {
+ if ( theParent == "Viewer" ) {
+ // set bold font for popup menu's TopLabel item (Viewer popup)
+ QFont fnt = QApplication::font(); fnt.setBold( TRUE );
+ popup->removeItem( QAD_TopLabel_Popup_ID );
+ popup->insertItem( new CustomItem( QString( IObject->getName() ), fnt ), QAD_TopLabel_Popup_ID, topItem );
+ }
+ else if ( theParent == "ObjectBrowser" ) {
+ // remove popup menu's TopLabel item (Object Browser popup)
+ popup->removeItem( QAD_TopLabel_Popup_ID );
+ }
+ }
+
+ // remove "Display only" command for component object
+ if ( theObject.compare( "Component" ) == 0 ) {
+ popup->removeItem( QAD_DisplayOnly_Popup_ID );
+ }
+ else if ( theObject == "Hypothesis" || theObject == "Algorithm" ) {
+ // remove Display/Erase commands
+ popup->removeItem( QAD_Display_Popup_ID );
+ popup->removeItem( QAD_DisplayOnly_Popup_ID );
+ popup->removeItem( QAD_Erase_Popup_ID );
+ // remove "Unassign ..." command if hyp/algo is not assigned
+ if ( SO->_is_nil() || !IObject->hasReference()/* !IsReferencedObject( SO ) */)
+ popup->removeItem( 1102 );
+ }
+ else if ( theObject == "Mesh" || theObject == "SubMesh" || theObject == "Group" ) {
+ // get actor
+ GEOM::GEOM_Shape_var aShape = GetSMESHGUI()->GetStudyAPI().GetShapeOnMeshOrSubMesh( SO );
+ if ( aShape->_is_nil() ) {
+ // imported mesh
+ popup->removeItem( 701 ); // Compute
+ popup->removeItem( 705 ); // Edit hypothesis
+ popup->removeItem( 706 ); // ...
+ }
+ SMESH_Actor* ac = ::FindActorByEntry(IObject->getEntry());
+ // if object has actor
+ if ( ac && studyFrame->getTypeView() == VIEW_VTK ) {
+ VTKViewer_RenderWindowInteractor* myRenderInter =
+ ( ( VTKViewer_ViewFrame* ) studyFrame->getRightFrame()->getViewFrame() )->getRWInteractor();
+ if ( myRenderInter->isVisible( IObject ) ) {
+ popup->removeItem( QAD_Display_Popup_ID );
+ popup->setItemChecked( 9010, ac->GetPointsLabeled() ); // Numbering / Display Nodes #
+ popup->setItemChecked( 9011, ac->GetCellsLabeled() ); // Numbering / Display Elements #
+ TVisualObjPtr aVisualObj = ac->GetObject();
+ int aNbEdges = aVisualObj->GetNbEntities(SMESH::EDGE);
+ int aNbFaces = aVisualObj->GetNbEntities(SMESH::FACE);
+ int aNbVolumes = aVisualObj->GetNbEntities(SMESH::VOLUME);
+ QMenuItem* mi = popup->findItem( 1131 );
+ if ( mi && mi->popup() ) {
+ int prType = ac->GetRepresentation();
+ // Display Mode / Wireframe
+ if(!aNbFaces && !aNbVolumes && !aNbEdges){
+ mi->popup()->removeItem( 211 );
+ }else{
+ mi->popup()->setItemChecked( 211, prType == SMESH_Actor::eEdge );
+ }
+ // Display Mode / Shading
+ if(!aNbFaces && !aNbVolumes){
+ mi->popup()->removeItem( 212 );
+ }else{
+ mi->popup()->setItemChecked( 212, prType == SMESH_Actor::eSurface );
+ }
+ // Display Mode / Points
+ mi->popup()->setItemChecked( 215, prType == SMESH_Actor::ePoint );
+ // Display Mode / Shrink
+ bool isShrunk = ac->IsShrunk();
+ bool isShrunkable = ac->IsShrunkable();
+ mi->popup()->setItemChecked( 213, isShrunk );
+ mi->popup()->setItemEnabled( 213, prType != SMESH_Actor::ePoint && isShrunkable);
+ }
+ // Scalar Bar
+ mi = popup->findItem( 2000 );
+ if ( mi && mi->popup() ) {
+ SMESH_Actor::eControl cMode = ac->GetControlMode();
+ switch ( cMode ) {
+ case SMESH_Actor::eLengthEdges:
+ mi->popup()->setItemChecked( 6001, true ); break;
+ case SMESH_Actor::eFreeBorders:
+ mi->popup()->setItemChecked( 6003, true );
+ mi->popup()->removeItem( 201 );
+ break;
+ case SMESH_Actor::eMultiConnection:
+ mi->popup()->setItemChecked( 6004, true ); break;
+ case SMESH_Actor::eArea:
+ mi->popup()->setItemChecked( 6011, true ); break;
+ case SMESH_Actor::eTaper:
+ mi->popup()->setItemChecked( 6012, true ); break;
+ case SMESH_Actor::eAspectRatio:
+ mi->popup()->setItemChecked( 6013, true ); break;
+ case SMESH_Actor::eMinimumAngle:
+ mi->popup()->setItemChecked( 6014, true ); break;
+ case SMESH_Actor::eWarping:
+ mi->popup()->setItemChecked( 6015, true ); break;
+ case SMESH_Actor::eSkew:
+ mi->popup()->setItemChecked( 6016, true ); break;
+ case SMESH_Actor::eNone:
+ default:
+ mi->popup()->removeItem( 200 );
+ mi->popup()->removeItem( 201 );
+ break;
+ }
+ TVisualObjPtr aVisualObj = ac->GetObject();
+ SMESH::ElementType aType;
+ if(!aNbEdges){
+ mi->popup()->removeItem( 6001 );
+ mi->popup()->removeItem( 6003 );
+ mi->popup()->removeItem( 6004 );
+ }
+ if(!aNbFaces){
+ mi->popup()->removeItem( 6011 );
+ mi->popup()->removeItem( 6012 );
+ mi->popup()->removeItem( 6013 );
+ mi->popup()->removeItem( 6014 );
+ mi->popup()->removeItem( 6015 );
+ mi->popup()->removeItem( 6016 );
+ }
+ if(!aNbFaces && !aNbEdges)
+ popup->removeItem( 2000 ); // Scalar Bar
+ }
+ }
+ else {
+ popup->removeItem( QAD_Erase_Popup_ID );
+ popup->removeItem( 114 ); // Numbering popup menu
+ popup->removeItem( 1131 ); // Display mode
+ popup->removeItem( 1132 ); // Color / size
+ popup->removeItem( 1133 ); // Transparency
+ popup->removeItem( 2000 ); // Scalar Bar
+ }
+ }
+ else {
+ // object doesn't have actor
+ CORBA::Object_var anObject = SO->GetObject();
+ bool bDisplay = false;
+ if ( !CORBA::is_nil( anObject ) ) {
+ SMESH::SMESH_Mesh_var aMeshObj = SMESH::SMESH_Mesh::_narrow( anObject );
+ if ( !aMeshObj->_is_nil() && ( aMeshObj->NbNodes() > 0 || aMeshObj->NbFaces() > 0 || aMeshObj->NbVolumes() > 0 ) )
+ bDisplay = true;
+ SMESH::SMESH_subMesh_var aSubMeshObj = SMESH::SMESH_subMesh::_narrow( anObject );
+ if ( !aSubMeshObj->_is_nil() && ( aSubMeshObj->GetNumberOfNodes() > 0 || aSubMeshObj->GetNumberOfElements() > 0 ) )
+ bDisplay = true;
+ SMESH::SMESH_Group_var aGroupObj = SMESH::SMESH_Group::_narrow( anObject );
+ if ( !aGroupObj->_is_nil() && aGroupObj->Size() > 0 )
+ bDisplay = true;
+ }
+ if ( !bDisplay ) {
+ popup->removeItem( QAD_Display_Popup_ID );
+ popup->removeItem( QAD_DisplayOnly_Popup_ID );
+ }
+ popup->removeItem( QAD_Erase_Popup_ID );
+ popup->removeItem( 114 ); // Numbering popup menu
+ popup->removeItem( 1131 ); // Display mode
+ popup->removeItem( 1132 ); // Color / size
+ popup->removeItem( 1133 ); // Transparency
+ popup->removeItem( 2000 ); // Scalar Bar
+ }
+ }
+ else {
+ // another SMESH object
+ popup->removeItem( QAD_Display_Popup_ID );
+ popup->removeItem( QAD_DisplayOnly_Popup_ID );
+ popup->removeItem( QAD_Erase_Popup_ID );
+ }
+ }
+ }
+ else {
+ // multiple selection
+ if ( parentComp != parent->getActiveComponent() ) {
+ // object not belongs to SMESH module - remove all commands except common Display/Erase...
+ while ( 1 ) {
+ int id = popup->idAt( 0 );
+ if ( id <= QAD_TopLabel_Popup_ID )
+ popup->removeItemAt( 0 );
+ else
+ break;
+ }
+ if ( parentComp.isNull() ) {
+ // objects from different components are selected
+ popup->removeItem( QAD_DisplayOnly_Popup_ID );
+ popup->removeItem( QAD_Display_Popup_ID );
+ popup->removeItem( QAD_Erase_Popup_ID );
+ }
+ }
+ else {
+ QString type = smeshGUI->CheckHomogeneousSelection();
+ if ( type != "Heterogeneous Selection" ) {
+ int topItem = popup->indexOf( QAD_TopLabel_Popup_ID );
+ if ( topItem >= 0 ) {
+ // set bold font for popup menu's TopLabel item
+ QFont fnt = QApplication::font(); fnt.setBold( TRUE );
+ popup->removeItem( QAD_TopLabel_Popup_ID );
+ popup->insertItem( new CustomItem( QString("%1 ").arg( nbSel ) + type + "(s) ", fnt ), QAD_TopLabel_Popup_ID, topItem );
+ }
+ }
+ }
+ }
+ return false;
}
//=============================================================================
-/*!
- *
+/*! Method: BuildPresentation(const Handle(SALOME_InteractiveObject)& theIO)
+ * Purpose: ensures that the actor for the given <theIO> exists in the active VTK view
*/
//=============================================================================
-void SMESHGUI::AddQuadrangle(SMESH_Actor * Mactor, int idquad, int idnode1,
- int idnode2, int idnode3, int idnode4)
+void SMESHGUI::BuildPresentation(const Handle(SALOME_InteractiveObject) & theIO)
{
- QApplication::setOverrideCursor(Qt::waitCursor);
- vtkIdList *Ids = vtkIdList::New();
- Ids->InsertNextId(Mactor->GetIdVTKNode(idnode1));
- Ids->InsertNextId(Mactor->GetIdVTKNode(idnode2));
- Ids->InsertNextId(Mactor->GetIdVTKNode(idnode3));
- Ids->InsertNextId(Mactor->GetIdVTKNode(idnode4));
-
- //vtkUnstructuredGrid* ugrid = vtkUnstructuredGrid::SafeDownCast( Mactor->DataSource );
- SMESH_Grid *ugrid = SMESH_Grid::SafeDownCast(Mactor->DataSource);
- int id = ugrid->InsertNextCell(VTK_QUAD, Ids);
- Mactor->AddElement(idquad, id);
-
- vtkDataSetMapper *QuadMapper = vtkDataSetMapper::New();
- QuadMapper->SetInput(ugrid);
- Mactor->DataSource = QuadMapper->GetInput();
- Mactor->SetMapper(QuadMapper);
- QApplication::restoreOverrideCursor();
+ if(theIO->hasEntry()){
+ QAD_Study* aStudy = SMESHGUI::GetSMESHGUI()->GetActiveStudy();
+ QAD_StudyFrame *aStudyFrame = aStudy->getActiveStudyFrame();
+ ::UpdateView(aStudyFrame,eDisplay,theIO->getEntry());
+ }
}
//=============================================================================
*
*/
//=============================================================================
-void SMESHGUI::AddTetras(SMESH_Actor * Mactor, int number,
- const SMESH::double_array & coords, const SMESH::long_array & indexes)
+void SMESHGUI::setOrb()
{
- QApplication::setOverrideCursor(Qt::waitCursor);
- //vtkUnstructuredGrid* ugrid = vtkUnstructuredGrid::SafeDownCast( Mactor->DataSource );
- SMESH_Grid *ugrid = SMESH_Grid::SafeDownCast(Mactor->DataSource);
- int i = 1;
- int j = 1;
- while (i <= number)
+ try
{
- vtkIdList *Ids = vtkIdList::New();
- Ids->InsertNextId(Mactor->GetIdVTKNode(indexes[j]));
- Ids->InsertNextId(Mactor->GetIdVTKNode(indexes[j + 1]));
- Ids->InsertNextId(Mactor->GetIdVTKNode(indexes[j + 2]));
- Ids->InsertNextId(Mactor->GetIdVTKNode(indexes[j + 3]));
- int id = ugrid->InsertNextCell(VTK_TETRA, Ids);
- Mactor->AddElement(indexes[j - 1], id);
- i++;
- j = j + 5;
+ ORB_INIT & init = *SINGLETON_ < ORB_INIT >::Instance();
+ ASSERT(SINGLETON_ < ORB_INIT >::IsAlreadyExisting());
+ _orb = init(0, 0);
+ } catch(...)
+ {
+ INFOS("internal error : orb not found");
+ _orb = 0;
}
- vtkDataSetMapper *TetraMapper = vtkDataSetMapper::New();
- TetraMapper->SetInput(ugrid);
- Mactor->DataSource = TetraMapper->GetInput();
- Mactor->SetMapper(TetraMapper);
- QApplication::restoreOverrideCursor();
+ ASSERT(!CORBA::is_nil(_orb));
}
//=============================================================================
*
*/
//=============================================================================
-void SMESHGUI::AddTetra(SMESH_Actor * Mactor, int idtetra, int idnode1,
- int idnode2, int idnode3, int idnode4)
-{
- QApplication::setOverrideCursor(Qt::waitCursor);
- MESSAGE("SMESHGUI::AddTetra " << idtetra << " : " << idnode1 << ";" <<
- idnode2 << ";" << idnode3 << ";" << idnode4) vtkIdList *Ids =
- vtkIdList::New();
- Ids->InsertNextId(Mactor->GetIdVTKNode(idnode1));
- Ids->InsertNextId(Mactor->GetIdVTKNode(idnode2));
- Ids->InsertNextId(Mactor->GetIdVTKNode(idnode3));
- Ids->InsertNextId(Mactor->GetIdVTKNode(idnode4));
-
- //vtkUnstructuredGrid* ugrid = vtkUnstructuredGrid::SafeDownCast( Mactor->DataSource );
- SMESH_Grid *ugrid = SMESH_Grid::SafeDownCast(Mactor->DataSource);
- int id = ugrid->InsertNextCell(VTK_TETRA, Ids);
- Mactor->AddElement(idtetra, id);
-
- MESSAGE(" Tetra VTK id " << id)
- vtkDataSetMapper *TetraMapper = vtkDataSetMapper::New();
- TetraMapper->SetInput(ugrid);
- Mactor->DataSource = TetraMapper->GetInput();
- Mactor->SetMapper(TetraMapper);
- QApplication::restoreOverrideCursor();
-}
+SMESH_Actor *SMESHGUI::ReadScript(SMESH::SMESH_Mesh_ptr theMesh){}
//=============================================================================
/*!
*
*/
//=============================================================================
-void SMESHGUI::AddHexaedres(SMESH_Actor * Mactor, int number,
- const SMESH::double_array & coords, const SMESH::long_array & indexes)
+void SMESHGUI::Dump(SMESH_Actor * Mactor)
{
- QApplication::setOverrideCursor(Qt::waitCursor);
- //vtkUnstructuredGrid* ugrid = vtkUnstructuredGrid::SafeDownCast( Mactor->DataSource );
- SMESH_Grid *ugrid = SMESH_Grid::SafeDownCast(Mactor->DataSource);
- int i = 1;
- int j = 1;
- while (i <= number)
+ vtkUnstructuredGrid *ugrid = Mactor->GetUnstructuredGrid();
+ vtkPoints *Pts = ugrid->GetPoints();
+ int nbPts = Pts->GetNumberOfPoints();
+ int nbCells = ugrid->GetNumberOfCells();
+
+ FILE *In;
+ int i, j;
+ In = fopen("/tmp/dumpMesh", "w+");
+ fprintf(In, "%d %d\n", nbPts, nbCells);
+ for (int i = 0; i < nbPts; i++)
{
- vtkIdList *Ids = vtkIdList::New();
- Ids->InsertNextId(Mactor->GetIdVTKNode(indexes[j]));
- Ids->InsertNextId(Mactor->GetIdVTKNode(indexes[j + 1]));
- Ids->InsertNextId(Mactor->GetIdVTKNode(indexes[j + 2]));
- Ids->InsertNextId(Mactor->GetIdVTKNode(indexes[j + 3]));
- Ids->InsertNextId(Mactor->GetIdVTKNode(indexes[j + 4]));
- Ids->InsertNextId(Mactor->GetIdVTKNode(indexes[j + 5]));
- Ids->InsertNextId(Mactor->GetIdVTKNode(indexes[j + 6]));
- Ids->InsertNextId(Mactor->GetIdVTKNode(indexes[j + 7]));
- int id = ugrid->InsertNextCell(VTK_HEXAHEDRON, Ids);
- Mactor->AddElement(indexes[j - 1], id);
- i++;
- j = j + 9;
+ float *p = ugrid->GetPoint(i);
+ fprintf(In, "%d %e %e %e\n", i, p[0], p[1], p[2]);
+ }
+
+ for (int i = 0; i < nbCells; i++)
+ {
+ fprintf(In, "%d %d", i, ugrid->GetCell(i)->GetCellType());
+ vtkIdList *Id = ugrid->GetCell(i)->GetPointIds();
+ for (j = 0; j < Id->GetNumberOfIds(); j++)
+ {
+ fprintf(In, " %d", Id->GetId(j));
+ }
+ fprintf(In, "\n");
}
- vtkDataSetMapper *HexaMapper = vtkDataSetMapper::New();
- HexaMapper->SetInput(ugrid);
- Mactor->DataSource = HexaMapper->GetInput();
- Mactor->SetMapper(HexaMapper);
- QApplication::restoreOverrideCursor();
+ fclose(In);
}
//=============================================================================
*
*/
//=============================================================================
-void SMESHGUI::AddHexaedre(SMESH_Actor * Mactor, int idhexa, int idnode1,
- int idnode2, int idnode3, int idnode4, int idnode5, int idnode6,
- int idnode7, int idnode8)
+void SMESHGUI::RemoveNodes(SMESH::SMESH_Mesh_ptr theMesh,
+ const TColStd_MapOfInteger & MapIndex)
{
- QApplication::setOverrideCursor(Qt::waitCursor);
- MESSAGE("SMESHGUI::AddHexaedre " << idhexa << " : " << idnode1 << ";" <<
- idnode2 << ";" << idnode3 << ";" << idnode4 << ";" << idnode5 << ";" <<
- idnode6 << ";" << idnode7 << ";" << idnode8) vtkIdList *Ids =
- vtkIdList::New();
- Ids->InsertNextId(Mactor->GetIdVTKNode(idnode1));
- Ids->InsertNextId(Mactor->GetIdVTKNode(idnode2));
- Ids->InsertNextId(Mactor->GetIdVTKNode(idnode3));
- Ids->InsertNextId(Mactor->GetIdVTKNode(idnode4));
- Ids->InsertNextId(Mactor->GetIdVTKNode(idnode5));
- Ids->InsertNextId(Mactor->GetIdVTKNode(idnode6));
- Ids->InsertNextId(Mactor->GetIdVTKNode(idnode7));
- Ids->InsertNextId(Mactor->GetIdVTKNode(idnode8));
-
- //vtkUnstructuredGrid *ugrid = vtkUnstructuredGrid::SafeDownCast( Mactor->DataSource );
- SMESH_Grid *ugrid = SMESH_Grid::SafeDownCast(Mactor->DataSource);
- int id = ugrid->InsertNextCell(VTK_HEXAHEDRON, Ids);
- Mactor->AddElement(idhexa, id);
-
- MESSAGE(" Hexa VTK id " << id)
- vtkDataSetMapper *HexaMapper = vtkDataSetMapper::New();
- HexaMapper->SetInput(ugrid);
- Mactor->DataSource = HexaMapper->GetInput();
- Mactor->SetMapper(HexaMapper);
- QApplication::restoreOverrideCursor();
+ QAD_WaitCursor wc;
+ try{
+ SALOMEDS::SObject_var aSobj = myStudyAPI.FindObject(theMesh);
+ CORBA::String_var anEntry = aSobj->GetID();
+ if(SMESH_Actor* anActor = ::FindActorByEntry(anEntry.in())){
+ SMESH::long_array_var anArrayOfIdeces = new SMESH::long_array;
+ anArrayOfIdeces->length(MapIndex.Extent());
+ TColStd_MapIteratorOfMapOfInteger ite(MapIndex);
+ for(int i = 0; ite.More(); ite.Next(), i++){
+ anArrayOfIdeces[i] = anActor->GetNodeObjId(ite.Key());
+ }
+ SMESH::SMESH_MeshEditor_var aMeshEditor = theMesh->GetMeshEditor();
+ aMeshEditor->RemoveNodes(anArrayOfIdeces);
+ if(myAutomaticUpdate){
+ CORBA::Long anId = smeshGUI->myStudy->StudyId();
+ if(TVisualObjPtr aVisualObj = GetVisualObj(anId,anEntry.in())){
+ aVisualObj->Update(true);
+ }
+ }
+ }
+ }catch(SALOME::SALOME_Exception& exc) {
+ INFOS("Follow exception was cought:\n\t"<<exc.details.text);
+ }catch(const std::exception& exc){
+ INFOS("Follow exception was cought:\n\t"<<exc.what());
+ }catch(...){
+ INFOS("Unknown exception was cought !!!");
+ }
}
-//=====================================================================================
-// EXPORTED METHODS
-//=====================================================================================
-extern "C"
+//=============================================================================
+/*!
+ *
+ */
+//=============================================================================
+void SMESHGUI::RemoveElements(SMESH::SMESH_Mesh_ptr theMesh,
+ const TColStd_MapOfInteger & MapIndex)
{
- bool OnGUIEvent(int theCommandID, QAD_Desktop * parent)
- {
- return SMESHGUI::OnGUIEvent(theCommandID, parent);
- }
-
- bool OnKeyPress(QKeyEvent * pe, QAD_Desktop * parent,
- QAD_StudyFrame * studyFrame)
- {
- return SMESHGUI::OnKeyPress(pe, parent, studyFrame);
- }
-
- bool OnMousePress(QMouseEvent * pe, QAD_Desktop * parent,
- QAD_StudyFrame * studyFrame)
- {
- return SMESHGUI::OnMousePress(pe, parent, studyFrame);
- }
-
- bool OnMouseMove(QMouseEvent * pe, QAD_Desktop * parent,
- QAD_StudyFrame * studyFrame)
- {
- return SMESHGUI::OnMouseMove(pe, parent, studyFrame);
- }
-
- bool SetSettings(QAD_Desktop * parent)
- {
- return SMESHGUI::SetSettings(parent);
- }
-
- bool customPopup(QAD_Desktop * parent, QPopupMenu * popup,
- const QString & theContext, const QString & theParent,
- const QString & theObject)
- {
- return SMESHGUI::CustomPopup(parent, popup, theContext, theParent,
- theObject);
- }
-
- void definePopup(QString & theContext, QString & theParent,
- QString & theObject)
- {
- SMESHGUI::DefinePopup(theContext, theParent, theObject);
- }
-
- bool activeStudyChanged(QAD_Desktop * parent)
- {
- SMESHGUI::activeStudyChanged(parent);
- }
-
- void buildPresentation(const Handle(SALOME_InteractiveObject) & theIO)
- {
- SMESHGUI::BuildPresentation(theIO);
- }
-
- void supportedViewType(int *buffer, int bufferSize)
- {
- if (!buffer || !bufferSize)
- return;
- buffer[0] = (int)VIEW_VTK;
- }
-
+ QAD_WaitCursor wc;
+ try{
+ SALOMEDS::SObject_var aSobj = myStudyAPI.FindObject(theMesh);
+ CORBA::String_var anEntry = aSobj->GetID();
+ if(SMESH_Actor* anActor = ::FindActorByEntry(anEntry.in())){
+ SMESH::long_array_var anArrayOfIdeces = new SMESH::long_array;
+ anArrayOfIdeces->length(MapIndex.Extent());
+ TColStd_MapIteratorOfMapOfInteger ite(MapIndex);
+ for(int i = 0; ite.More(); ite.Next(), i++){
+ anArrayOfIdeces[i] = anActor->GetElemObjId(ite.Key());
+ }
+ SMESH::SMESH_MeshEditor_var aMeshEditor = theMesh->GetMeshEditor();
+ aMeshEditor->RemoveElements(anArrayOfIdeces);
+ if(myAutomaticUpdate){
+ CORBA::Long anId = smeshGUI->myStudy->StudyId();
+ if(TVisualObjPtr aVisualObj = GetVisualObj(anId,anEntry.in())){
+ aVisualObj->Update(true);
+ }
+ }
+ }
+ }catch(SALOME::SALOME_Exception& exc) {
+ INFOS("Follow exception was cought:\n\t"<<exc.details.text);
+ }catch(const std::exception& exc){
+ INFOS("Follow exception was cought:\n\t"<<exc.what());
+ }catch(...){
+ INFOS("Unknown exception was cought !!!");
+ }
}
//=============================================================================
*
*/
//=============================================================================
-void SMESHGUI::ViewNodes()
+void SMESHGUI::OrientationElements(SMESH::SMESH_Mesh_ptr aMesh,
+ const TColStd_MapOfInteger & MapIndex)
{
- if (myActiveStudy->getActiveStudyFrame()->getTypeView() != VIEW_VTK)
- return;
-
- EraseSimulationActors();
- mySimulationActors = vtkActorCollection::New();
- vtkRenderer *theRenderer =
- ((VTKViewer_ViewFrame *) myActiveStudy->getActiveStudyFrame()->
- getRightFrame()->getViewFrame())->getRenderer();
- vtkActorCollection *theActors = theRenderer->GetActors();
- theActors->InitTraversal();
- vtkActor *ac = theActors->GetNextActor();
- while (!(ac == NULL))
- {
- if (ac->IsA("SMESH_Actor"))
- {
- SMESH_Actor *anActor = SMESH_Actor::SafeDownCast(ac);
- if (anActor->GetVisibility() == 1)
- {
- vtkGeometryFilter *gf = vtkGeometryFilter::New();
- gf->SetInput(anActor->DataSource);
- vtkMaskPoints *verts = vtkMaskPoints::New();
- verts->SetInput(gf->GetOutput());
- verts->GenerateVerticesOn();
- verts->SetOnRatio(1);
-
- vtkPolyDataMapper *vertMapper = vtkPolyDataMapper::New();
- vertMapper->SetInput(verts->GetOutput());
- vertMapper->ScalarVisibilityOff();
-
- vtkActor *vertActor = vtkActor::New();
- vertActor->SetMapper(vertMapper);
-
- float r, g, b;
- anActor->GetNodeColor(r, g, b);
- vertActor->GetProperty()->SetColor(r, g, b);
-
- vertActor->GetProperty()->SetPointSize(anActor->GetNodeSize());
-
- vertActor->PickableOff();
-
- mySimulationActors->AddItem(vertActor);
- theRenderer->AddActor(vertActor);
- }
- }
- ac = theActors->GetNextActor();
- }
-
- vtkRenderWindow *renWin = theRenderer->GetRenderWindow();
- renWin->Render();
+ MESSAGE("OrientationElements - not implemeted yet!");
}
//=============================================================================
*
*/
//=============================================================================
-void SMESHGUI::Control(int theCommandID)
+void SMESHGUI::DiagonalInversion(SMESH::SMESH_Mesh_ptr aMesh,
+ const TColStd_MapOfInteger & MapIndex)
{
- if (myActiveStudy->getActiveStudyFrame()->getTypeView() != VIEW_VTK)
- return;
-
- QApplication::setOverrideCursor(Qt::waitCursor);
- DisplayScalarBar(false);
-
- vtkDoubleArray *scalars = vtkDoubleArray::New();
- scalars->SetNumberOfComponents(1);
-
- vtkDataSetMapper *meshMapper = 0;
- SALOME_Selection *Sel =
- SALOME_Selection::Selection(myActiveStudy->getSelection());
- int nbSel = Sel->IObjectCount();
- Standard_Boolean result;
- Handle(SALOME_InteractiveObject) IObject = Sel->firstIObject();
- SMESH_Actor *MeshActor =
- FindActorByEntry(IObject->getEntry(), result, true);
-
- // Mesh may be not updated after Compute
- if (!MeshActor->DataSource || !MeshActor->GetMapper())
- {
- QApplication::restoreOverrideCursor();
- return;
- }
-
- vtkDataSet *aDataSet = MeshActor->DataSource;
- typedef double (*TScalarFun) (vtkCell * theCell);
- TScalarFun aScalarFun;
- if (result)
- {
- QString type;
- switch (theCommandID)
- {
- case 6001:
- {
- type = tr("SMESH_CONTROL_LENGTH_EDGES");
- aDataSet = MeshActor->EdgeDevice->GetMapper()->GetInput();
- aScalarFun = &(SMESHGUI_ComputeScalarValue::LengthEdges);
- MESSAGE(" init minimum length " << aDataSet->GetNumberOfCells());
- if (MeshActor->getDisplayMode() != 0)
- ChangeRepresentation(MeshActor, 1); // limitation; in Wireframe, colored edges are not visible
- break;
- }
- case 6011:
- {
- type = tr("SMESH_CONTROL_AREA_ELEMENTS");
- aScalarFun = &(SMESHGUI_ComputeScalarValue::AreaElements);
- if (MeshActor->getDisplayMode() != 1)
- ChangeRepresentation(MeshActor, 1);
- break;
- }
- case 6012:
- {
- type = tr("SMESH_CONTROL_TAPER_ELEMENTS");
- aScalarFun = &(SMESHGUI_ComputeScalarValue::Taper);
- break;
- }
- case 6013:
- {
- type = tr("SMESH_CONTROL_ASPECTRATIO_ELEMENTS");
- aScalarFun = &(SMESHGUI_ComputeScalarValue::AspectRatio);
- if (MeshActor->getDisplayMode() != 1)
- ChangeRepresentation(MeshActor, 1);
- break;
- }
- case 6014:
- {
- type = tr("SMESH_CONTROL_MINIMUMANGLE_ELEMENTS");
- aScalarFun = &(SMESHGUI_ComputeScalarValue::MinimumAngle);
- if (MeshActor->getDisplayMode() != 1)
- ChangeRepresentation(MeshActor, 1);
- break;
- }
- case 6015:
- {
- type = tr("SMESH_CONTROL_WARP_ELEMENTS");
- aScalarFun = &(SMESHGUI_ComputeScalarValue::Warp);
- break;
- }
- case 6016:
- {
- type = tr("SMESH_CONTROL_SKEW_ELEMENTS");
- aScalarFun = &(SMESHGUI_ComputeScalarValue::Skew);
- break;
- }
- }
-
- for (int i = 0, iEnd = aDataSet->GetNumberOfCells(); i < iEnd; i++)
- scalars->InsertTuple1(i, aScalarFun(aDataSet->GetCell(i)));
-
- float range[2];
- scalars->GetRange(range);
-
- vtkLookupTable *wat = vtkLookupTable::New();
- wat->SetRange(range);
- wat->Build();
-
- scalars->SetLookupTable(wat);
-
- if (!meshMapper)
- meshMapper = (vtkDataSetMapper *) (MeshActor->getMapper());
- meshMapper->SetScalarModeToUseCellData();
- MeshActor->DataSource->GetCellData()->SetScalars(scalars);
- meshMapper->SetScalarRange(range);
- meshMapper->ScalarVisibilityOn();
+ MESSAGE("OrientationElements - not implemeted yet!");
+}
- vtkScalarBarActor *aScalarBar = GetScalarBar();
- if (aScalarBar == NULL)
- {
- aScalarBar = vtkScalarBarActor::New();
- QString Bold = QAD_CONFIG->getSetting("ScalarBar:Bold");
- QString Italic = QAD_CONFIG->getSetting("ScalarBar:Italic");
- QString Shadow = QAD_CONFIG->getSetting("ScalarBar:Shadow");
- QString FontFamily = QAD_CONFIG->getSetting("ScalarBar:FontFamily");
- QString Orientation =
- QAD_CONFIG->getSetting("ScalarBar:Orientation");
- float Width = QAD_CONFIG->getSetting("ScalarBar:Width").toFloat();
- float Height = QAD_CONFIG->getSetting("ScalarBar:Height").toFloat();
- int NumberOfLabels =
- QAD_CONFIG->getSetting("ScalarBar:NumberOfLabels").toInt();
- int NumberOfColors =
- QAD_CONFIG->getSetting("ScalarBar:NumberOfColors").toInt();
-
- SetSettingsScalarBar(aScalarBar, Bold, Italic, Shadow, FontFamily,
- Orientation, Width, Height, NumberOfColors, NumberOfLabels);
- vtkRenderer *theRenderer =
- ((VTKViewer_ViewFrame *) myActiveStudy->getActiveStudyFrame()->
- getRightFrame()->getViewFrame())->getRenderer();
- theRenderer->AddActor2D(aScalarBar);
- }
- aScalarBar->SetLookupTable(wat);
- aScalarBar->SetTitle(type.latin1());
+//=====================================================================================
+// EXPORTED METHODS
+//=====================================================================================
+void SMESHGUI::SupportedViewType(int *buffer, int bufferSize)
+{
+ if (!buffer || !bufferSize)
+ return;
+ buffer[0] = (int)VIEW_VTK;
+}
- scalars->Delete();
- // wat->Delete();
- DisplayScalarBar(true);
- }
- QApplication::restoreOverrideCursor();
+void SMESHGUI::Deactivate()
+{
+ if ( SMESHGUI::GetSMESHGUI() ) {
+ SMESHGUI::GetSMESHGUI()->EmitSignalCloseAllDialogs();
+ }
}
+
//=============================================================================
/*!
*
*/
//=============================================================================
-void SMESHGUI::SetSettingsScalarBar(vtkScalarBarActor * theScalarBar,
- QString Bold, QString Italic,
- QString Shadow, QString FontFamily,
- QString Orientation, float Width, float Height, int NbColors, int NbLabels)
-{
- if (Bold.isNull() || Bold.isEmpty() || (Bold.compare("true") == 0))
- theScalarBar->BoldOn();
- else
- theScalarBar->BoldOff();
-
- if (Italic.isNull() || Italic.isEmpty() || (Italic.compare("true") == 0))
- theScalarBar->ItalicOn();
- else
- theScalarBar->ItalicOff();
-
- if (Shadow.isNull() || Shadow.isEmpty() || (Shadow.compare("true") == 0))
- theScalarBar->ShadowOn();
- else
- theScalarBar->ShadowOff();
-
- if (FontFamily.compare("Arial") == 0)
- theScalarBar->SetFontFamilyToArial();
- else if (FontFamily.compare("Courier") == 0)
- theScalarBar->SetFontFamilyToCourier();
- else if (FontFamily.compare("Times") == 0)
- theScalarBar->SetFontFamilyToTimes();
- else
- theScalarBar->SetFontFamilyToArial();
-
- if (Orientation.isNull() || Orientation.isEmpty() ||
- (Orientation.compare("Vertical") == 0))
- theScalarBar->SetOrientationToVertical();
- else
- theScalarBar->SetOrientationToHorizontal();
+void SMESHGUI::SetPickable(SMESH_Actor* theActor){
+ if(VTKViewer_ViewFrame* aViewFrame = GetCurrentVtkView()){
+ int anIsAllPickable = (theActor == NULL);
+ vtkRenderer *aRenderer = aViewFrame->getRenderer();
+ vtkActorCollection *aCollection = aRenderer->GetActors();
+ aCollection->InitTraversal();
+ while(vtkActor *anAct = aCollection->GetNextActor()){
+ if(SALOME_Actor *anActor = dynamic_cast<SALOME_Actor*>(anAct)){
+ if(anActor->GetVisibility()){
+ anActor->SetPickable(anIsAllPickable);
+ }
+ }
+ }
+ if(theActor)
+ theActor->SetPickable(!anIsAllPickable);
+ RepaintCurrentView();
+ }
+}
- theScalarBar->SetWidth((Width == 0) ? 0.17 : Width);
- theScalarBar->SetHeight((Height == 0) ? 0.8 : Height);
- theScalarBar->SetNumberOfLabels((NbLabels == 0) ? 5 : NbLabels);
- theScalarBar->SetMaximumNumberOfColors((NbColors == 0) ? 64 : NbColors);
+void SMESHGUI::ViewNodes(){
+ EraseSimulationActors();
+ ::SetPointRepresentation(true);
}
//=============================================================================
*
*/
//=============================================================================
-void SMESHGUI::DisplayScalarBar(bool visibility)
-{
- if (myActiveStudy->getActiveStudyFrame()->getTypeView() != VIEW_VTK)
- return;
-
- vtkRenderer *theRenderer =
- ((VTKViewer_ViewFrame *) myActiveStudy->getActiveStudyFrame()->
- getRightFrame()->getViewFrame())->getRenderer();
- vtkScalarBarActor *aScalarBar = GetScalarBar();
-
- if (aScalarBar == NULL)
- {
- MESSAGE("myScalarBar is NULL");
- return;
- }
-
- if (visibility)
- aScalarBar->VisibilityOn();
- else
- {
- aScalarBar->VisibilityOff();
- //Turn off mesh coloring (influences on all views)
- vtkActorCollection *actorList = theRenderer->GetActors();
- actorList->InitTraversal();
- vtkActor *ac = actorList->GetNextActor();
- while (ac != NULL)
- {
- if (ac->GetMapper() != NULL)
- {
- ac->GetMapper()->ScalarVisibilityOff();
- }
- ac = actorList->GetNextActor();
- }
- // Turn off ScalarBar in all views
- /*QList<QAD_StudyFrame> aFrames = myActiveStudy->getStudyFrames();
- * for ( QAD_StudyFrame* aFrame = aFrames.first(); aFrame; aFrame = aFrames.next() ) {
- * if (aFrame->getTypeView() == VIEW_VTK) {
- * vtkRenderer *aRenderer = ((VTKViewer_ViewFrame*) aFrame->getRightFrame()->getViewFrame())->getRenderer();
- * vtkActor2DCollection* actor2DList = aRenderer->GetActors2D();
- * actor2DList->InitTraversal();
- * vtkActor2D* aActor2d = actor2DList->GetNextActor2D();
- * while (aActor2d != NULL) {
- * if (aActor2d->IsA("vtkScalarBarActor")) {
- * aActor2d->VisibilityOff();
- * break;
- * }
- * actor2DList->GetNextActor2D();
- * }
- * }
- * } */
+void SMESHGUI::Control( int theCommandID ){
+ SALOME_Selection *Sel = SALOME_Selection::Selection( myActiveStudy->getSelection() );
+ if(Sel){
+ Handle(SALOME_InteractiveObject) anIO = Sel->firstIObject();
+ if(!anIO.IsNull()){
+ QString aTitle;
+ SMESH_Actor::eControl aControl = SMESH_Actor::eNone;
+ if(SMESH_Actor *anActor = ::FindActorByEntry(anIO->getEntry())){
+ switch ( theCommandID ){
+ case 6001:
+ aTitle = tr( "LENGTH_EDGES" );
+ aControl = SMESH_Actor::eLengthEdges;
+ break;
+ case 6003:
+ aTitle = tr( "FREE_BORDERS" );
+ aControl = SMESH_Actor::eFreeBorders;
+ break;
+ case 6004:
+ aTitle = tr( "MULTI_BORDERS" );
+ aControl = SMESH_Actor::eMultiConnection;
+ break;
+ case 6011:
+ aTitle = tr( "AREA_ELEMENTS" );
+ aControl = SMESH_Actor::eArea;
+ break;
+ case 6012:
+ aTitle = tr( "TAPER_ELEMENTS" );
+ aControl = SMESH_Actor::eTaper;
+ break;
+ case 6013:
+ aTitle = tr( "ASPECTRATIO_ELEMENTS" );
+ aControl = SMESH_Actor::eAspectRatio;
+ break;
+ case 6014:
+ aTitle = tr( "MINIMUMANGLE_ELEMENTS" );
+ aControl = SMESH_Actor::eMinimumAngle;
+ break;
+ case 6015:
+ aTitle = tr( "WARP_ELEMENTS" );
+ aControl = SMESH_Actor::eWarping;
+ break;
+ case 6016:
+ aTitle = tr( "SKEW_ELEMENTS" );
+ aControl = SMESH_Actor::eSkew;
+ break;
}
- myActiveStudy->update3dViewers();
+ anActor->SetControlMode(aControl);
+ anActor->GetScalarBarActor()->SetTitle(aTitle.latin1());
+ }
+ }
+ }
}
//=============================================================================
*
*/
//=============================================================================
-void SMESHGUI::UpdateScalarBar(float MinRange, float MaxRange)
+void SMESHGUI::SetSettingsScalarBar(vtkScalarBarActor * theScalarBar,
+ QString Bold,
+ QString Italic,
+ QString Shadow,
+ QString FontFamily,
+ QString Orientation,
+ float Width,
+ float Height,
+ int NbColors,
+ int NbLabels)
{
- vtkScalarBarActor *aScalarBar = GetScalarBar();
- if (aScalarBar == NULL)
- {
- MESSAGE("myScalarBar is NULL");
- return;
- }
- DisplayScalarBar(false);
-
- aScalarBar->GetLookupTable()->SetRange(MinRange, MaxRange);
- vtkRenderer *aRenderer =
- ((VTKViewer_ViewFrame *) myActiveStudy->getActiveStudyFrame()->
- getRightFrame()->getViewFrame())->getRenderer();
- vtkActorCollection *aActorList = aRenderer->GetActors();
- aActorList->InitTraversal();
- vtkActor *aActor = aActorList->GetNextActor();
- while (aActor != NULL)
- {
- if (aActor->IsA("SMESH_Actor"))
- {
- SMESH_Actor *aMeshActor = SMESH_Actor::SafeDownCast(aActor);
- vtkDataSetMapper *aMeshMapper =
- (vtkDataSetMapper *) (aMeshActor->getMapper());
- if ((aMeshMapper != NULL))
- {
- aMeshMapper->SetScalarRange(MinRange, MaxRange);
- aMeshMapper->ScalarVisibilityOn();
- }
- }
- aActor = aActorList->GetNextActor();
- }
- DisplayScalarBar(true);
+ if (Bold.isNull() || Bold.isEmpty() || (Bold.compare("true") == 0))
+ theScalarBar->BoldOn();
+ else
+ theScalarBar->BoldOff();
+
+ if (Italic.isNull() || Italic.isEmpty() || (Italic.compare("true") == 0))
+ theScalarBar->ItalicOn();
+ else
+ theScalarBar->ItalicOff();
+
+ if (Shadow.isNull() || Shadow.isEmpty() || (Shadow.compare("true") == 0))
+ theScalarBar->ShadowOn();
+ else
+ theScalarBar->ShadowOff();
+
+ if (FontFamily.compare("Arial") == 0)
+ theScalarBar->SetFontFamilyToArial();
+ else if (FontFamily.compare("Courier") == 0)
+ theScalarBar->SetFontFamilyToCourier();
+ else if (FontFamily.compare("Times") == 0)
+ theScalarBar->SetFontFamilyToTimes();
+ else
+ theScalarBar->SetFontFamilyToArial();
+
+ if (Orientation.isNull() || Orientation.isEmpty() ||
+ (Orientation.compare("Vertical") == 0))
+ theScalarBar->SetOrientationToVertical();
+ else
+ theScalarBar->SetOrientationToHorizontal();
+
+ theScalarBar->SetWidth((Width == 0) ? 0.17 : Width);
+ theScalarBar->SetHeight((Height == 0) ? 0.8 : Height);
+
+ theScalarBar->SetNumberOfLabels((NbLabels == 0) ? 5 : NbLabels);
+ theScalarBar->SetMaximumNumberOfColors((NbColors == 0) ? 64 : NbColors);
}
//=============================================================================
//=============================================================================
void SMESHGUI::SetDisplaySettings()
{
- EmitSignalDeactivateDialog();
- SMESHGUI_Preferences_ColorDlg *aDlg =
- new SMESHGUI_Preferences_ColorDlg(QAD_Application::getDesktop(), "");
-
- QString SCr = QAD_CONFIG->getSetting("SMESH:SettingsFillColorRed");
- QString SCg = QAD_CONFIG->getSetting("SMESH:SettingsFillColorGreen");
- QString SCb = QAD_CONFIG->getSetting("SMESH:SettingsFillColorBlue");
- QColor color = QColor(SCr.toInt(), SCg.toInt(), SCb.toInt());
- aDlg->SetColor(1, color);
-
- SCr = QAD_CONFIG->getSetting("SMESH:SettingsOutlineColorRed");
- SCg = QAD_CONFIG->getSetting("SMESH:SettingsOutlineColorGreen");
- SCb = QAD_CONFIG->getSetting("SMESH:SettingsOutlineColorBlue");
- color = QColor(SCr.toInt(), SCg.toInt(), SCb.toInt());
- aDlg->SetColor(2, color);
-
- SCr = QAD_CONFIG->getSetting("SMESH:SettingsNodeColorRed");
- SCg = QAD_CONFIG->getSetting("SMESH:SettingsNodeColorGreen");
- SCb = QAD_CONFIG->getSetting("SMESH:SettingsNodeColorBlue");
- color = QColor(SCr.toInt(), SCg.toInt(), SCb.toInt());
- aDlg->SetColor(3, color);
-
- QString SBr = QAD_CONFIG->getSetting("SMESH:SettingsBackFaceColorRed");
- QString SBg = QAD_CONFIG->getSetting("SMESH:SettingsBackFaceColorGreen");
- QString SBb = QAD_CONFIG->getSetting("SMESH:SettingsBackFaceColorBlue");
- color = QColor(SBr.toInt(), SBg.toInt(), SBb.toInt());
- aDlg->SetColor(4, color);
-
- QString intValue = QAD_CONFIG->getSetting("SMESH:SettingsWidth");
- aDlg->SetIntValue(1, intValue.toInt());
- intValue = QAD_CONFIG->getSetting("SMESH:SettingsNodesSize");
- aDlg->SetIntValue(2, intValue.toInt());
- intValue = QAD_CONFIG->getSetting("SMESH:SettingsShrinkCoeff");
- aDlg->SetIntValue(3, intValue.toInt());
-
- if (aDlg->exec())
- {
- QColor colorFill = aDlg->GetColor(1);
- QAD_CONFIG->addSetting("SMESH:SettingsFillColorRed", colorFill.red());
- QAD_CONFIG->addSetting("SMESH:SettingsFillColorGreen",
- colorFill.green());
- QAD_CONFIG->addSetting("SMESH:SettingsFillColorBlue", colorFill.blue());
-
- QColor colorOutline = aDlg->GetColor(2);
- QAD_CONFIG->addSetting("SMESH:SettingsOutlineColorRed",
- colorOutline.red());
- QAD_CONFIG->addSetting("SMESH:SettingsOutlineColorGreen",
- colorOutline.green());
- QAD_CONFIG->addSetting("SMESH:SettingsOutlineColorBlue",
- colorOutline.blue());
-
- QColor colorNode = aDlg->GetColor(3);
- QAD_CONFIG->addSetting("SMESH:SettingsNodeColorRed", colorNode.red());
- QAD_CONFIG->addSetting("SMESH:SettingsNodeColorGreen",
- colorNode.green());
- QAD_CONFIG->addSetting("SMESH:SettingsNodeColorBlue", colorNode.blue());
-
- QColor colorBackFace = aDlg->GetColor(4);
- QAD_CONFIG->addSetting("SMESH:SettingsBackFaceColorRed",
- colorBackFace.red());
- QAD_CONFIG->addSetting("SMESH:SettingsBackFaceColorGreen",
- colorBackFace.green());
- QAD_CONFIG->addSetting("SMESH:SettingsBackFaceColorBlue",
- colorBackFace.blue());
-
- int width = aDlg->GetIntValue(1);
- QAD_CONFIG->addSetting("SMESH:SettingsWidth", width);
-
- int nodes_size = aDlg->GetIntValue(2);
- QAD_CONFIG->addSetting("SMESH:SettingsNodesSize", nodes_size);
-
- int shrink_coeff = aDlg->GetIntValue(3);
- QAD_CONFIG->addSetting("SMESH:SettingsShrinkCoeff", shrink_coeff);
- }
-
- delete aDlg;
+ EmitSignalDeactivateDialog();
+ SMESHGUI_Preferences_ColorDlg *aDlg =
+ new SMESHGUI_Preferences_ColorDlg(QAD_Application::getDesktop(), "");
+
+ QColor color;
+ QString SCr, SCg, SCb;
+ SCr = QAD_CONFIG->getSetting("SMESH:SettingsFillColorRed");
+ SCg = QAD_CONFIG->getSetting("SMESH:SettingsFillColorGreen");
+ SCb = QAD_CONFIG->getSetting("SMESH:SettingsFillColorBlue");
+ if (!SCr.isEmpty() && !SCg.isEmpty() && !SCb.isEmpty())
+ color = QColor(SCr.toInt(), SCg.toInt(), SCb.toInt());
+ else color = QColor(0, 170, 255);
+ aDlg->SetColor(1, color);
+
+ SCr = QAD_CONFIG->getSetting("SMESH:SettingsOutlineColorRed");
+ SCg = QAD_CONFIG->getSetting("SMESH:SettingsOutlineColorGreen");
+ SCb = QAD_CONFIG->getSetting("SMESH:SettingsOutlineColorBlue");
+ if (!SCr.isEmpty() && !SCg.isEmpty() && !SCb.isEmpty())
+ color = QColor(SCr.toInt(), SCg.toInt(), SCb.toInt());
+ else color = QColor(0, 170, 255);
+ aDlg->SetColor(2, color);
+
+ SCr = QAD_CONFIG->getSetting("SMESH:SettingsNodeColorRed");
+ SCg = QAD_CONFIG->getSetting("SMESH:SettingsNodeColorGreen");
+ SCb = QAD_CONFIG->getSetting("SMESH:SettingsNodeColorBlue");
+ if (!SCr.isEmpty() && !SCg.isEmpty() && !SCb.isEmpty())
+ color = QColor(SCr.toInt(), SCg.toInt(), SCb.toInt());
+ else color = Qt::red;
+ aDlg->SetColor(3, color);
+
+ QString SBr = QAD_CONFIG->getSetting("SMESH:SettingsBackFaceColorRed");
+ QString SBg = QAD_CONFIG->getSetting("SMESH:SettingsBackFaceColorGreen");
+ QString SBb = QAD_CONFIG->getSetting("SMESH:SettingsBackFaceColorBlue");
+ if (!SCr.isEmpty() && !SCg.isEmpty() && !SCb.isEmpty())
+ color = QColor(SBr.toInt(), SBg.toInt(), SBb.toInt());
+ else color = Qt::blue;
+ aDlg->SetColor(4, color);
+
+ QString intValue = QAD_CONFIG->getSetting("SMESH:SettingsWidth");
+ if (intValue.isEmpty()) intValue = "1";
+ aDlg->SetIntValue(1, intValue.toInt());
+ intValue = QAD_CONFIG->getSetting("SMESH:SettingsNodesSize");
+ if (intValue.isEmpty()) intValue = "3";
+ aDlg->SetIntValue(2, intValue.toInt());
+ intValue = QAD_CONFIG->getSetting("SMESH:SettingsShrinkCoeff");
+ if (intValue.isEmpty()) intValue = "75";
+ aDlg->SetIntValue(3, intValue.toInt());
+
+ if (aDlg->exec()) {
+ QColor colorFill = aDlg->GetColor(1);
+ QAD_CONFIG->addSetting("SMESH:SettingsFillColorRed", colorFill.red());
+ QAD_CONFIG->addSetting("SMESH:SettingsFillColorGreen", colorFill.green());
+ QAD_CONFIG->addSetting("SMESH:SettingsFillColorBlue", colorFill.blue());
+
+ QColor colorOutline = aDlg->GetColor(2);
+ QAD_CONFIG->addSetting("SMESH:SettingsOutlineColorRed", colorOutline.red());
+ QAD_CONFIG->addSetting("SMESH:SettingsOutlineColorGreen", colorOutline.green());
+ QAD_CONFIG->addSetting("SMESH:SettingsOutlineColorBlue", colorOutline.blue());
+
+ QColor colorNode = aDlg->GetColor(3);
+ QAD_CONFIG->addSetting("SMESH:SettingsNodeColorRed", colorNode.red());
+ QAD_CONFIG->addSetting("SMESH:SettingsNodeColorGreen", colorNode.green());
+ QAD_CONFIG->addSetting("SMESH:SettingsNodeColorBlue", colorNode.blue());
+
+ QColor colorBackFace = aDlg->GetColor(4);
+ QAD_CONFIG->addSetting("SMESH:SettingsBackFaceColorRed", colorBackFace.red());
+ QAD_CONFIG->addSetting("SMESH:SettingsBackFaceColorGreen", colorBackFace.green());
+ QAD_CONFIG->addSetting("SMESH:SettingsBackFaceColorBlue", colorBackFace.blue());
+
+ int width = aDlg->GetIntValue(1);
+ QAD_CONFIG->addSetting("SMESH:SettingsWidth", width);
+
+ int nodes_size = aDlg->GetIntValue(2);
+ QAD_CONFIG->addSetting("SMESH:SettingsNodesSize", nodes_size);
+
+ int shrink_coeff = aDlg->GetIntValue(3);
+ QAD_CONFIG->addSetting("SMESH:SettingsShrinkCoeff", shrink_coeff);
+ }
+
+ delete aDlg;
}
//=======================================================================
*
*/
//=============================================================================
-void SMESHGUI::DisplayEdges(SMESH_Actor * ac, bool visibility)
-{
- if (myActiveStudy->getActiveStudyFrame()->getTypeView() != VIEW_VTK)
- return;
- if (ac->DataSource == NULL || ac->GetMapper() == NULL)
- return;
-
- vtkGeometryFilter *gf = vtkGeometryFilter::New();
- gf->SetInput(ac->DataSource);
- vtkFeatureEdges *edges = vtkFeatureEdges::New();
- edges->SetInput(gf->GetOutput());
- edges->BoundaryEdgesOn();
- edges->ManifoldEdgesOn();
-
- vtkPolyDataMapper *edgeMapper = vtkPolyDataMapper::New();
- edgeMapper->SetInput(edges->GetOutput());
- edgeMapper->ScalarVisibilityOff();
-
- vtkRenderer *theRenderer =
- ((VTKViewer_ViewFrame *) myActiveStudy->getActiveStudyFrame()->
- getRightFrame()->getViewFrame())->getRenderer();
- vtkActorCollection *actorList = theRenderer->GetActors();
-
- int test = actorList->IsItemPresent(ac->EdgeDevice);
- if (test == 0)
- {
- vtkProperty *prop = vtkProperty::New();
- prop->SetColor(QAD_CONFIG->getSetting("SMESH:SettingsOutlineColorRed").
- toFloat() / 255.,
- QAD_CONFIG->getSetting("SMESH:SettingsOutlineColorGreen").
- toFloat() / 255.,
- QAD_CONFIG->getSetting("SMESH:SettingsOutlineColorBlue").toFloat() /
- 255.);
- prop->SetPointSize(QAD_CONFIG->getSetting("SMESH:SettingsNodesSize").
- toInt());
- prop->SetLineWidth(QAD_CONFIG->getSetting("SMESH:SettingsWidth").
- toInt());
- ac->EdgeDevice->SetProperty(prop);
- ac->SetEdgeColor(QAD_CONFIG->
- getSetting("SMESH:SettingsOutlineColorRed").toFloat() / 255.,
- QAD_CONFIG->getSetting("SMESH:SettingsOutlineColorGreen").
- toFloat() / 255.,
- QAD_CONFIG->getSetting("SMESH:SettingsOutlineColorBlue").toFloat() /
- 255.);
- ac->EdgeDevice->SetMapper(edgeMapper);
-
- theRenderer->AddActor(ac->EdgeDevice);
- }
- else
- {
- ac->EdgeDevice->SetMapper(edgeMapper);
- edgeMapper->Update();
- }
-
- vtkShrinkFilter *shrink = vtkShrinkFilter::New();
- shrink->SetInput(ac->DataSource);
- shrink->SetShrinkFactor(ac->GetShrinkFactor());
- vtkGeometryFilter *Shrinkgf = vtkGeometryFilter::New();
- Shrinkgf->SetInput(shrink->GetOutput());
- vtkFeatureEdges *ShrinkEdges = vtkFeatureEdges::New();
- ShrinkEdges->SetInput(Shrinkgf->GetOutput());
- ShrinkEdges->BoundaryEdgesOn();
- ShrinkEdges->ManifoldEdgesOn();
-
- vtkPolyDataMapper *ShrinkEdgeMapper = vtkPolyDataMapper::New();
- ShrinkEdgeMapper->SetInput(ShrinkEdges->GetOutput());
- ShrinkEdgeMapper->ScalarVisibilityOff();
-
- test = actorList->IsItemPresent(ac->EdgeShrinkDevice);
- if (test == 0)
- {
- vtkProperty *prop = vtkProperty::New();
- prop->SetColor(QAD_CONFIG->getSetting("SMESH:SettingsOutlineColorRed").
- toFloat() / 255.,
- QAD_CONFIG->getSetting("SMESH:SettingsOutlineColorGreen").
- toFloat() / 255.,
- QAD_CONFIG->getSetting("SMESH:SettingsOutlineColorBlue").toFloat() /
- 255.);
- prop->SetPointSize(QAD_CONFIG->getSetting("SMESH:SettingsNodesSize").
- toInt());
- prop->SetLineWidth(QAD_CONFIG->getSetting("SMESH:SettingsWidth").
- toInt());
- ac->EdgeShrinkDevice->SetProperty(prop);
- ac->SetEdgeColor(QAD_CONFIG->
- getSetting("SMESH:SettingsOutlineColorRed").toFloat() / 255.,
- QAD_CONFIG->getSetting("SMESH:SettingsOutlineColorGreen").
- toFloat() / 255.,
- QAD_CONFIG->getSetting("SMESH:SettingsOutlineColorBlue").toFloat() /
- 255.);
- ac->EdgeShrinkDevice->SetMapper(ShrinkEdgeMapper);
-
- theRenderer->AddActor(ac->EdgeShrinkDevice);
- }
- else
- {
- ac->EdgeShrinkDevice->SetMapper(ShrinkEdgeMapper);
- ShrinkEdgeMapper->Update();
- }
-
- vtkRenderWindow *renWin = theRenderer->GetRenderWindow();
- renWin->Render();
-}
+void SMESHGUI::DisplayEdges(SMESH_Actor * ac, bool visibility){}
//=============================================================================
/*!
*
*/
//=============================================================================
-void SMESHGUI::InitActor(SMESH::SMESH_Mesh_ptr aMesh)
-{
- SALOMEDS::SObject_var aSO_M = myStudyAPI.FindMesh(aMesh);
- SALOMEDS::GenericAttribute_var anAttr;
- SALOMEDS::AttributeName_var aName;
- if (!aSO_M->_is_nil())
- {
- if (aSO_M->FindAttribute(anAttr, "AttributeName"))
- {
- aName = SALOMEDS::AttributeName::_narrow(anAttr);
- Standard_Boolean result;
- SMESH_Actor *MeshActor =
- smeshGUI->FindActorByEntry(aSO_M->GetID(), result, true);
- if (!result)
- {
- SMESH_Actor *amesh = SMESH_Actor::New();
- Handle(SALOME_InteractiveObject) IO =
- new SALOME_InteractiveObject(aSO_M->GetID(), "MESH",
- aName->Value());
- amesh->setIO(IO);
- amesh->setName(aName->Value());
- DisplayActor(amesh, false);
- }
- }
- }
-}
+void SMESHGUI::InitActor(SMESH::SMESH_Mesh_ptr aMesh){}
//=============================================================================
/*!
*
*/
//=============================================================================
-void SMESHGUI::Update()
-{
- MESSAGE("SMESHGUI::Update");
- if (myActiveStudy->getActiveStudyFrame()->getTypeView() == VIEW_VTK)
- { //VTK
- vtkRenderer *theRenderer =
- ((VTKViewer_ViewFrame *) myActiveStudy->getActiveStudyFrame()->
- getRightFrame()->getViewFrame())->getRenderer();
-
- SALOME_Selection *Sel =
- SALOME_Selection::Selection(myActiveStudy->getSelection());
- int nbSel = Sel->IObjectCount();
- if (nbSel == 0)
- {
- vtkActorCollection *actorList = theRenderer->GetActors();
- actorList->InitTraversal();
- vtkActor *ac = actorList->GetNextActor();
- while (!(ac == NULL))
- {
- if (ac->IsA("SMESH_Actor"))
- {
- SMESH_Actor *anActor = SMESH_Actor::SafeDownCast(ac);
- if (anActor->hasIO())
- {
- Handle(SALOME_InteractiveObject) IO = anActor->getIO();
- Update(IO);
- }
- }
- ac = actorList->GetNextActor();
- }
- }
- else
- {
- SALOME_ListIteratorOfListIO It(Sel->StoredIObjects());
- for (; It.More(); It.Next())
- {
- Handle(SALOME_InteractiveObject) IO = It.Value();
- Update(IO);
- }
- }
- vtkRenderWindow *renWin = theRenderer->GetRenderWindow();
- renWin->Render();
- }
- QApplication::restoreOverrideCursor();
+void SMESHGUI::Update(){
+ if(VTKViewer_ViewFrame* aViewFrame = GetCurrentVtkView()){
+ SALOME_Selection *Sel = SALOME_Selection::Selection(myActiveStudy->getSelection());
+ if(Sel->IObjectCount() == 0){
+ vtkRenderer* aRenderer = aViewFrame->getRenderer();
+ vtkActorCollection *aCollection = aRenderer->GetActors();
+ aCollection->InitTraversal();
+ while(vtkActor *anAct = aCollection->GetNextActor()){
+ if(SMESH_Actor *anActor = dynamic_cast<SMESH_Actor*>(anAct)){
+ if(anActor->hasIO()){
+ Update(anActor->getIO());
+ }
+ }
+ }
+ }else{
+ SALOME_ListIteratorOfListIO It(Sel->StoredIObjects());
+ for(; It.More(); It.Next()){
+ Handle(SALOME_InteractiveObject) IO = It.Value();
+ Update(IO);
+ }
+ }
+ ::RepaintCurrentView();
+ }
}
//=============================================================================
*
*/
//=============================================================================
-void SMESHGUI::Update(const Handle(SALOME_InteractiveObject) & IO)
-{
- if (myActiveStudy->getActiveStudyFrame()->getTypeView() != VIEW_VTK)
- return;
-
- if (IO->hasEntry())
- {
- Standard_Boolean res;
- SMESH::SMESH_Mesh_var aMesh = ConvertIOinMesh(IO, res);
- if (res)
- {
- SMESH_Actor *ac = FindActorByEntry(IO->getEntry(), res, false);
- if (res)
- {
- // Check whether the actor belongs to the active view
- VTKViewer_RenderWindowInteractor *rwInter =
- ((VTKViewer_ViewFrame *) myActiveStudy->
- getActiveStudyFrame()->getRightFrame()->getViewFrame())->
- getRWInteractor();
-
- ac = ReadScript(aMesh);
- // The actor belongs to inactive view -> create a copy and display it in the active view
- if (!rwInter->isInViewer(IO))
- {
- SMESH_Actor *acCopy = SMESH_Actor::New();
- acCopy->ShallowCopy(ac);
- ac=acCopy;
- }
-
- if (ac != NULL)
- {
-#ifdef TRACE
- Dump(ac);
-#endif
- DisplayActor(ac);
- DisplayEdges(ac);
- smeshGUI->ChangeRepresentation(ac, ac->getDisplayMode());
- }
- }
- }
- }
+void SMESHGUI::Update(const Handle(SALOME_InteractiveObject) & theIO){
+ CORBA::Long anId = smeshGUI->myStudy->StudyId();
+ TVisualObjPtr aVisualObj = ::GetVisualObj(anId,theIO->getEntry());
+ aVisualObj->Update();
+ ::UpdateView(eDisplay,theIO->getEntry());
}
//=============================================================================
getRightFrame()->getViewFrame())->getRenderer();
vtkUnstructuredGrid *ugrid =
- vtkUnstructuredGrid::SafeDownCast(Mactor->DataSource);
+ vtkUnstructuredGrid::SafeDownCast(Mactor->GetUnstructuredGrid());
vtkIdList *IdCells = vtkIdList::New();
ugrid->GetPointCells(idnode, IdCells);
prop->SetColor(1., 0., 0.);
prop->SetRepresentationToWireframe();
- int Edgewidth = (int)Mactor->EdgeDevice->GetProperty()->GetLineWidth();
+ int Edgewidth = (int)Mactor->GetLineWidth();
if (Edgewidth == 0)
Edgewidth = 1;
prop->SetLineWidth(Edgewidth + 1);
if (result)
{
vtkUnstructuredGrid *ugrid =
- vtkUnstructuredGrid::SafeDownCast(ac->DataSource);
+ vtkUnstructuredGrid::SafeDownCast(ac->GetUnstructuredGrid());
vtkUnstructuredGrid *newugrid = vtkUnstructuredGrid::New();
vtkPoints *Pts = ugrid->GetPoints();
*
*/
//=============================================================================
-void SMESHGUI::ScalarVisibilityOff()
-{
- if (myActiveStudy->getActiveStudyFrame()->getTypeView() != VIEW_VTK)
- return;
-
- vtkRenderer *theRenderer =
- ((VTKViewer_ViewFrame *) myActiveStudy->getActiveStudyFrame()->
- getRightFrame()->getViewFrame())->getRenderer();
- vtkActorCollection *actorList = theRenderer->GetActors();
-
- actorList->InitTraversal();
- vtkActor *ac = actorList->GetNextActor();
- while (!(ac == NULL))
- {
- if (ac->IsA("SMESH_Actor"))
- {
- SMESH_Actor *anActor = SMESH_Actor::SafeDownCast(ac);
- if (anActor->GetVisibility() == 1)
- {
- vtkDataSetMapper *meshMapper =
- (vtkDataSetMapper *) (anActor->getMapper());
- meshMapper->ScalarVisibilityOff();
- meshMapper->SetInput(anActor->DataSource);
- ChangeRepresentation(anActor, anActor->getDisplayMode());
- }
- }
- ac = actorList->GetNextActor();
- }
-
- theRenderer->Render();
+void SMESHGUI::ScalarVisibilityOff(){
+ if(vtkRenderer *aRenderer = ::GetCurrentRenderer()){
+ vtkActorCollection *actorList = aRenderer->GetActors();
+ actorList->InitTraversal();
+ while(vtkActor *ac = actorList->GetNextActor()){
+ if(SMESH_Actor *anActor = SMESH_Actor::SafeDownCast(ac)){
+ anActor->GetMapper()->ScalarVisibilityOff();
+ }
+ }
+ ::RepaintCurrentView();
+ }
}
//=============================================================================
pts[1] = idNodes[1];
vtkUnstructuredGrid *ugrid =
- vtkUnstructuredGrid::SafeDownCast(ac->DataSource);
+ vtkUnstructuredGrid::SafeDownCast(ac->GetUnstructuredGrid());
vtkUnstructuredGrid *newugrid = vtkUnstructuredGrid::New();
newugrid->SetPoints(ugrid->GetPoints());
newugrid->InsertNextCell(VTK_LINE, 2, pts);
pts[2] = idNodes[2];
}
vtkUnstructuredGrid *ugrid =
- vtkUnstructuredGrid::SafeDownCast(ac->DataSource);
+ vtkUnstructuredGrid::SafeDownCast(ac->GetUnstructuredGrid());
vtkUnstructuredGrid *newugrid = vtkUnstructuredGrid::New();
newugrid->SetPoints(ugrid->GetPoints());
newugrid->InsertNextCell(VTK_TRIANGLE, 3, pts);
SMESH_Actor *ac = FindActor(aMesh, result, true);
vtkUnstructuredGrid *ugrid =
- vtkUnstructuredGrid::SafeDownCast(ac->DataSource);
+ vtkUnstructuredGrid::SafeDownCast(ac->GetUnstructuredGrid());
if (result)
{
Ids->InsertId(3, idNodes[3]);
}
- // vtkUnstructuredGrid* ugrid = vtkUnstructuredGrid::SafeDownCast( ac->DataSource );
+ // vtkUnstructuredGrid* ugrid = vtkUnstructuredGrid::SafeDownCast( ac->GetUnstructuredGrid() );
vtkUnstructuredGrid *newugrid = vtkUnstructuredGrid::New();
newugrid->SetPoints(ugrid->GetPoints());
newugrid->InsertNextCell(VTK_QUAD, Ids);
Ids->InsertId(3, idNodes[3]);
vtkUnstructuredGrid *ugrid =
- vtkUnstructuredGrid::SafeDownCast(ac->DataSource);
+ vtkUnstructuredGrid::SafeDownCast(ac->GetUnstructuredGrid());
vtkUnstructuredGrid *newugrid = vtkUnstructuredGrid::New();
newugrid->SetPoints(ugrid->GetPoints());
newugrid->InsertNextCell(VTK_TETRA, Ids);
Ids->InsertId(7, idNodes[7]);
vtkUnstructuredGrid *ugrid =
- vtkUnstructuredGrid::SafeDownCast(ac->DataSource);
+ vtkUnstructuredGrid::SafeDownCast(ac->GetUnstructuredGrid());
vtkUnstructuredGrid *newugrid = vtkUnstructuredGrid::New();
newugrid->SetPoints(ugrid->GetPoints());
newugrid->InsertNextCell(VTK_HEXAHEDRON, Ids);
*
*/
//=============================================================================
-void SMESHGUI::AddFace(SMESH::SMESH_Mesh_ptr aMesh,
- const TColStd_MapOfInteger & MapIndex, bool reverse)
+void SMESHGUI::AddFace(SMESH::SMESH_Mesh_ptr theMesh,
+ const TColStd_MapOfInteger & MapIndex,
+ bool reverse)
{
- QApplication::setOverrideCursor(Qt::waitCursor);
- Standard_Boolean result;
- SMESH_Actor *ac = FindActor(aMesh, result, true);
- if (result)
- {
- TColStd_MapIteratorOfMapOfInteger ite(MapIndex);
- SMESH::long_array_var anArrayOfIdeces = new SMESH::long_array;
- anArrayOfIdeces->length(MapIndex.Extent());
-
- int i = 0;
- for (; ite.More(); ite.Next())
- {
- anArrayOfIdeces[i] = ac->GetIdSMESHDSNode(ite.Key());
- i++;
- }
-
- int tmp;
- if (MapIndex.Extent() == 4)
- {
- int idNodes[4];
- int i = 0;
- TColStd_MapIteratorOfMapOfInteger ite1(MapIndex);
- for (; ite1.More(); ite1.Next())
- {
- idNodes[i] = ite1.Key();
- i++;
- }
-
- vtkUnstructuredGrid *ugrid =
- vtkUnstructuredGrid::SafeDownCast(ac->DataSource);
- float *p0 = ugrid->GetPoint(idNodes[0]);
- float *p1 = ugrid->GetPoint(idNodes[1]);
- float *p2 = ugrid->GetPoint(idNodes[2]);
- float *p3 = ugrid->GetPoint(idNodes[3]);
-
- gp_Pnt P0(p0[0], p0[1], p0[2]);
-
- gp_Vec V1(P0, gp_Pnt(p1[0], p1[1], p1[2]));
- gp_Vec V2(P0, gp_Pnt(p2[0], p2[1], p2[2]));
- gp_Vec V3(P0, gp_Pnt(p3[0], p3[1], p3[2]));
-
- gp_Vec Cross1 = V1 ^ V2;
- gp_Vec Cross2 = V2 ^ V3;
-
- if (Cross1.Dot(Cross2) < 0)
- {
-
- V1 = gp_Vec(P0, gp_Pnt(p2[0], p2[1], p2[2]));
- V2 = gp_Vec(P0, gp_Pnt(p1[0], p1[1], p1[2]));
- Cross1 = V1 ^ V2;
- Cross2 = V2 ^ V3;
-
- if (Cross1.Dot(Cross2) < 0)
- {
- tmp = anArrayOfIdeces[2];
- anArrayOfIdeces[2] = anArrayOfIdeces[3];
- anArrayOfIdeces[3] = tmp;
- }
- else
- {
- tmp = anArrayOfIdeces[1];
- anArrayOfIdeces[1] = anArrayOfIdeces[2];
- anArrayOfIdeces[2] = tmp;
- }
- }
- }
-
- // int tmp;
- if (reverse)
- {
- for (i = 0; i < (MapIndex.Extent() / 2); i++)
- {
- tmp = anArrayOfIdeces[i];
- anArrayOfIdeces[i] = anArrayOfIdeces[MapIndex.Extent() - i - 1];
- anArrayOfIdeces[MapIndex.Extent() - i - 1] = tmp;
- }
- }
- SMESH::SMESH_MeshEditor_var aMeshEditor = aMesh->GetMeshEditor();
- aMeshEditor->AddFace(anArrayOfIdeces);
- }
- if (myAutomaticUpdate)
- {
- SMESH_Actor *Mesh = smeshGUI->ReadScript(aMesh);
- if (Mesh != NULL)
- {
- smeshGUI->DisplayActor(Mesh);
- smeshGUI->DisplayEdges(Mesh);
- smeshGUI->ChangeRepresentation(Mesh, Mesh->getDisplayMode());
- AddActorInSelection(Mesh);
- }
- }
- QApplication::restoreOverrideCursor();
+ QAD_WaitCursor wc;
+ try{
+ SALOMEDS::SObject_var aSobj = myStudyAPI.FindObject(theMesh);
+ CORBA::String_var anEntry = aSobj->GetID();
+ if(SMESH_Actor* anActor = ::FindActorByEntry(anEntry.in())){
+ SMESH::long_array_var anArrayOfIdeces = new SMESH::long_array;
+ anArrayOfIdeces->length(MapIndex.Extent());
+ TColStd_MapIteratorOfMapOfInteger ite(MapIndex);
+ for(int i = 0; ite.More(); ite.Next(), i++){
+ anArrayOfIdeces[i] = anActor->GetNodeObjId(ite.Key());
+ }
+ int tmp;
+ if(MapIndex.Extent() == 4){
+ int idNodes[4];
+ TColStd_MapIteratorOfMapOfInteger ite1(MapIndex);
+ for(int i = 0; ite1.More(); ite1.Next(), i++){
+ idNodes[i] = ite1.Key();
+ }
+ vtkUnstructuredGrid *ugrid = anActor->GetUnstructuredGrid();
+ float *p0 = ugrid->GetPoint(idNodes[0]);
+ float *p1 = ugrid->GetPoint(idNodes[1]);
+ float *p2 = ugrid->GetPoint(idNodes[2]);
+ float *p3 = ugrid->GetPoint(idNodes[3]);
+
+ gp_Pnt P0(p0[0], p0[1], p0[2]);
+
+ gp_Vec V1(P0, gp_Pnt(p1[0], p1[1], p1[2]));
+ gp_Vec V2(P0, gp_Pnt(p2[0], p2[1], p2[2]));
+ gp_Vec V3(P0, gp_Pnt(p3[0], p3[1], p3[2]));
+
+ gp_Vec Cross1 = V1 ^ V2;
+ gp_Vec Cross2 = V2 ^ V3;
+
+ if(Cross1.Dot(Cross2) < 0){
+ V1 = gp_Vec(P0, gp_Pnt(p2[0], p2[1], p2[2]));
+ V2 = gp_Vec(P0, gp_Pnt(p1[0], p1[1], p1[2]));
+ Cross1 = V1 ^ V2;
+ Cross2 = V2 ^ V3;
+
+ if(Cross1.Dot(Cross2) < 0){
+ tmp = anArrayOfIdeces[2];
+ anArrayOfIdeces[2] = anArrayOfIdeces[3];
+ anArrayOfIdeces[3] = tmp;
+ }else{
+ tmp = anArrayOfIdeces[1];
+ anArrayOfIdeces[1] = anArrayOfIdeces[2];
+ anArrayOfIdeces[2] = tmp;
+ }
+ }
+ }
+ if(reverse){
+ for(int i = 0; i < (MapIndex.Extent() / 2); i++){
+ tmp = anArrayOfIdeces[i];
+ anArrayOfIdeces[i] = anArrayOfIdeces[MapIndex.Extent() - i - 1];
+ anArrayOfIdeces[MapIndex.Extent() - i - 1] = tmp;
+ }
+ }
+ SMESH::SMESH_MeshEditor_var aMeshEditor = theMesh->GetMeshEditor();
+ aMeshEditor->AddFace(anArrayOfIdeces);
+ if(myAutomaticUpdate){
+ CORBA::Long anId = smeshGUI->myStudy->StudyId();
+ if(TVisualObjPtr aVisualObj = GetVisualObj(anId,anEntry.in())){
+ aVisualObj->Update(true);
+ }
+ AddActorInSelection(anActor);
+ }
+ }
+ }catch(SALOME::SALOME_Exception& exc) {
+ INFOS("Follow exception was cought:\n\t"<<exc.details.text);
+ }catch(const std::exception& exc){
+ INFOS("Follow exception was cought:\n\t"<<exc.what());
+ }catch(...){
+ INFOS("Unknown exception was cought !!!");
+ }
}
//=============================================================================
*
*/
//=============================================================================
-void SMESHGUI::AddVolume(SMESH::SMESH_Mesh_ptr aMesh,
- const TColStd_MapOfInteger & MapIndex)
+void SMESHGUI::AddVolume(SMESH::SMESH_Mesh_ptr theMesh,
+ const TColStd_MapOfInteger & MapIndex)
{
- QApplication::setOverrideCursor(Qt::waitCursor);
- Standard_Boolean result;
- SMESH_Actor *ac = FindActor(aMesh, result, true);
- if (result)
- {
- TColStd_MapIteratorOfMapOfInteger ite(MapIndex);
- SMESH::long_array_var anArrayOfIdeces = new SMESH::long_array;
- anArrayOfIdeces->length(MapIndex.Extent());
-
- int i = 0;
- for (; ite.More(); ite.Next())
- {
- anArrayOfIdeces[i] = ac->GetIdSMESHDSNode(ite.Key());
- i++;
- }
-
- SMESH::SMESH_MeshEditor_var aMeshEditor = aMesh->GetMeshEditor();
- aMeshEditor->AddVolume(anArrayOfIdeces);
- }
- if (myAutomaticUpdate)
- {
- SMESH_Actor *Mesh = smeshGUI->ReadScript(aMesh);
- if (Mesh != NULL)
- {
- smeshGUI->DisplayActor(Mesh);
- smeshGUI->DisplayEdges(Mesh);
- smeshGUI->ChangeRepresentation(Mesh, Mesh->getDisplayMode());
- AddActorInSelection(Mesh);
- }
- }
- QApplication::restoreOverrideCursor();
+ QAD_WaitCursor wc;
+ try{
+ SALOMEDS::SObject_var aSobj = myStudyAPI.FindObject(theMesh);
+ CORBA::String_var anEntry = aSobj->GetID();
+ if(SMESH_Actor* anActor = ::FindActorByEntry(anEntry.in())){
+ SMESH::long_array_var anArrayOfIdeces = new SMESH::long_array;
+ anArrayOfIdeces->length(MapIndex.Extent());
+ TColStd_MapIteratorOfMapOfInteger ite(MapIndex);
+ for(int i = 0; ite.More(); ite.Next(), i++){
+ anArrayOfIdeces[i] = anActor->GetNodeObjId(ite.Key());
+ }
+ SMESH::SMESH_MeshEditor_var aMeshEditor = theMesh->GetMeshEditor();
+ aMeshEditor->AddVolume(anArrayOfIdeces);
+ if(myAutomaticUpdate){
+ CORBA::Long anId = smeshGUI->myStudy->StudyId();
+ if(TVisualObjPtr aVisualObj = GetVisualObj(anId,anEntry.in())){
+ aVisualObj->Update(true);
+ }
+ }
+ }
+ }catch(SALOME::SALOME_Exception& exc) {
+ INFOS("Follow exception was cought:\n\t"<<exc.details.text);
+ }catch(const std::exception& exc){
+ INFOS("Follow exception was cought:\n\t"<<exc.what());
+ }catch(...){
+ INFOS("Unknown exception was cought !!!");
+ }
}
-
//=============================================================================
/*!
*
*/
//=============================================================================
-void SMESHGUI::AddEdge(SMESH::SMESH_Mesh_ptr aMesh,
- const TColStd_MapOfInteger & MapIndex)
+void SMESHGUI::AddEdge(SMESH::SMESH_Mesh_ptr theMesh,
+ const TColStd_MapOfInteger & MapIndex)
{
- QApplication::setOverrideCursor(Qt::waitCursor);
- Standard_Boolean result;
- SMESH_Actor *ac = FindActor(aMesh, result, true);
- if (result)
- {
- TColStd_MapIteratorOfMapOfInteger ite(MapIndex);
- SMESH::long_array_var anArrayOfIdeces = new SMESH::long_array;
- anArrayOfIdeces->length(MapIndex.Extent());
-
- int i = 0;
- for (; ite.More(); ite.Next())
- {
- anArrayOfIdeces[i] = ac->GetIdSMESHDSNode(ite.Key());
- i++;
- }
-
- SMESH::SMESH_MeshEditor_var aMeshEditor = aMesh->GetMeshEditor();
- aMeshEditor->AddEdge(anArrayOfIdeces);
- }
- if (myAutomaticUpdate)
- {
- SMESH_Actor *Mesh = smeshGUI->ReadScript(aMesh);
- if (Mesh != NULL)
- {
- smeshGUI->DisplayActor(Mesh);
- smeshGUI->DisplayEdges(Mesh);
- smeshGUI->ChangeRepresentation(Mesh, Mesh->getDisplayMode());
- AddActorInSelection(Mesh);
- }
- }
- QApplication::restoreOverrideCursor();
+ QAD_WaitCursor wc;
+ try{
+ SALOMEDS::SObject_var aSobj = myStudyAPI.FindObject(theMesh);
+ CORBA::String_var anEntry = aSobj->GetID();
+ if(SMESH_Actor* anActor = ::FindActorByEntry(anEntry.in())){
+ SMESH::long_array_var anArrayOfIdeces = new SMESH::long_array;
+ anArrayOfIdeces->length(MapIndex.Extent());
+ TColStd_MapIteratorOfMapOfInteger ite(MapIndex);
+ for(int i = 0; ite.More(); ite.Next(), i++){
+ anArrayOfIdeces[i] = anActor->GetNodeObjId(ite.Key());
+ }
+ SMESH::SMESH_MeshEditor_var aMeshEditor = theMesh->GetMeshEditor();
+ aMeshEditor->AddEdge(anArrayOfIdeces);
+ if(myAutomaticUpdate){
+ CORBA::Long anId = smeshGUI->myStudy->StudyId();
+ if(TVisualObjPtr aVisualObj = GetVisualObj(anId,anEntry.in())){
+ aVisualObj->Update(true);
+ }
+ }
+ }
+ }catch(SALOME::SALOME_Exception& exc) {
+ INFOS("Follow exception was cought:\n\t"<<exc.details.text);
+ }catch(const std::exception& exc){
+ INFOS("Follow exception was cought:\n\t"<<exc.what());
+ }catch(...){
+ INFOS("Unknown exception was cought !!!");
+ }
}
-
//=============================================================================
/*!
*
*/
//=============================================================================
-void SMESHGUI::AddNode(SMESH::SMESH_Mesh_ptr aMesh, float x, float y, float z)
+void SMESHGUI::AddNode(SMESH::SMESH_Mesh_ptr theMesh,
+ float x, float y, float z)
{
- QApplication::setOverrideCursor(Qt::waitCursor);
- Standard_Boolean result;
- SMESH_Actor *ac = FindActor(aMesh, result, true);
- if (result)
- {
- SMESH::SMESH_MeshEditor_var aMeshEditor = aMesh->GetMeshEditor();
- aMeshEditor->AddNode(x, y, z);
-
- if (myAutomaticUpdate)
- {
- SMESH_Actor *Mesh = smeshGUI->ReadScript(aMesh);
- if (Mesh != NULL)
- {
- smeshGUI->DisplayActor(Mesh);
- smeshGUI->DisplayEdges(Mesh);
- smeshGUI->ChangeRepresentation(Mesh, Mesh->getDisplayMode());
- AddActorInSelection(Mesh);
- }
- }
- }
- QApplication::restoreOverrideCursor();
+ QAD_WaitCursor wc;
+ try{
+ SALOMEDS::SObject_var aSobj = myStudyAPI.FindObject(theMesh);
+ CORBA::String_var anEntry = aSobj->GetID();
+ if(SMESH_Actor* anActor = ::FindActorByEntry(anEntry.in())){
+ SMESH::SMESH_MeshEditor_var aMeshEditor = theMesh->GetMeshEditor();
+ aMeshEditor->AddNode(x, y, z);
+ if(myAutomaticUpdate){
+ CORBA::Long anId = smeshGUI->myStudy->StudyId();
+ if(TVisualObjPtr aVisualObj = GetVisualObj(anId,anEntry.in())){
+ aVisualObj->Update(true);
+ }
+ }
+ }
+ }catch(SALOME::SALOME_Exception& exc) {
+ INFOS("Follow exception was cought:\n\t"<<exc.details.text);
+ }catch(const std::exception& exc){
+ INFOS("Follow exception was cought:\n\t"<<exc.what());
+ }catch(...){
+ INFOS("Unknown exception was cought !!!");
+ }
}
-
//=============================================================================
/*!
*
//===============================================================================
void SMESHGUI::OnEditDelete()
{
- if (QAD_MessageBox::warn2
- (QAD_Application::getDesktop(),
- tr("SMESH_WRN_WARNING"),
- tr("SMESH_REALLY_DELETE"),
- tr("SMESH_BUT_YES"), tr("SMESH_BUT_NO"), 1, 0, 0) != 1)
- return;
-
- int nbSf = myActiveStudy->getStudyFramesCount();
-
- Standard_Boolean found;
- SALOMEDS::Study_var aStudy = myActiveStudy->getStudyDocument();
- SALOMEDS::StudyBuilder_var aStudyBuilder = myStudy->NewBuilder();
- SALOMEDS::GenericAttribute_var anAttr;
- SALOMEDS::AttributeIOR_var anIOR;
-
- SALOME_Selection *Sel =
- SALOME_Selection::Selection(myActiveStudy->getSelection());
- SALOME_ListIteratorOfListIO It(Sel->StoredIObjects());
- for (; It.More(); It.Next())
- {
- Handle(SALOME_InteractiveObject) IObject = It.Value();
- if (IObject->hasEntry())
- {
- SALOMEDS::SObject_var SO =
- myStudy->FindObjectID(IObject->getEntry());
-
- /* Erase child graphical objects */
- SALOMEDS::ChildIterator_var it = aStudy->NewChildIterator(SO);
- for (; it->More(); it->Next())
- {
- SALOMEDS::SObject_var CSO = it->Value();
- if (CSO->FindAttribute(anAttr, "AttributeIOR"))
- {
- anIOR = SALOMEDS::AttributeIOR::_narrow(anAttr);
-
- for (int i = 0; i < nbSf; i++)
- {
- QAD_StudyFrame *sf = myActiveStudy->getStudyFrame(i);
- if (sf->getTypeView() == VIEW_VTK)
- {
- vtkRenderer *Renderer =
- ((VTKViewer_ViewFrame *) smeshGUI->
- myActiveStudy->getActiveStudyFrame()->
- getRightFrame()->getViewFrame())->getRenderer();
- SMESH_Actor *ac =
- smeshGUI->FindActorByEntry(CSO->GetID(), found,
- false);
- if (found)
- {
- Renderer->RemoveActor(ac->EdgeDevice);
- Renderer->RemoveActor(ac->EdgeShrinkDevice);
- Renderer->RemoveActor(ac);
- }
- }
- }
- }
- }
-
- /* Erase main graphical object */
- for (int i = 0; i < nbSf; i++)
- {
- QAD_StudyFrame *sf = myActiveStudy->getStudyFrame(i);
- if (sf->getTypeView() == VIEW_VTK)
- {
- vtkRenderer *Renderer =
- ((VTKViewer_ViewFrame *) smeshGUI->myActiveStudy->
- getActiveStudyFrame()->getRightFrame()->
- getViewFrame())->getRenderer();
- VTKViewer_RenderWindowInteractor *myRenderInter =
- ((VTKViewer_ViewFrame *) sf->getRightFrame()->
- getViewFrame())->getRWInteractor();
- SMESH_Actor *ac =
- smeshGUI->FindActorByEntry(IObject->getEntry(), found,
- false);
- if (found)
- {
- Renderer->RemoveActor(ac->EdgeDevice);
- Renderer->RemoveActor(ac->EdgeShrinkDevice);
- }
- myRenderInter->Remove(IObject);
- }
- }
-
- /* Erase objects in Study */
- SALOMEDS::SObject_var obj =
- myStudy->FindObjectID(IObject->getEntry());
- if (!obj->_is_nil())
- {
- QAD_Operation *op =
- new SALOMEGUI_ImportOperation(myActiveStudy);
- op->start();
- aStudyBuilder->RemoveObject(obj);
- op->finish();
- }
-
- } /* IObject->hasEntry() */
- } /* more/next */
+ if (QAD_MessageBox::warn2
+ (QAD_Application::getDesktop(),
+ tr("SMESH_WRN_WARNING"),
+ tr("SMESH_REALLY_DELETE"),
+ tr("SMESH_BUT_YES"), tr("SMESH_BUT_NO"), 1, 0, 0) != 1)
+ return;
+
+ int nbSf = myActiveStudy->getStudyFramesCount();
+
+ Standard_Boolean found;
+ SALOMEDS::Study_var aStudy = myActiveStudy->getStudyDocument();
+ SALOMEDS::StudyBuilder_var aStudyBuilder = myStudy->NewBuilder();
+ SALOMEDS::GenericAttribute_var anAttr;
+ SALOMEDS::AttributeIOR_var anIOR;
+
+ SALOME_Selection *Sel = SALOME_Selection::Selection(myActiveStudy->getSelection());
+ SALOME_ListIteratorOfListIO It(Sel->StoredIObjects());
+ for(; It.More(); It.Next()){
+ Handle(SALOME_InteractiveObject) IObject = It.Value();
+ if(IObject->hasEntry()){
+ SALOMEDS::SObject_var SO = myStudy->FindObjectID(IObject->getEntry());
+
+ /* Erase child graphical objects */
+ SALOMEDS::ChildIterator_var it = aStudy->NewChildIterator(SO);
+ for(; it->More(); it->Next()){
+ SALOMEDS::SObject_var CSO = it->Value();
+ if(CSO->FindAttribute(anAttr, "AttributeIOR")){
+ anIOR = SALOMEDS::AttributeIOR::_narrow(anAttr);
+
+ for(int i = 0; i < nbSf; i++){
+ QAD_StudyFrame *sf = myActiveStudy->getStudyFrame(i);
+ CORBA::String_var anEntry = CSO->GetID();
+ if(SMESH_Actor* anActor = ::FindActorByEntry(sf,anEntry.in())){
+ RemoveActor(sf,anActor);
+ }
+ }
+ }
+ }
+
+ /* Erase main graphical object */
+ for(int i = 0; i < nbSf; i++){
+ QAD_StudyFrame *sf = myActiveStudy->getStudyFrame(i);
+ if(SMESH_Actor* anActor = ::FindActorByEntry(sf,IObject->getEntry())){
+ RemoveActor(sf,anActor);
+ }
+ }
+
+ // Remove object(s) from data structures
+ SALOMEDS::SObject_var obj = myStudy->FindObjectID(IObject->getEntry());
+ if(!obj->_is_nil()){
+ SMESH::SMESH_Group_var aGroup = SMESH::SMESH_Group ::_narrow(obj->GetObject());
+ SMESH::SMESH_subMesh_var aSubMesh = SMESH::SMESH_subMesh::_narrow(obj->GetObject());
+
+ if ( !aGroup->_is_nil() ) { // DELETE GROUP
+ SMESH::SMESH_Mesh_var aMesh = aGroup->GetMesh();
+ aMesh->RemoveGroup( aGroup );
+ }
+ else if ( !aSubMesh->_is_nil() ) { // DELETE SUBMESH
+ SMESH::SMESH_Mesh_var aMesh = aSubMesh->GetFather();
+ aMesh->RemoveSubMesh( aSubMesh );
+ }
+ else {// default action: remove SObject from the study
+ // san - it's no use opening a transaction here until UNDO/REDO is provided in SMESH
+ //QAD_Operation *op = new SALOMEGUI_ImportOperation(myActiveStudy);
+ //op->start();
+ aStudyBuilder->RemoveObjectWithChildren( obj );
+ //op->finish();
+ }
+ }
+
+ } /* IObject->hasEntry() */
+ } /* more/next */
+
+ /* Clear any previous selection */
+ Sel->ClearIObjects();
+ myActiveStudy->updateObjBrowser();
+}
- /* Clear any previous selection */
- Sel->ClearIObjects();
- myActiveStudy->updateObjBrowser();
+//=======================================================================
+// name : SMESHGUI::GetFilterMgr
+// Purpose : Get filter manager
+//=======================================================================
+SMESH::FilterManager_ptr SMESHGUI::GetFilterMgr()
+{
+ return myFilterMgr;
}
#define SMESHGUI_HeaderFile
#include "TColStd_MapOfInteger.hxx"
+#include <map>
#include "SMESHDS_Document.hxx"
// SALOME Includes
+#include "SALOMEGUI.h"
#include "QAD_Desktop.h"
#include "SALOME_Selection.h"
#include "SALOME_InteractiveObject.hxx"
-#include "SMESH_Actor.h"
-
#include "SMESHGUI_StudyAPI.h"
+#include "SMESHGUI_Hypotheses.h"
// IDL Headers
#include <SALOMEconfig.h>
#include CORBA_SERVER_HEADER(SMESH_Gen)
#include CORBA_SERVER_HEADER(SMESH_Mesh)
+#include CORBA_SERVER_HEADER(SMESH_Group)
#include CORBA_SERVER_HEADER(SMESH_Hypothesis)
-#include CORBA_SERVER_HEADER(SMESH_BasicHypothesis)
#include CORBA_SERVER_HEADER(GEOM_Gen)
#include CORBA_SERVER_HEADER(SALOMEDS_Attributes)
+#include CORBA_SERVER_HEADER(SMESH_Filter)
// QT Includes
#include <qstringlist.h>
-// VTK Inlcudes
-#include <vtkScalarBarActor.h>
+// VTK Inlcludes
+
+class vtkActorCollection;
+class vtkActor2DCollection;
+class vtkScalarBarActor;
+class vtkActor;
+
+class SMESH_Actor;
//=================================================================================
// class : SMESHGUI
// purpose :
//=================================================================================
-class SMESHGUI : public QObject
+class SMESHGUI : public SALOMEGUI
{
Q_OBJECT
// vtkScalarBarActor* myScalarBar;
+ SMESHDS_Document * myDocument;//NBU
+
bool myAutomaticUpdate;
+ SMESH::FilterManager_var myFilterMgr;
+
+ // Hypotheses/algorithms from plugin libraries
+ map<string, HypothesisData*> myHypothesesMap;
+ map<string, HypothesisData*> myAlgorithmsMap;
+ map<string, SMESHGUI_GenericHypothesisCreator*> myHypCreatorMap;
+
public :
- SMESHGUI();
+ SMESHGUI( const QString& name = "", QObject* parent = 0 );
~SMESHGUI();
static SMESHGUI* GetOrCreateSMESHGUI( QAD_Desktop* desktop );
SALOMEDS::Study_ptr GetStudy();
SMESHGUI_StudyAPI GetStudyAPI();
- vtkScalarBarActor* GetScalarBar();
-
QDialog* GetActiveDialogBox() ;
void SetActiveDialogBox(QDialog* aDlg) ;
bool DefineDlgPosition(QWidget* aDlg, int& x, int& y) ;
- /* Managed by IAPP */
- Standard_EXPORT static bool OnGUIEvent ( int theCommandID, QAD_Desktop* parent) ;
- Standard_EXPORT static bool OnMousePress ( QMouseEvent* pe, QAD_Desktop* parent,
- QAD_StudyFrame* studyFrame );
- Standard_EXPORT static bool OnMouseMove ( QMouseEvent* pe, QAD_Desktop* parent,
- QAD_StudyFrame* studyFrame );
- Standard_EXPORT static bool OnKeyPress ( QKeyEvent* pe, QAD_Desktop* parent,
- QAD_StudyFrame* studyFrame );
- Standard_EXPORT static void activeStudyChanged ( QAD_Desktop* parent );
- Standard_EXPORT static bool SetSettings ( QAD_Desktop* parent );
- Standard_EXPORT static void DefinePopup( QString & theContext,
- QString & theParent,
- QString & theObject );
- Standard_EXPORT static bool CustomPopup ( QAD_Desktop* parent,
- QPopupMenu* popup,
- const QString& theContext,
- const QString& theParent,
- const QString& theObject );
- Standard_EXPORT static void BuildPresentation(const Handle(SALOME_InteractiveObject)&);
+ virtual bool OnGUIEvent (int theCommandID, QAD_Desktop* parent);
+ virtual bool OnMousePress (QMouseEvent* pe, QAD_Desktop* parent, QAD_StudyFrame* studyFrame);
+ virtual bool OnMouseMove (QMouseEvent* pe, QAD_Desktop* parent, QAD_StudyFrame* studyFrame);
+ virtual bool OnKeyPress (QKeyEvent* pe, QAD_Desktop* parent, QAD_StudyFrame* studyFrame);
+ virtual bool ActiveStudyChanged( QAD_Desktop* parent );
+ virtual bool SetSettings ( QAD_Desktop* parent );
+ virtual void DefinePopup ( QString & theContext, QString & theParent, QString & theObject );
+ virtual bool CustomPopup ( QAD_Desktop* parent, QPopupMenu* popup, const QString & theContext,
+ const QString & theParent, const QString & theObject );
+ virtual void BuildPresentation ( const Handle(SALOME_InteractiveObject)& theIO );
+ virtual void SupportedViewType (int* buffer, int bufferSize);
+ virtual void Deactivate ();
void OnEditDelete();
/* Mesh Management */
SMESH::SMESH_Mesh_ptr InitMesh( GEOM::GEOM_Shape_ptr aShape, QString NameMesh );
SMESH::SMESH_subMesh_ptr AddSubMesh( SMESH::SMESH_Mesh_ptr aMesh, GEOM::GEOM_Shape_ptr aShape, QString NameMesh );
+ SMESH::SMESH_Group_ptr AddGroup( SMESH::SMESH_Mesh_ptr aMesh, SMESH::ElementType aType, QString aName );
+
+ /* Hypotheses and Algorithms Management */
+ void InitAvailableHypotheses ();
+ QStringList GetAvailableHypotheses (const bool isAlgo);
+ HypothesisData* GetHypothesisData (const char* aHypType);
+ SMESHGUI_GenericHypothesisCreator* GetHypothesisCreator (const QString& aHypType);
+
+ SMESH::SMESH_Hypothesis_ptr CreateHypothesis (const QString& aHypType,
+ const QString& aHypName,
+ const bool isAlgo = false);
- /* Hypothesis Management */
- SMESH::SMESH_Hypothesis_ptr CreateHypothesis( QString TypeHypothesis, QString NameHypothesis );
- void AddHypothesisOnMesh( SMESH::SMESH_Mesh_ptr aMesh, SMESH::SMESH_Hypothesis_ptr aHyp ) ;
- void AddHypothesisOnSubMesh( SMESH::SMESH_subMesh_ptr aSubMesh, SMESH::SMESH_Hypothesis_ptr aHyp ) ;
+ bool AddHypothesisOnMesh (SMESH::SMESH_Mesh_ptr aMesh, SMESH::SMESH_Hypothesis_ptr aHyp);
+ bool AddAlgorithmOnMesh (SMESH::SMESH_Mesh_ptr aMesh, SMESH::SMESH_Hypothesis_ptr aHyp);
- void RemoveHypothesisOrAlgorithmOnMesh( const Handle(SALOME_InteractiveObject)& IObject ) ;
- void RemoveHypothesisOrAlgorithmOnMesh( SALOMEDS::SObject_ptr MorSM, SMESH::SMESH_Hypothesis_ptr anHyp ) ;
+ bool AddHypothesisOnSubMesh (SMESH::SMESH_subMesh_ptr aSubMesh, SMESH::SMESH_Hypothesis_ptr aHyp);
+ bool AddAlgorithmOnSubMesh (SMESH::SMESH_subMesh_ptr aSubMesh, SMESH::SMESH_Hypothesis_ptr aHyp);
- void CreateLocalLength( QString TypeHypothesis, QString NameHypothesis, double Length );
- void CreateNbSegments( QString TypeHypothesis, QString NameHypothesis, int nbSegments );
- void CreateMaxElementArea( QString TypeHypothesis, QString NameHypothesis, double MaxArea );
- void CreateMaxElementVolume( QString TypeHypothesis, QString NameHypothesis, double MaxVolume );
+ bool RemoveHypothesisOrAlgorithmOnMesh (const Handle(SALOME_InteractiveObject)& IObject);
+ bool RemoveHypothesisOrAlgorithmOnMesh (SALOMEDS::SObject_ptr MorSM,
+ SMESH::SMESH_Hypothesis_ptr anHyp);
- /* Algorithms Management */
- void AddAlgorithmOnMesh( SMESH::SMESH_Mesh_ptr aMesh, SMESH::SMESH_Hypothesis_ptr aHyp );
- void AddAlgorithmOnSubMesh( SMESH::SMESH_subMesh_ptr aSubMesh, SMESH::SMESH_Hypothesis_ptr aHyp );
- void CreateAlgorithm( QString TypeAlgo, QString NameAlgo );
+ void SetPickable(SMESH_Actor* theActor = NULL);
/* NODES */
void ViewNodes();
vtkActor* SimulationMoveNode(SMESH_Actor* Mactor, int idnode);
void MoveNode( SMESH::SMESH_Mesh_ptr aMesh, int idnode, float x, float y, float z);
- void AddNode(SMESH_Actor*, int idnode, float x, float y, float z) ;
- void AddNodes( SMESH_Actor* Mactor, int number,
- const SMESH::double_array& coords, const SMESH::long_array& indexes);
void DisplaySimulationNode( SMESH::SMESH_Mesh_ptr aMesh, float x, float y, float z);
void DisplaySimulationMoveNode( vtkActor* ac, int idnode, float x, float y, float z);
- void RemoveNode(SMESH_Actor*, int idnode) ;
void RemoveNodes(SMESH::SMESH_Mesh_ptr aMesh, const TColStd_MapOfInteger& MapIndex) ;
- void RemoveNodes(SMESH_Actor* Mactor, int number,
- const SMESH::double_array& coords, const SMESH::long_array& indexes);
/* EDGES */
- void AddEdge(SMESH_Actor*, int idedge, int idnode1, int idnode2) ;
- void AddEdges( SMESH_Actor* Mactor, int number,
- const SMESH::double_array& coords, const SMESH::long_array& indexes);
void DisplayEdges(SMESH_Actor* ac, bool visibility = true);
void DisplayEdgesConnectivityLegendBox(vtkActor *ac);
void DisplaySimulationEdge( SMESH::SMESH_Mesh_ptr aMesh, const TColStd_MapOfInteger& MapIndex );
/* TRIANGLES */
- void AddTriangle(SMESH_Actor*, int idtri, int idnode1, int idnode2, int idnode3) ;
- void AddTriangles( SMESH_Actor* Mactor, int number,
- const SMESH::double_array& coords, const SMESH::long_array& indexes);
void DisplaySimulationTriangle( SMESH::SMESH_Mesh_ptr aMesh, const TColStd_MapOfInteger& MapIndex, bool reverse );
/* QUADRANGLES */
- void AddQuadrangle(SMESH_Actor*, int idquad, int idnode1, int idnode2,
- int idnode3, int idnode4) ;
- void AddQuadrangles( SMESH_Actor* Mactor, int number,
- const SMESH::double_array& coords, const SMESH::long_array& indexes);
void DisplaySimulationQuadrangle( SMESH::SMESH_Mesh_ptr aMesh, const TColStd_MapOfInteger& MapIndex, bool reverse );
/* VOLUMES */
- void AddTetra(SMESH_Actor*, int idtetra, int idnode1, int idnode2,
- int idnode3, int idnode4) ;
- void AddHexaedre(SMESH_Actor*, int idhexa, int idnode1, int idnode2,
- int idnode3, int idnode4, int idnode5, int idnode6, int idnode7, int idnode8) ;
- void AddTetras( SMESH_Actor* Mactor, int number,
- const SMESH::double_array& coords, const SMESH::long_array& indexes);
- void AddHexaedres( SMESH_Actor* Mactor, int number,
- const SMESH::double_array& coords, const SMESH::long_array& indexes);
void DisplaySimulationTetra( SMESH::SMESH_Mesh_ptr aMesh, const TColStd_MapOfInteger& MapIndex );
void DisplaySimulationHexa( SMESH::SMESH_Mesh_ptr aMesh, const TColStd_MapOfInteger& MapIndex );
/* ELEMENTS */
- void RemoveElement(SMESH_Actor*, int idnode);
void RemoveElements(SMESH::SMESH_Mesh_ptr aMesh, const TColStd_MapOfInteger& MapIndex) ;
- void RemoveElements(SMESH_Actor* Mactor, int number,
- const SMESH::double_array& coords, const SMESH::long_array& indexes);
void OrientationElements(SMESH::SMESH_Mesh_ptr aMesh, const TColStd_MapOfInteger& MapIndex);
void DiagonalInversion(SMESH::SMESH_Mesh_ptr aMesh, const TColStd_MapOfInteger& MapIndex);
SMESH::SMESH_Mesh_ptr ConvertIOinMesh(const Handle(SALOME_InteractiveObject)& IO, Standard_Boolean& testResult) ;
SMESH::SMESH_subMesh_ptr ConvertIOinSubMesh(const Handle(SALOME_InteractiveObject)& IO, Standard_Boolean& testResult) ;
+ SMESH::SMESH_Group_ptr ConvertIOinSMESHGroup(const Handle(SALOME_InteractiveObject)& IO, Standard_Boolean& testResult) ;
/* Geometry Client */
GEOM::GEOM_Shape_ptr ConvertIOinGEOMShape( const Handle(SALOME_InteractiveObject)& IO,
void SetViewMode(int commandId);
void ChangeRepresentation( SMESH_Actor* ac, int type );
- SMESH_Actor* FindActor(SMESH::SMESH_Mesh_ptr aMesh,
+ SMESH_Actor* FindActor(CORBA::Object_ptr theObj,
Standard_Boolean& testResult,
bool onlyInActiveView);
SMESH_Actor* FindActorByEntry(QString entry,
QString Bold, QString Italic, QString Shadow, QString Font,
QString Orientation, float Width, float Height,
int NbColors, int NbLabels);
- void DisplayScalarBar(bool visibility);
- void UpdateScalarBar(float MinRange, float MaxRange);
-
- void SetDisplaySettings();
+ void SetDisplaySettings();
SALOMEDS::Study::ListOfSObject* GetMeshesUsingAlgoOrHypothesis( SMESH::SMESH_Hypothesis_ptr AlgoOrHyp ) ;
static void setOrb();
/* Import/Export */ //NBU
- void Import_Document(QAD_Desktop* parent, int theCommandID);
+ static void Import_Mesh(QAD_Desktop* parent, int theCommandID);
static void Export_Mesh(QAD_Desktop* parent, int theCommandID);
+ /* Filter manager */
+ SMESH::FilterManager_ptr GetFilterMgr();
+
signals:
void SignalDeactivateActiveDialog() ;
void SignalCloseAllDialogs() ;
//=================================================================================
void SMESHGUI_AddEdgeDlg::ClickOnCancel()
{
- QAD_Application::getDesktop()->SetSelectionMode( 4 );
+ QAD_Application::getDesktop()->SetSelectionMode( ActorSelection );
disconnect( mySelection, 0, this, 0 );
mySMESHGUI->ResetState() ;
mySMESHGUI->EraseSimulationActors();
if(nbNodes < 1)
return ;
- if ( mySelection->SelectionMode() != 1 ) {
+ if ( mySelection->SelectionMode() != NodeSelection ) {
QAD_MessageBox::warn1 ( QAD_Application::getDesktop(), tr ("SMESH_WRN_WARNING"),
- tr ("SMESH_WRN_SELECTIONMODE_NODES"), tr ("SMESH_BUT_YES") );
+ tr ("SMESH_WRN_SELECTIONMODE_NODES"), tr ("SMESH_BUT_OK") );
return;
}
//=================================================================================
void SMESHGUI_AddFaceDlg::ClickOnCancel()
{
- QAD_Application::getDesktop()->SetSelectionMode( 4 );
+ QAD_Application::getDesktop()->SetSelectionMode( ActorSelection );
disconnect( mySelection, 0, this, 0 );
mySMESHGUI->ResetState() ;
mySMESHGUI->EraseSimulationActors();
if(nbNodes < 1)
return ;
- if ( mySelection->SelectionMode() != 1 ) {
+ if ( mySelection->SelectionMode() != NodeSelection ) {
QAD_MessageBox::warn1 ( QAD_Application::getDesktop(), tr ("SMESH_WRN_WARNING"),
- tr ("SMESH_WRN_SELECTIONMODE_NODES"), tr ("SMESH_BUT_YES") );
+ tr ("SMESH_WRN_SELECTIONMODE_NODES"), tr ("SMESH_BUT_OK") );
return;
}
#include "QAD_Application.h"
#include "QAD_Desktop.h"
+#include "QAD_MessageBox.h"
+#include "QAD_WaitCursor.h"
+#include "QAD_Operation.h"
+
#include "utilities.h"
// QT Includes
-#include <qbuttongroup.h>
#include <qgroupbox.h>
#include <qlabel.h>
#include <qlineedit.h>
#include <qpushbutton.h>
-#include <qradiobutton.h>
#include <qlayout.h>
-#include <qvariant.h>
-#include <qtooltip.h>
-#include <qwhatsthis.h>
-#include <qimage.h>
#include <qpixmap.h>
-
//=================================================================================
// class : SMESHGUI_AddSubMeshDlg()
// purpose : Constructs a SMESHGUI_AddSubMeshDlg which is a child of 'parent', with the
// TRUE to construct a modal dialog.
//=================================================================================
SMESHGUI_AddSubMeshDlg::SMESHGUI_AddSubMeshDlg( QWidget* parent, const char* name, SALOME_Selection* Sel, bool modal, WFlags fl )
- : QDialog( parent, name, modal, WStyle_Customize | WStyle_NormalBorder | WStyle_Title | WStyle_SysMenu )
+ : QDialog( parent, name, modal, WStyle_Customize | WStyle_NormalBorder | WStyle_Title | WStyle_SysMenu | WDestructiveClose )
{
- QPixmap image1(QAD_Desktop::getResourceManager()->loadPixmap( "SMESH",tr("ICON_DLG_ADD_SUBMESH")));
QPixmap image0(QAD_Desktop::getResourceManager()->loadPixmap( "SMESH",tr("ICON_SELECT")));
if ( !name )
setName( "SMESHGUI_AddSubMeshDlg" );
- resize( 303, 175 );
setCaption( tr( "SMESH_ADD_SUBMESH" ) );
setSizeGripEnabled( TRUE );
- SMESHGUI_AddSubMeshDlgLayout = new QGridLayout( this );
+ QGridLayout* SMESHGUI_AddSubMeshDlgLayout = new QGridLayout( this );
SMESHGUI_AddSubMeshDlgLayout->setSpacing( 6 );
SMESHGUI_AddSubMeshDlgLayout->setMargin( 11 );
/***************************************************************/
- GroupConstructors = new QButtonGroup( this, "GroupConstructors" );
- GroupConstructors->setTitle( tr( "SMESH_SUBMESH" ) );
- GroupConstructors->setExclusive( TRUE );
- GroupConstructors->setColumnLayout(0, Qt::Vertical );
- GroupConstructors->layout()->setSpacing( 0 );
- GroupConstructors->layout()->setMargin( 0 );
- GroupConstructorsLayout = new QGridLayout( GroupConstructors->layout() );
- GroupConstructorsLayout->setAlignment( Qt::AlignTop );
- GroupConstructorsLayout->setSpacing( 6 );
- GroupConstructorsLayout->setMargin( 11 );
- Constructor1 = new QRadioButton( GroupConstructors, "Constructor1" );
- Constructor1->setText( tr( "" ) );
- Constructor1->setPixmap( image1 );
- Constructor1->setChecked( TRUE );
- Constructor1->setSizePolicy( QSizePolicy( (QSizePolicy::SizeType)1, (QSizePolicy::SizeType)0, Constructor1->sizePolicy().hasHeightForWidth() ) );
- Constructor1->setMinimumSize( QSize( 50, 0 ) );
- GroupConstructorsLayout->addWidget( Constructor1, 0, 0 );
- QSpacerItem* spacer = new QSpacerItem( 20, 20, QSizePolicy::Expanding, QSizePolicy::Minimum );
- GroupConstructorsLayout->addItem( spacer, 0, 1 );
- SMESHGUI_AddSubMeshDlgLayout->addWidget( GroupConstructors, 0, 0 );
-
- /***************************************************************/
- GroupButtons = new QGroupBox( this, "GroupButtons" );
- GroupButtons->setGeometry( QRect( 10, 10, 281, 48 ) );
- GroupButtons->setTitle( tr( "" ) );
- GroupButtons->setColumnLayout(0, Qt::Vertical );
- GroupButtons->layout()->setSpacing( 0 );
- GroupButtons->layout()->setMargin( 0 );
- GroupButtonsLayout = new QGridLayout( GroupButtons->layout() );
- GroupButtonsLayout->setAlignment( Qt::AlignTop );
- GroupButtonsLayout->setSpacing( 6 );
- GroupButtonsLayout->setMargin( 11 );
- buttonCancel = new QPushButton( GroupButtons, "buttonCancel" );
- buttonCancel->setText( tr( "SMESH_BUT_CLOSE" ) );
- buttonCancel->setAutoDefault( TRUE );
- GroupButtonsLayout->addWidget( buttonCancel, 0, 3 );
- buttonApply = new QPushButton( GroupButtons, "buttonApply" );
- buttonApply->setText( tr( "SMESH_BUT_APPLY" ) );
- buttonApply->setAutoDefault( TRUE );
- GroupButtonsLayout->addWidget( buttonApply, 0, 1 );
- QSpacerItem* spacer_9 = new QSpacerItem( 20, 20, QSizePolicy::Expanding, QSizePolicy::Minimum );
- GroupButtonsLayout->addItem( spacer_9, 0, 2 );
- buttonOk = new QPushButton( GroupButtons, "buttonOk" );
- buttonOk->setText( tr( "SMESH_BUT_OK" ) );
- buttonOk->setAutoDefault( TRUE );
- buttonOk->setDefault( TRUE );
- GroupButtonsLayout->addWidget( buttonOk, 0, 0 );
- SMESHGUI_AddSubMeshDlgLayout->addWidget( GroupButtons, 2, 0 );
-
- /***************************************************************/
- GroupC1 = new QGroupBox( this, "GroupC1" );
- GroupC1->setTitle( tr( "SMESH_ARGUMENTS" ) );
- GroupC1->setMinimumSize( QSize( 0, 0 ) );
- GroupC1->setFrameShape( QGroupBox::Box );
- GroupC1->setFrameShadow( QGroupBox::Sunken );
+ GroupC1 = new QGroupBox( tr( "SMESH_ARGUMENTS" ), this, "GroupC1" );
GroupC1->setColumnLayout(0, Qt::Vertical );
GroupC1->layout()->setSpacing( 0 );
GroupC1->layout()->setMargin( 0 );
- GroupC1Layout = new QGridLayout( GroupC1->layout() );
+ QGridLayout* GroupC1Layout = new QGridLayout( GroupC1->layout() );
GroupC1Layout->setAlignment( Qt::AlignTop );
GroupC1Layout->setSpacing( 6 );
GroupC1Layout->setMargin( 11 );
- TextLabelC1A1 = new QLabel( GroupC1, "TextLabelC1A1" );
- TextLabelC1A1->setText( tr( "SMESH_OBJECT_MESH" ) );
- TextLabelC1A1->setMinimumSize( QSize( 50, 0 ) );
- TextLabelC1A1->setFrameShape( QLabel::NoFrame );
- TextLabelC1A1->setFrameShadow( QLabel::Plain );
- GroupC1Layout->addWidget( TextLabelC1A1, 0, 0 );
+ TextLabel_NameMesh = new QLabel( tr( "SMESH_NAME" ), GroupC1, "TextLabel_NameMesh" );
+ GroupC1Layout->addWidget( TextLabel_NameMesh, 0, 0 );
+ LineEdit_NameMesh = new QLineEdit( GroupC1, "LineEdit_NameMesh" );
+ GroupC1Layout->addWidget( LineEdit_NameMesh, 0, 2 );
+
+ TextLabelC1A1 = new QLabel( tr( "SMESH_OBJECT_MESH" ), GroupC1, "TextLabelC1A1" );
+ GroupC1Layout->addWidget( TextLabelC1A1, 1, 0 );
SelectButtonC1A1 = new QPushButton( GroupC1, "SelectButtonC1A1" );
- SelectButtonC1A1->setText( tr( "" ) );
SelectButtonC1A1->setPixmap( image0 );
SelectButtonC1A1->setToggleButton( FALSE );
- GroupC1Layout->addWidget( SelectButtonC1A1, 0, 1 );
+ GroupC1Layout->addWidget( SelectButtonC1A1, 1, 1 );
LineEditC1A1 = new QLineEdit( GroupC1, "LineEditC1A1" );
- GroupC1Layout->addWidget( LineEditC1A1, 0, 2 );
-
- TextLabelC1A2 = new QLabel( GroupC1, "TextLabelC1A2" );
- TextLabelC1A2->setText( tr( "SMESH_OBJECT_GEOM" ) );
- TextLabelC1A2->setMinimumSize( QSize( 50, 0 ) );
- TextLabelC1A2->setFrameShape( QLabel::NoFrame );
- TextLabelC1A2->setFrameShadow( QLabel::Plain );
- GroupC1Layout->addWidget( TextLabelC1A2, 1, 0 );
+ GroupC1Layout->addWidget( LineEditC1A1, 1, 2 );
+
+ TextLabelC1A2 = new QLabel( tr( "SMESH_OBJECT_GEOM" ), GroupC1, "TextLabelC1A2" );
+ GroupC1Layout->addWidget( TextLabelC1A2, 2, 0 );
SelectButtonC1A2 = new QPushButton( GroupC1, "SelectButtonC1A2" );
- SelectButtonC1A2->setText( tr( "" ) );
SelectButtonC1A2->setPixmap( image0 );
SelectButtonC1A2->setToggleButton( FALSE );
- GroupC1Layout->addWidget( SelectButtonC1A2, 1, 1 );
+ GroupC1Layout->addWidget( SelectButtonC1A2, 2, 1 );
LineEditC1A2 = new QLineEdit( GroupC1, "LineEditC1A2" );
- GroupC1Layout->addWidget( LineEditC1A2, 1, 2 );
-
- TextLabel_NameMesh = new QLabel( GroupC1, "TextLabel_NameMesh" );
- TextLabel_NameMesh->setText( tr( "SMESH_NAME" ) );
- GroupC1Layout->addWidget( TextLabel_NameMesh, 2, 0 );
- LineEdit_NameMesh = new QLineEdit( GroupC1, "LineEdit_NameMesh" );
- GroupC1Layout->addWidget( LineEdit_NameMesh, 2, 2 );
+ GroupC1Layout->addWidget( LineEditC1A2, 2, 2 );
- TextLabelC1A1Hyp = new QLabel( GroupC1, "TextLabelC1A1Hyp" );
- TextLabelC1A1Hyp->setText( tr( "SMESH_OBJECT_HYPOTHESIS" ) );
- TextLabelC1A1Hyp->setMinimumSize( QSize( 50, 0 ) );
- TextLabelC1A1Hyp->setFrameShape( QLabel::NoFrame );
- TextLabelC1A1Hyp->setFrameShadow( QLabel::Plain );
+ TextLabelC1A1Hyp = new QLabel( tr( "SMESH_OBJECT_HYPOTHESIS" ), GroupC1, "TextLabelC1A1Hyp" );
GroupC1Layout->addWidget( TextLabelC1A1Hyp, 3, 0 );
SelectButtonC1A1Hyp = new QPushButton( GroupC1, "SelectButtonC1A1Hyp" );
- SelectButtonC1A1Hyp->setText( tr( "" ) );
SelectButtonC1A1Hyp->setPixmap( image0 );
GroupC1Layout->addWidget( SelectButtonC1A1Hyp, 3, 1 );
LineEditC1A1Hyp = new QLineEdit( GroupC1, "LineEditC1A1Hyp" );
- LineEditC1A1Hyp->setSizePolicy( QSizePolicy( (QSizePolicy::SizeType)3, (QSizePolicy::SizeType)0, LineEditC1A1Hyp->sizePolicy().hasHeightForWidth() ) );
GroupC1Layout->addWidget( LineEditC1A1Hyp, 3, 2 );
- TextLabelC1A1Algo = new QLabel( GroupC1, "TextLabelC1A1Algo" );
- TextLabelC1A1Algo->setText( tr( "SMESH_OBJECT_ALGORITHM" ) );
- TextLabelC1A1Algo->setMinimumSize( QSize( 50, 0 ) );
- TextLabelC1A1Algo->setFrameShape( QLabel::NoFrame );
- TextLabelC1A1Algo->setFrameShadow( QLabel::Plain );
+ TextLabelC1A1Algo = new QLabel( tr( "SMESH_OBJECT_ALGORITHM" ), GroupC1, "TextLabelC1A1Algo" );
GroupC1Layout->addWidget( TextLabelC1A1Algo, 4, 0 );
SelectButtonC1A1Algo = new QPushButton( GroupC1, "SelectButtonC1A1Algo" );
- SelectButtonC1A1Algo->setText( tr( "" ) );
SelectButtonC1A1Algo->setPixmap( image0 );
GroupC1Layout->addWidget( SelectButtonC1A1Algo, 4, 1 );
LineEditC1A1Algo = new QLineEdit( GroupC1, "LineEditC1A1Algo" );
- LineEditC1A1Algo->setSizePolicy( QSizePolicy( (QSizePolicy::SizeType)3, (QSizePolicy::SizeType)0, LineEditC1A1Algo->sizePolicy().hasHeightForWidth() ) );
GroupC1Layout->addWidget( LineEditC1A1Algo, 4, 2 );
SMESHGUI_AddSubMeshDlgLayout->addWidget( GroupC1, 1, 0 );
+
/***************************************************************/
+ GroupButtons = new QGroupBox( this, "GroupButtons" );
+ GroupButtons->setColumnLayout(0, Qt::Vertical );
+ GroupButtons->layout()->setSpacing( 0 );
+ GroupButtons->layout()->setMargin( 0 );
+ QGridLayout* GroupButtonsLayout = new QGridLayout( GroupButtons->layout() );
+ GroupButtonsLayout->setAlignment( Qt::AlignTop );
+ GroupButtonsLayout->setSpacing( 6 );
+ GroupButtonsLayout->setMargin( 11 );
- Init(Sel) ;
+ buttonOk = new QPushButton( tr( "SMESH_BUT_OK" ), GroupButtons, "buttonOk" );
+ buttonOk->setAutoDefault( TRUE );
+ buttonOk->setDefault( TRUE );
+ GroupButtonsLayout->addWidget( buttonOk, 0, 0 );
+
+ buttonApply = new QPushButton( tr( "SMESH_BUT_APPLY" ), GroupButtons, "buttonApply" );
+ buttonApply->setAutoDefault( TRUE );
+ GroupButtonsLayout->addWidget( buttonApply, 0, 1 );
+
+ GroupButtonsLayout->addItem( new QSpacerItem( 20, 20, QSizePolicy::Expanding, QSizePolicy::Minimum ), 0, 2 );
+
+ buttonCancel = new QPushButton( tr( "SMESH_BUT_CLOSE" ), GroupButtons, "buttonCancel" );
+ buttonCancel->setAutoDefault( TRUE );
+ GroupButtonsLayout->addWidget( buttonCancel, 0, 3 );
+
+ SMESHGUI_AddSubMeshDlgLayout->addWidget( GroupButtons, 2, 0 );
+
+ /***************************************************************/
+ Init( Sel ) ;
}
//=================================================================================
void SMESHGUI_AddSubMeshDlg::Init( SALOME_Selection* Sel )
{
- GroupC1->show();
- myConstructorId = 0 ;
- Constructor1->setChecked( TRUE );
- myEditCurrentArgument = LineEditC1A1 ;
mySelection = Sel;
mySMESHGUI = SMESHGUI::GetSMESHGUI() ;
mySMESHGUI->SetActiveDialogBox( (QDialog*)this ) ;
- myGeomFilter = new SALOME_TypeFilter( "GEOM" );
- myMeshFilter = new SMESH_TypeFilter( MESH );
-
- myAlgorithmFilter = new SMESH_TypeFilter( ALGORITHM );
+ myGeomFilter = new SALOME_TypeFilter( "GEOM" );
+ myMeshFilter = new SMESH_TypeFilter( MESH );
+ myAlgorithmFilter = new SMESH_TypeFilter( ALGORITHM );
myHypothesisFilter = new SMESH_TypeFilter( HYPOTHESIS );
- myNameSubMesh = "SubMesh";
-
- myGeomShape = GEOM::GEOM_Shape::_nil();
- myMesh = SMESH::SMESH_Mesh::_nil();
-
/* signals and slots connections */
- connect( buttonOk, SIGNAL( clicked() ), this, SLOT( ClickOnOk() ) );
- connect( buttonApply, SIGNAL( clicked() ), this, SLOT(ClickOnApply() ) );
+ connect( buttonOk, SIGNAL( clicked() ), this, SLOT( ClickOnOk() ) );
+ connect( buttonApply, SIGNAL( clicked() ), this, SLOT( ClickOnApply() ) );
connect( buttonCancel, SIGNAL( clicked() ), this, SLOT( ClickOnCancel() ) ) ;
- connect( GroupConstructors, SIGNAL(clicked(int) ), SLOT( ConstructorsClicked(int) ) );
-
- connect( SelectButtonC1A1, SIGNAL (clicked() ), this, SLOT( SetEditCurrentArgument() ) ) ;
- connect( SelectButtonC1A2, SIGNAL (clicked() ), this, SLOT( SetEditCurrentArgument() ) ) ;
- connect( LineEdit_NameMesh, SIGNAL (textChanged(const QString&) ), this, SLOT( TextChangedInLineEdit(const QString&) ) ) ;
- connect( SelectButtonC1A1Hyp, SIGNAL (clicked() ), this, SLOT( SetEditCurrentArgument() ) ) ;
+ connect( SelectButtonC1A1, SIGNAL (clicked() ), this, SLOT( SetEditCurrentArgument() ) ) ;
+ connect( SelectButtonC1A2, SIGNAL (clicked() ), this, SLOT( SetEditCurrentArgument() ) ) ;
+ connect( SelectButtonC1A1Hyp, SIGNAL (clicked() ), this, SLOT( SetEditCurrentArgument() ) ) ;
connect( SelectButtonC1A1Algo, SIGNAL (clicked() ), this, SLOT( SetEditCurrentArgument() ) ) ;
- connect( mySelection, SIGNAL( currentSelectionChanged() ), this, SLOT( SelectionIntoArgument() ) );
- connect( mySMESHGUI, SIGNAL ( SignalDeactivateActiveDialog() ), this, SLOT( DeactivateActiveDialog() ) ) ;
- connect( mySMESHGUI, SIGNAL ( SignalCloseAllDialogs() ), this, SLOT( ClickOnCancel() ) ) ;
+ connect( mySelection, SIGNAL( currentSelectionChanged() ), this, SLOT( SelectionIntoArgument() ) );
+ connect( mySMESHGUI, SIGNAL( SignalDeactivateActiveDialog() ), this, SLOT( DeactivateActiveDialog() ) ) ;
+ connect( mySMESHGUI, SIGNAL( SignalCloseAllDialogs() ), this, SLOT( ClickOnCancel() ) ) ;
int x, y ;
mySMESHGUI->DefineDlgPosition( this, x, y ) ;
this->move( x, y ) ;
this->show() ;
- SelectionIntoArgument();
-
- return ;
-}
-
+ LineEdit_NameMesh->setText( tr( "SMESH_SUBMESH" ) );
+ LineEdit_NameMesh->setFocus() ;
+ myEditCurrentArgument = LineEditC1A1 ;
+ mySelection->ClearFilters() ;
+ mySelection->AddFilter( myMeshFilter ) ;
-//=================================================================================
-// function : ConstructorsClicked()
-// purpose : Radio button management
-//=================================================================================
-void SMESHGUI_AddSubMeshDlg::ConstructorsClicked(int constructorId)
-{
- return ;
+ SelectionIntoArgument();
}
//=================================================================================
//=================================================================================
void SMESHGUI_AddSubMeshDlg::ClickOnOk()
{
- this->ClickOnApply() ;
- this->ClickOnCancel() ;
+ if ( this->ClickOnApply() )
+ this->ClickOnCancel() ;
}
//=================================================================================
// function : ClickOnApply()
// purpose :
//=================================================================================
-void SMESHGUI_AddSubMeshDlg::ClickOnApply()
+bool SMESHGUI_AddSubMeshDlg::ClickOnApply()
{
- switch(myConstructorId)
- {
- case 0 :
- {
- if ( !myNameSubMesh.isEmpty() && !myNameSubMesh.isNull() &&
- !myGeomShape->_is_nil() && !myMesh->_is_nil()) {
- mySubMesh = mySMESHGUI->AddSubMesh( myMesh, myGeomShape, myNameSubMesh ) ;
- }
-
- if( myOkHypothesis && !mySubMesh->_is_nil() ) {
- SALOME_ListIteratorOfListIO It( HypoList );
- for(;It.More();It.Next()) {
- Handle(SALOME_InteractiveObject) IObject = It.Value();
- Standard_Boolean testResult;
- myHypothesis = mySMESHGUI->ConvertIOinSMESHHypothesis(IObject, testResult) ;
- if( testResult )
- mySMESHGUI->AddHypothesisOnSubMesh(mySubMesh, myHypothesis) ;
+ QString myNameSubMesh = LineEdit_NameMesh->text().stripWhiteSpace();
+ if ( myNameSubMesh.isEmpty() ) {
+ QAD_MessageBox::warn1( this, tr( "SMESH_WRN_WARNING" ), tr( "SMESH_WRN_EMPTY_NAME" ), tr( "SMESH_BUT_OK" ) );
+ return false;
+ }
+
+ if ( myMesh->_is_nil() || myGeomShape->_is_nil() || ( !HypoList.count() && !AlgoList.count() ) )
+ return false;
+
+ SALOMEDS::SObject_var aMeshSO = mySMESHGUI->GetStudyAPI().FindObject( myMesh );
+ GEOM::GEOM_Shape_var myMainShape = mySMESHGUI->GetStudyAPI().GetShapeOnMeshOrSubMesh( aMeshSO );
+ if ( myMainShape->_is_nil() )
+ return false;
+
+ QAD_WaitCursor wc;
+
+ QAD_Operation* op = new QAD_Operation( mySMESHGUI->GetActiveStudy() );
+
+ // start transaction
+ op->start();
+
+ // create submesh
+ SMESH::SMESH_subMesh_var aSubMesh = mySMESHGUI->AddSubMesh( myMesh, myGeomShape, myNameSubMesh ) ;
+
+ if ( !aSubMesh->_is_nil() ) {
+ // assign hypotheses
+ for( int i = 0; i < HypoList.count(); i++ ) {
+ SALOMEDS::SObject_var aHypSO = mySMESHGUI->GetStudy()->FindObjectID( HypoList[i] );
+ if ( !aHypSO->_is_nil() ) {
+ CORBA::Object_var anObject = aHypSO->GetObject();
+ if ( !CORBA::is_nil( anObject ) ) {
+ SMESH::SMESH_Hypothesis_var aHyp = SMESH::SMESH_Hypothesis::_narrow( anObject );
+ if ( !aHyp->_is_nil() )
+ if ( !mySMESHGUI->AddHypothesisOnSubMesh( aSubMesh, aHyp ) ) {
+ // abort transaction
+ op->abort();
+ return false;
}
}
-
- if( myOkAlgorithm && !mySubMesh->_is_nil() ) {
- SALOME_ListIteratorOfListIO It( AlgoList );
- for(;It.More();It.Next()) {
- Handle(SALOME_InteractiveObject) IObject = It.Value();
- Standard_Boolean testResult;
- myAlgorithm = mySMESHGUI->ConvertIOinSMESHHypothesis(IObject, testResult) ;
- if( testResult )
- mySMESHGUI->AddAlgorithmOnSubMesh(mySubMesh, myAlgorithm) ;
+ }
+ }
+ // assign algorithms
+ for( int i = 0; i < AlgoList.count(); i++ ) {
+ SALOMEDS::SObject_var aHypSO = mySMESHGUI->GetStudy()->FindObjectID( AlgoList[i] );
+ if ( !aHypSO->_is_nil() ) {
+ CORBA::Object_var anObject = aHypSO->GetObject();
+ if ( !CORBA::is_nil( anObject ) ) {
+ SMESH::SMESH_Hypothesis_var aHyp = SMESH::SMESH_Hypothesis::_narrow( anObject );
+ if ( !aHyp->_is_nil() )
+ if ( !mySMESHGUI->AddAlgorithmOnSubMesh( aSubMesh, aHyp ) ) {
+ // abort transaction
+ op->abort();
+ return false;
}
}
-
- break ;
}
}
+ }
+ // commit transaction
+ op->finish();
+ return true;
}
//=================================================================================
void SMESHGUI_AddSubMeshDlg::ClickOnCancel()
{
- disconnect( mySelection, 0, this, 0 );
- mySMESHGUI->ResetState() ;
- mySelection->ClearFilters() ;
- reject() ;
- return ;
+ close();
}
+static bool IsFatherOf( SALOMEDS::SObject_ptr SO, SALOMEDS::SObject_ptr fatherSO ) {
+ if ( !SO->_is_nil() && !fatherSO->_is_nil() ) {
+ SALOMEDS::SObject_var aSO = SO->GetFather();
+ while( strlen( aSO->GetID() ) >= strlen( fatherSO->GetID() ) ) {
+ if ( QString( aSO->GetID() ) == QString( fatherSO->GetID() ) )
+ return true;
+ aSO = aSO->GetFather();
+ }
+ }
+ return false;
+}
//=================================================================================
// function : SelectionIntoArgument()
//=================================================================================
void SMESHGUI_AddSubMeshDlg::SelectionIntoArgument()
{
- myEditCurrentArgument->setText("") ;
+ SMESHGUI_StudyAPI myStudyAPI = mySMESHGUI->GetStudyAPI();
QString aString = "";
int nbSel = mySMESHGUI->GetNameOfSelectedIObjects(mySelection, aString) ;
- switch (myConstructorId)
- {
- case 0:
- {
- if ( myEditCurrentArgument == LineEditC1A1 ) {
- if ( nbSel != 1 ) {
- myOkHypothesis = false;
- myOkAlgorithm = false;
- return ;
- } else {
- Standard_Boolean testResult ;
- Handle(SALOME_InteractiveObject) IO = mySelection->firstIObject() ;
- myMesh = mySMESHGUI->ConvertIOinMesh(IO, testResult) ;
- if( !testResult ) {
- myMesh = SMESH::SMESH_Mesh::_nil();
- return ;
- }
- }
- } else if ( myEditCurrentArgument == LineEditC1A2 ) {
- if ( nbSel != 1 ) {
- myOkHypothesis = false;
- myOkAlgorithm = false;
- return ;
- } else {
- Standard_Boolean testResult ;
- Handle(SALOME_InteractiveObject) IO = mySelection->firstIObject() ;
- myGeomShape = mySMESHGUI->ConvertIOinGEOMShape(IO, testResult) ;
- if( !testResult ) {
- myGeomShape = GEOM::GEOM_Shape::_nil();
- return ;
- }
- }
- } else if ( myEditCurrentArgument == LineEditC1A1Hyp ) {
- if ( nbSel >= 1 ) {
- HypoList.Clear();
- SALOME_ListIteratorOfListIO Itinit( mySelection->StoredIObjects() );
- for (; Itinit.More(); Itinit.Next()) {
- HypoList.Append(Itinit.Value());
- }
- myOkHypothesis = true ;
- if (nbSel > 1)
- aString = tr("%1 Hypothesis").arg(nbSel) ;
- LineEditC1A1Hyp->setText(aString) ;
- }
- else {
- myOkHypothesis = false ;
- return ;
- }
- } else if ( myEditCurrentArgument == LineEditC1A1Algo ) {
- if ( nbSel >= 1 ) {
- AlgoList.Clear();
- SALOME_ListIteratorOfListIO Itinit( mySelection->StoredIObjects() );
- for (; Itinit.More(); Itinit.Next()) {
- AlgoList.Append(Itinit.Value());
- }
- myOkAlgorithm = true ;
- if (nbSel > 1)
- aString = tr("%1 Algorithms").arg(nbSel) ;
- LineEditC1A1Algo->setText(aString) ;
- }
- else {
- myOkAlgorithm = false ;
- return ;
- }
- }
- break;
+ if ( myEditCurrentArgument == LineEditC1A1 ) {
+ // mesh
+ if ( nbSel != 1 ) {
+ myMesh = SMESH::SMESH_Mesh::_nil();
+ aString = "";
+ }
+ else {
+ Standard_Boolean testResult ;
+ Handle(SALOME_InteractiveObject) IO = mySelection->firstIObject() ;
+ myMesh = mySMESHGUI->ConvertIOinMesh(IO, testResult) ;
+ if( !testResult ) {
+ myMesh = SMESH::SMESH_Mesh::_nil();
+ aString = "";
+ }
+ }
+ myGeomShape = GEOM::GEOM_Shape::_nil();
+ LineEditC1A2->setText( "" );
+ }
+ else if ( myEditCurrentArgument == LineEditC1A2 ) {
+ // geom shape
+ if ( nbSel != 1 ) {
+ myGeomShape = GEOM::GEOM_Shape::_nil();
+ aString = "";
+ }
+ else {
+ Standard_Boolean testResult ;
+ Handle(SALOME_InteractiveObject) IO = mySelection->firstIObject() ;
+ myGeomShape = mySMESHGUI->ConvertIOinGEOMShape(IO, testResult) ;
+ if( !testResult ) {
+ myGeomShape = GEOM::GEOM_Shape::_nil();
+ aString = "";
}
+ if ( !myMesh->_is_nil() ) {
+ SALOMEDS::SObject_var aMeshSO = myStudyAPI.FindObject( myMesh );
+ GEOM::GEOM_Shape_var aMainGeomShape = myStudyAPI.GetShapeOnMeshOrSubMesh( aMeshSO );
+ SALOMEDS::SObject_var aMainGeomShapeSO = myStudyAPI.FindObject( aMainGeomShape );
+ if ( aMainGeomShapeSO->_is_nil() || !IsFatherOf( mySMESHGUI->GetStudy()->FindObjectID( IO->getEntry() ), aMainGeomShapeSO ) ) {
+ myGeomShape = GEOM::GEOM_Shape::_nil();
+ aString = "";
+ }
+ }
+ }
+ }
+ else if ( myEditCurrentArgument == LineEditC1A1Hyp ) {
+ // hypotheses
+ HypoList.clear();
+ if ( nbSel >= 1 ) {
+ SALOME_ListIteratorOfListIO Itinit( mySelection->StoredIObjects() );
+ for ( ; Itinit.More(); Itinit.Next() ) {
+ HypoList.append( Itinit.Value()->getEntry() );
+ }
+ if ( nbSel > 1 )
+ aString = tr( "%1 Hypothesis" ).arg( nbSel ) ;
+ }
+ else {
+ aString = "";
}
+ }
+ else if ( myEditCurrentArgument == LineEditC1A1Algo ) {
+ // algorithms
+ AlgoList.clear();
+ if ( nbSel >= 1 ) {
+ SALOME_ListIteratorOfListIO Itinit( mySelection->StoredIObjects() );
+ for ( ; Itinit.More(); Itinit.Next() ) {
+ AlgoList.append( Itinit.Value()->getEntry() );
+ }
+ if ( nbSel > 1 )
+ aString = tr( "%1 Algorithms" ).arg( nbSel ) ;
+ }
+ else {
+ aString = "";
+ }
+ }
myEditCurrentArgument->setText(aString) ;
+
+ UpdateControlState();
}
void SMESHGUI_AddSubMeshDlg::SetEditCurrentArgument()
{
QPushButton* send = (QPushButton*)sender();
- switch (myConstructorId)
- {
- case 0: /* default constructor */
- {
- if(send == SelectButtonC1A1) {
- LineEditC1A1->setFocus() ;
- myEditCurrentArgument = LineEditC1A1;
- mySelection->ClearFilters() ;
- mySelection->AddFilter(myMeshFilter) ;
- } else if (send == SelectButtonC1A2) {
- LineEditC1A2->setFocus() ;
- myEditCurrentArgument = LineEditC1A2;
- mySelection->ClearFilters() ;
- mySelection->AddFilter(myGeomFilter) ;
- } else if( send == SelectButtonC1A1Hyp ) {
- LineEditC1A1Hyp->setFocus() ;
- myEditCurrentArgument = LineEditC1A1Hyp ;
- mySelection->ClearFilters() ;
- mySelection->AddFilter(myHypothesisFilter) ;
- } else if( send == SelectButtonC1A1Algo ) {
- LineEditC1A1Algo->setFocus() ;
- myEditCurrentArgument = LineEditC1A1Algo ;
- mySelection->ClearFilters() ;
- mySelection->AddFilter(myAlgorithmFilter) ;
- }
- SelectionIntoArgument() ;
- break;
- }
- }
- return ;
+ if(send == SelectButtonC1A1) {
+ LineEditC1A1->setFocus() ;
+ myEditCurrentArgument = LineEditC1A1;
+ mySelection->ClearFilters() ;
+ mySelection->AddFilter(myMeshFilter) ;
+ } else if (send == SelectButtonC1A2) {
+ LineEditC1A2->setFocus() ;
+ myEditCurrentArgument = LineEditC1A2;
+ mySelection->ClearFilters() ;
+ mySelection->AddFilter(myGeomFilter) ;
+ } else if( send == SelectButtonC1A1Hyp ) {
+ LineEditC1A1Hyp->setFocus() ;
+ myEditCurrentArgument = LineEditC1A1Hyp ;
+ mySelection->ClearFilters() ;
+ mySelection->AddFilter(myHypothesisFilter) ;
+ } else if( send == SelectButtonC1A1Algo ) {
+ LineEditC1A1Algo->setFocus() ;
+ myEditCurrentArgument = LineEditC1A1Algo ;
+ mySelection->ClearFilters() ;
+ mySelection->AddFilter(myAlgorithmFilter) ;
+ }
+ SelectionIntoArgument() ;
}
//=================================================================================
//=================================================================================
void SMESHGUI_AddSubMeshDlg::DeactivateActiveDialog()
{
- if ( GroupConstructors->isEnabled() ) {
+ if ( GroupC1->isEnabled() ) {
disconnect( mySelection, 0, this, 0 );
- GroupConstructors->setEnabled(false) ;
GroupC1->setEnabled(false) ;
GroupButtons->setEnabled(false) ;
}
void SMESHGUI_AddSubMeshDlg::ActivateThisDialog()
{
mySMESHGUI->EmitSignalDeactivateDialog() ;
- GroupConstructors->setEnabled(true) ;
GroupC1->setEnabled(true) ;
GroupButtons->setEnabled(true) ;
connect ( mySelection, SIGNAL( currentSelectionChanged() ), this, SLOT( SelectionIntoArgument() ) );
- return ;
}
//=================================================================================
void SMESHGUI_AddSubMeshDlg::enterEvent(QEvent* e)
{
- if ( GroupConstructors->isEnabled() )
- return ;
- ActivateThisDialog() ;
- return ;
+ if ( !GroupC1->isEnabled() )
+ ActivateThisDialog() ;
}
//=================================================================================
void SMESHGUI_AddSubMeshDlg::closeEvent( QCloseEvent* e )
{
- this->ClickOnCancel() ;
- return ;
+ disconnect( mySelection, 0, this, 0 );
+ mySMESHGUI->ResetState() ;
+ mySelection->ClearFilters() ;
+ QDialog::closeEvent( e );
}
//=================================================================================
-// function : TextChangedInLineEdit()
+// function : UpdateControlState()
// purpose :
//=================================================================================
-void SMESHGUI_AddSubMeshDlg::TextChangedInLineEdit(const QString& newText)
-{
- QLineEdit* send = (QLineEdit*)sender();
- QString newT = strdup(newText) ;
-
- if (send == LineEdit_NameMesh) {
- myNameSubMesh = newText;
+void SMESHGUI_AddSubMeshDlg::UpdateControlState()
+{
+ bool isEnabled = ( !myMesh->_is_nil() && !myGeomShape->_is_nil() && ( HypoList.count() || AlgoList.count() ) );
+ bool isImportedMesh = false;
+ if ( !myMesh->_is_nil() ) {
+ SALOMEDS::SObject_var aMeshSO = mySMESHGUI->GetStudyAPI().FindObject( myMesh );
+ GEOM::GEOM_Shape_var myGeomShape = mySMESHGUI->GetStudyAPI().GetShapeOnMeshOrSubMesh( aMeshSO );
+ isImportedMesh = myGeomShape->_is_nil();
}
- return ;
+
+ buttonOk ->setEnabled( isEnabled && !isImportedMesh );
+ buttonApply->setEnabled( isEnabled && !isImportedMesh );
}
+
+
+
+
+
#include "SMESH_TypeFilter.hxx"
// QT Includes
-#include <qvariant.h>
#include <qdialog.h>
+#include <qstringlist.h>
// IDL Headers
#include <SALOMEconfig.h>
#include CORBA_SERVER_HEADER(GEOM_Shape)
#include CORBA_SERVER_HEADER(SMESH_Mesh)
-class QVBoxLayout;
-class QHBoxLayout;
-class QGridLayout;
-class QButtonGroup;
class QGroupBox;
class QLabel;
class QLineEdit;
class QPushButton;
-class QRadioButton;
class SMESHGUI;
-
//=================================================================================
// class : SMESHGUI_AddSubMeshDlg
// purpose :
SMESHGUI_AddSubMeshDlg( QWidget* parent = 0, const char* name = 0, SALOME_Selection* Sel = 0, bool modal = FALSE, WFlags fl = 0 );
~SMESHGUI_AddSubMeshDlg();
-private:
-
- void Init( SALOME_Selection* Sel ) ;
+protected:
void closeEvent( QCloseEvent* e ) ;
void enterEvent ( QEvent * ) ;
+private:
+ void Init( SALOME_Selection* Sel ) ;
+
+ void UpdateControlState();
+
+private:
SMESHGUI* mySMESHGUI ;
SALOME_Selection* mySelection ;
- GEOM::GEOM_Shape_var myGeomShape ;
- int myConstructorId ;
- QLineEdit* myEditCurrentArgument;
-
SMESH::SMESH_Mesh_var myMesh;
- SMESH::SMESH_subMesh_var mySubMesh;
-
- QString myNameSubMesh ;
+ GEOM::GEOM_Shape_var myGeomShape ;
+ QLineEdit* myEditCurrentArgument;
Handle(SALOME_TypeFilter) myGeomFilter;
Handle(SMESH_TypeFilter) myMeshFilter;
Handle(SMESH_TypeFilter) myHypothesisFilter;
Handle(SMESH_TypeFilter) myAlgorithmFilter;
- SALOME_ListIO HypoList;
- SALOME_ListIO AlgoList;
+ QStringList HypoList;
+ QStringList AlgoList;
- bool myOkHypothesis;
- bool myOkAlgorithm;
-
- SMESH::SMESH_Hypothesis_var myHypothesis;
- SMESH::SMESH_Hypothesis_var myAlgorithm;
-
- QButtonGroup* GroupConstructors;
- QRadioButton* Constructor1;
QGroupBox* GroupButtons;
QPushButton* buttonOk;
- QPushButton* buttonCancel;
QPushButton* buttonApply;
+ QPushButton* buttonCancel;
+
QGroupBox* GroupC1;
QLabel* TextLabel_NameMesh ;
QLineEdit* LineEdit_NameMesh ;
QLineEdit* LineEditC1A1Algo;
private slots:
-
- void ConstructorsClicked(int constructorId);
void ClickOnOk();
+ bool ClickOnApply();
void ClickOnCancel();
- void ClickOnApply();
void SetEditCurrentArgument() ;
void SelectionIntoArgument() ;
void DeactivateActiveDialog() ;
void ActivateThisDialog() ;
- void TextChangedInLineEdit(const QString& newText) ;
-
-protected:
- QGridLayout* SMESHGUI_AddSubMeshDlgLayout;
- QGridLayout* GroupConstructorsLayout;
- QGridLayout* GroupButtonsLayout;
- QGridLayout* GroupC1Layout;
};
#endif // DIALOGBOX_ADD_SUBMESH_H
//=================================================================================
void SMESHGUI_AddVolumeDlg::ClickOnCancel()
{
- QAD_Application::getDesktop()->SetSelectionMode( 4 );
+ QAD_Application::getDesktop()->SetSelectionMode( ActorSelection );
disconnect( mySelection, 0, this, 0 );
mySMESHGUI->ResetState() ;
mySMESHGUI->EraseSimulationActors();
if(nbNodes < 1)
return ;
- if ( mySelection->SelectionMode() != 1 ) {
+ if ( mySelection->SelectionMode() != NodeSelection ) {
QAD_MessageBox::warn1 ( QAD_Application::getDesktop(), tr ("SMESH_WRN_WARNING"),
- tr ("SMESH_WRN_SELECTIONMODE_NODES"), tr ("SMESH_BUT_YES") );
+ tr ("SMESH_WRN_SELECTIONMODE_NODES"), tr ("SMESH_BUT_OK") );
return;
}
--- /dev/null
+// SMESH SMESHGUI : GUI for SMESH component
+//
+// Copyright (C) 2003 CEA
+//
+// This library 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.
+//
+// This library 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 this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+//
+// See http://www.salome-platform.org or email : webmaster.salome@opencascade.org
+//
+//
+//
+// File : SMESHGUI_CreateHypothesesDlg.cxx
+// Author : Julia DOROVSKIKH
+// Module : SMESH
+// $Header$
+
+using namespace std;
+#include "SMESHGUI_CreateHypothesesDlg.h"
+#include "SMESHGUI.h"
+#include "SALOME_ListIteratorOfListIO.hxx"
+
+#include "QAD_Application.h"
+#include "QAD_Desktop.h"
+#include "utilities.h"
+
+// QT Includes
+#include <qbuttongroup.h>
+#include <qgroupbox.h>
+#include <qpushbutton.h>
+#include <qlayout.h>
+#include <qlistview.h>
+#include <qheader.h>
+
+//=================================================================================
+// class : SMESHGUI_CreateHypothesesDlg()
+// purpose : Constructs a SMESHGUI_CreateHypothesesDlg which is a child of 'parent', with the
+// name 'name' and widget flags set to 'f'.
+// The dialog will by default be modeless, unless you set 'modal' to
+// TRUE to construct a modal dialog.
+//=================================================================================
+SMESHGUI_CreateHypothesesDlg::SMESHGUI_CreateHypothesesDlg (QWidget* parent,
+ const char* name,
+ bool modal,
+ bool isAlgo)
+ : QDialog( parent, name, modal, WStyle_Customize | WStyle_NormalBorder | WStyle_Title | WStyle_SysMenu | WDestructiveClose ),
+ myIsAlgo( isAlgo )
+{
+ MESSAGE("SMESHGUI_CreateHypothesesDlg");
+
+ if ( !name )
+ setName( "SMESHGUI_CreateHypothesesDlg" );
+ setCaption( isAlgo ? tr( "SMESH_CREATE_ALGORITHMS" ) : tr( "SMESH_CREATE_HYPOTHESES" ) );
+ setSizeGripEnabled( TRUE );
+
+ QGridLayout* SMESHGUI_CreateHypothesesDlgLayout = new QGridLayout( this );
+ SMESHGUI_CreateHypothesesDlgLayout->setSpacing( 6 );
+ SMESHGUI_CreateHypothesesDlgLayout->setMargin( 11 );
+
+ /***************************************************************/
+ GroupAlgorithms = new QGroupBox( this, "GroupAlgorithms" );
+ GroupAlgorithms->setTitle( isAlgo ? tr("SMESH_AVAILABLE_ALGORITHMS") : tr("SMESH_AVAILABLE_HYPOTHESES") );
+ GroupAlgorithms->setColumnLayout(0, Qt::Vertical );
+ GroupAlgorithms->layout()->setSpacing( 0 );
+ GroupAlgorithms->layout()->setMargin( 0 );
+
+ QGridLayout* hypLayout = new QGridLayout( GroupAlgorithms->layout() );
+ hypLayout->setGeometry( QRect( 12, 18, 139, 250 ) );
+ hypLayout->setAlignment( Qt::AlignTop );
+ hypLayout->setSpacing( 6 );
+ hypLayout->setMargin( 11 );
+
+ ListAlgoDefinition = new QListView( GroupAlgorithms, "ListAlgoDefinition" );
+ ListAlgoDefinition->setMinimumSize( 400, 200 );
+ ListAlgoDefinition->addColumn("");
+ ListAlgoDefinition->header()->hide();
+ ListAlgoDefinition->setSelectionMode(QListView::Single);
+ ListAlgoDefinition->setResizeMode(QListView::AllColumns);
+ ListAlgoDefinition->setRootIsDecorated( true );
+
+ hypLayout->addWidget( ListAlgoDefinition, 0, 0 );
+ SMESHGUI_CreateHypothesesDlgLayout->addWidget( GroupAlgorithms, 0, 0 );
+
+ /***************************************************************/
+ GroupButtons = new QGroupBox( this, "GroupButtons" );
+ GroupButtons->setColumnLayout( 0, Qt::Vertical );
+ GroupButtons->layout()->setSpacing( 0 );
+ GroupButtons->layout()->setMargin( 0 );
+ QGridLayout* GroupButtonsLayout = new QGridLayout( GroupButtons->layout() );
+ GroupButtonsLayout->setAlignment( Qt::AlignTop );
+ GroupButtonsLayout->setSpacing( 6 );
+ GroupButtonsLayout->setMargin( 11 );
+
+ buttonApply = new QPushButton( GroupButtons, "buttonApply" );
+ buttonApply->setText( tr( "SMESH_BUT_CREATE" ) );
+ buttonApply->setAutoDefault( TRUE );
+ buttonApply->setDefault( FALSE );
+ buttonApply->setEnabled( FALSE ) ;
+ GroupButtonsLayout->addWidget( buttonApply, 0, 1 );
+
+ QSpacerItem* spacer_9 = new QSpacerItem( 20, 20, QSizePolicy::Expanding, QSizePolicy::Minimum );
+ GroupButtonsLayout->addItem( spacer_9, 0, 2 );
+
+ buttonCancel = new QPushButton( GroupButtons, "buttonCancel" );
+ buttonCancel->setText( tr( "SMESH_BUT_CLOSE" ) );
+ buttonCancel->setAutoDefault( TRUE );
+ buttonCancel->setDefault( TRUE );
+ buttonCancel->setEnabled( TRUE ) ;
+ GroupButtonsLayout->addWidget( buttonCancel, 0, 3 );
+
+ SMESHGUI_CreateHypothesesDlgLayout->addWidget( GroupButtons, 1, 0 );
+ /***************************************************************/
+
+ Init();
+}
+
+//=================================================================================
+// function : ~SMESHGUI_CreateHypothesesDlg()
+// purpose : Destroys the object and frees any allocated resources
+//=================================================================================
+SMESHGUI_CreateHypothesesDlg::~SMESHGUI_CreateHypothesesDlg()
+{
+ // no need to delete child widgets, Qt does it all for us
+}
+
+//=================================================================================
+// function : Init()
+// purpose :
+//=================================================================================
+void SMESHGUI_CreateHypothesesDlg::Init()
+{
+ mySMESHGUI = SMESHGUI::GetSMESHGUI() ;
+ mySMESHGUI->SetActiveDialogBox( (QDialog*)this ) ;
+
+ InitAlgoDefinition();
+
+ /* signals and slots connections */
+ connect( buttonCancel, SIGNAL( clicked() ), this, SLOT( ClickOnCancel() ) ) ;
+ connect( buttonApply , SIGNAL( clicked() ), this, SLOT( ClickOnApply() ) ) ;
+
+// connect( mySMESHGUI, SIGNAL ( SignalDeactivateActiveDialog() ), this, SLOT( DeactivateActiveDialog() ) ) ;
+ connect( mySMESHGUI, SIGNAL ( SignalCloseAllDialogs() ), this, SLOT( ClickOnCancel() ) ) ;
+
+ connect( ListAlgoDefinition, SIGNAL( selectionChanged() ), this, SLOT( onSelectionChanged() ) );
+ connect( ListAlgoDefinition, SIGNAL( doubleClicked(QListViewItem*) ), this, SLOT( onDoubleClicked(QListViewItem*) ) );
+
+ int x, y ;
+ mySMESHGUI->DefineDlgPosition( this, x, y ) ;
+ this->move( x, y ) ;
+ this->show() ;
+}
+
+//=================================================================================
+// function : ClickOnCancel()
+// purpose :
+//=================================================================================
+void SMESHGUI_CreateHypothesesDlg::ClickOnCancel()
+{
+ close() ;
+}
+
+//=================================================================================
+// function : ClickOnApply()
+// purpose :
+//=================================================================================
+void SMESHGUI_CreateHypothesesDlg::ClickOnApply()
+{
+ QListViewItem* item = ListAlgoDefinition->selectedItem();
+ if ( !item )
+ return;
+ QString aHypType = item->text( 1 );
+ MESSAGE("Apply " << aHypType);
+ char* sHypType = (char*)aHypType.latin1();
+
+ HypothesisData* aHypData = mySMESHGUI->GetHypothesisData(sHypType);
+ if ( !aHypData )
+ return;
+ QString aClientLibName = aHypData->ClientLibName;
+ MESSAGE("Client lib name = " << aClientLibName);
+
+ if (aClientLibName == "")
+ {
+ // Call hypothesis creation server method (without GUI)
+ QString aHypName = aHypData->Label;
+ mySMESHGUI->CreateHypothesis(sHypType, aHypName, myIsAlgo);
+ }
+ else
+ {
+ // Get hypotheses creator client (GUI)
+ SMESHGUI_GenericHypothesisCreator* aCreator =
+ mySMESHGUI->GetHypothesisCreator(sHypType);
+
+ // Create hypothesis/algorithm
+ aCreator->CreateHypothesis(myIsAlgo, this);
+ }
+
+// buttonApply->setEnabled(FALSE);
+ return;
+}
+
+//=================================================================================
+// function : ActivateThisDialog()
+// purpose :
+//=================================================================================
+void SMESHGUI_CreateHypothesesDlg::ActivateThisDialog()
+{
+ mySMESHGUI->EmitSignalDeactivateDialog() ;
+ GroupButtons->setEnabled(true) ;
+ return ;
+}
+
+//=================================================================================
+// function : enterEvent()
+// purpose :
+//=================================================================================
+void SMESHGUI_CreateHypothesesDlg::enterEvent(QEvent* e)
+{
+ ActivateThisDialog() ;
+ return ;
+}
+
+//=================================================================================
+// function : closeEvent()
+// purpose :
+//=================================================================================
+void SMESHGUI_CreateHypothesesDlg::closeEvent( QCloseEvent* e )
+{
+ mySMESHGUI->ResetState();
+ QDialog::closeEvent( e );
+}
+
+//=================================================================================
+// function : onSelectionChanged()
+// purpose :
+//=================================================================================
+void SMESHGUI_CreateHypothesesDlg::onSelectionChanged()
+{
+ QListViewItem* item = ListAlgoDefinition->selectedItem();
+ buttonApply->setEnabled( item && item->depth() > 0 ) ;
+}
+
+//=================================================================================
+// function : onDoubleClicked()
+// purpose :
+//=================================================================================
+void SMESHGUI_CreateHypothesesDlg::onDoubleClicked(QListViewItem* i)
+{
+ if ( i && i->depth() > 0 )
+ this->ClickOnApply();
+}
+
+//=================================================================================
+// function : InitAlgoDefinition()
+// purpose :
+//=================================================================================
+void SMESHGUI_CreateHypothesesDlg::InitAlgoDefinition()
+{
+ ListAlgoDefinition->clear();
+ QStringList HypList = mySMESHGUI->GetAvailableHypotheses(myIsAlgo);
+ for ( int i = 0; i < HypList.count(); ++i ) {
+ HypothesisData* aHypData = mySMESHGUI->GetHypothesisData( HypList[i] );
+ QListViewItem* parentItem = 0;
+ QListViewItem* childItem = ListAlgoDefinition->firstChild();
+ while ( childItem ) {
+ if ( childItem->text(0) == aHypData->PluginName ) {
+ parentItem = childItem;
+ break;
+ }
+ childItem = childItem->nextSibling();
+ }
+ if ( !parentItem )
+ parentItem = new QListViewItem( ListAlgoDefinition, aHypData->PluginName );
+ parentItem->setOpen( true );
+ QListViewItem* aItem = new QListViewItem( parentItem, aHypData->Label, HypList[i] );
+ QPixmap aPixMap (QAD_Desktop::getResourceManager()->loadPixmap
+ ("SMESH", tr(aHypData->IconId)));
+ if ( !aPixMap.isNull() )
+ aItem->setPixmap( 0, aPixMap );
+ }
+}
--- /dev/null
+// SMESH SMESHGUI : GUI for SMESH component
+//
+// Copyright (C) 2003 CEA
+//
+// This library 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.
+//
+// This library 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 this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+//
+// See http://www.salome-platform.org or email : webmaster.salome@opencascade.org
+//
+//
+//
+// File : SMESHGUI_CreateHypothesesDlg.h
+// Author : Julia DOROVSKIKH
+// Module : SMESH
+// $Header$
+
+#ifndef DIALOGBOX_CREATE_HYPOTHESES_H
+#define DIALOGBOX_CREATE_HYPOTHESES_H
+
+// QT Includes
+#include <qvariant.h>
+#include <qdialog.h>
+#include <qstringlist.h>
+
+// IDL Headers
+#include <SALOMEconfig.h>
+#include CORBA_SERVER_HEADER(GEOM_Gen)
+#include CORBA_SERVER_HEADER(GEOM_Shape)
+#include CORBA_SERVER_HEADER(SMESH_Mesh)
+
+#include <map>
+#include <string>
+
+using namespace std;
+
+class QButtonGroup;
+class QGroupBox;
+class QPushButton;
+class QListView;
+class QListViewItem;
+class SMESHGUI;
+
+//=================================================================================
+// class : SMESHGUI_CreateHypothesesDlg
+// purpose :
+//=================================================================================
+class SMESHGUI_CreateHypothesesDlg : public QDialog
+{
+ Q_OBJECT
+
+public:
+ SMESHGUI_CreateHypothesesDlg (QWidget* parent = 0,
+ const char* name = 0,
+ bool modal = FALSE,
+ bool isAlgo = FALSE);
+ ~SMESHGUI_CreateHypothesesDlg ();
+
+private:
+
+ void Init() ;
+ void closeEvent( QCloseEvent* e ) ;
+ void enterEvent ( QEvent * ) ;
+
+ void InitAlgoDefinition();
+
+ SMESHGUI* mySMESHGUI;
+ bool myIsAlgo;
+
+ QGroupBox* GroupButtons;
+ QPushButton* buttonCancel;
+ QPushButton* buttonApply;
+
+ QGroupBox* GroupAlgorithms;
+ QListView* ListAlgoDefinition;
+
+private slots:
+
+ void ClickOnCancel();
+ void ClickOnApply();
+ void ActivateThisDialog() ;
+
+ void onSelectionChanged();
+ void onDoubleClicked(QListViewItem*);
+};
+
+#endif // DIALOGBOX_CREATE_HYPOTHESES_H
//=================================================================================
void SMESHGUI_DiagonalInversionDlg::ClickOnCancel()
{
- QAD_Application::getDesktop()->SetSelectionMode( 4 );
+ QAD_Application::getDesktop()->SetSelectionMode( ActorSelection );
disconnect( mySelection, 0, this, 0 );
mySMESHGUI->ResetState() ;
reject() ;
myOkElements = false;
QString aString = "";
- if ( mySelection->SelectionMode() != 2 ) {
+ if ( mySelection->SelectionMode() != EdgeSelection ) {
return;
}
#include "QAD_Application.h"
#include "QAD_Desktop.h"
+#include "QAD_WaitCursor.h"
+#include "QAD_Operation.h"
+
#include "utilities.h"
// QT Includes
-#include <qbuttongroup.h>
#include <qgroupbox.h>
#include <qlabel.h>
#include <qlineedit.h>
#include <qpushbutton.h>
-#include <qradiobutton.h>
#include <qlayout.h>
-#include <qvariant.h>
-#include <qtooltip.h>
-#include <qwhatsthis.h>
-#include <qimage.h>
#include <qpixmap.h>
//VRV: porting on Qt 3.0.5
#endif
//VRV: porting on Qt 3.0.5
+class ListBoxIOR : public QListBoxText
+{
+public:
+ enum { RTTI_IOR = 1000 };
+
+public:
+ ListBoxIOR( QListBox* listbox,
+ const char* ior,
+ const QString& text = QString::null)
+ : QListBoxText( listbox, text ), myIOR( ior ) {}
+ virtual ~ListBoxIOR() {};
+ virtual int rtti() const { return RTTI_IOR; }
+ const char* GetIOR() { return myIOR.c_str(); }
+
+private:
+ string myIOR;
+};
+
+#define ALLOW_CHANGE_SHAPE 0
+
+int findItem( QListBox* listBox, const string& ior )
+{
+ for ( int i = 0; i < listBox->count(); i++ ) {
+ if ( listBox->item( i )->rtti() == ListBoxIOR::RTTI_IOR ) {
+ ListBoxIOR* anItem = ( ListBoxIOR* )( listBox->item( i ) );
+ if ( anItem && ior == string( anItem->GetIOR() ) )
+ return i;
+ }
+ }
+ return -1;
+}
+
//=================================================================================
// class : SMESHGUI_EditHypothesesDlg()
// purpose : Constructs a SMESHGUI_EditHypothesesDlg which is a child of 'parent', with the
// TRUE to construct a modal dialog.
//=================================================================================
SMESHGUI_EditHypothesesDlg::SMESHGUI_EditHypothesesDlg( QWidget* parent, const char* name, SALOME_Selection* Sel, bool modal, WFlags fl )
- : QDialog( parent, name, modal, WStyle_Customize | WStyle_NormalBorder | WStyle_Title | WStyle_SysMenu )
+ : QDialog( parent, name, modal, WStyle_Customize | WStyle_NormalBorder | WStyle_Title | WStyle_SysMenu | WDestructiveClose ),
+ myImportedMesh( false )
{
- QPixmap image1(QAD_Desktop::getResourceManager()->loadPixmap( "SMESH",tr("ICON_DLG_EDIT_MESH")));
QPixmap image0(QAD_Desktop::getResourceManager()->loadPixmap( "SMESH",tr("ICON_SELECT")));
if ( !name )
- setName( "SMESHGUI_EditHypothesesDlg" );
- resize( 417, 573 );
+ setName( "SMESHGUI_EditHypothesesDlg" );
setCaption( tr( "SMESH_EDIT_HYPOTHESES" ) );
setSizeGripEnabled( TRUE );
- SMESHGUI_EditHypothesesDlgLayout = new QGridLayout( this );
+ QGridLayout* SMESHGUI_EditHypothesesDlgLayout = new QGridLayout( this );
SMESHGUI_EditHypothesesDlgLayout->setSpacing( 6 );
SMESHGUI_EditHypothesesDlgLayout->setMargin( 11 );
/***************************************************************/
- GroupConstructors = new QButtonGroup( this, "GroupConstructors" );
- GroupConstructors->setTitle( tr( "SMESH_HYPOTHESES" ) );
- GroupConstructors->setExclusive( TRUE );
- GroupConstructors->setColumnLayout(0, Qt::Vertical );
- GroupConstructors->layout()->setSpacing( 0 );
- GroupConstructors->layout()->setMargin( 0 );
- GroupConstructorsLayout = new QGridLayout( GroupConstructors->layout() );
- GroupConstructorsLayout->setAlignment( Qt::AlignTop );
- GroupConstructorsLayout->setSpacing( 6 );
- GroupConstructorsLayout->setMargin( 11 );
- Constructor1 = new QRadioButton( GroupConstructors, "Constructor1" );
- Constructor1->setText( tr( "" ) );
- Constructor1->setPixmap( image1 );
- Constructor1->setChecked( TRUE );
- Constructor1->setSizePolicy( QSizePolicy( (QSizePolicy::SizeType)1, (QSizePolicy::SizeType)0, Constructor1->sizePolicy().hasHeightForWidth() ) );
- Constructor1->setMinimumSize( QSize( 50, 0 ) );
- GroupConstructorsLayout->addWidget( Constructor1, 0, 0 );
- QSpacerItem* spacer = new QSpacerItem( 20, 20, QSizePolicy::Expanding, QSizePolicy::Minimum );
- GroupConstructorsLayout->addItem( spacer, 0, 1 );
- SMESHGUI_EditHypothesesDlgLayout->addWidget( GroupConstructors, 0, 0 );
-
- /***************************************************************/
- GroupButtons = new QGroupBox( this, "GroupButtons" );
- GroupButtons->setGeometry( QRect( 10, 10, 281, 96 ) );
- GroupButtons->setTitle( tr( "" ) );
- GroupButtons->setColumnLayout(0, Qt::Vertical );
- GroupButtons->layout()->setSpacing( 0 );
- GroupButtons->layout()->setMargin( 0 );
- GroupButtonsLayout = new QGridLayout( GroupButtons->layout() );
- GroupButtonsLayout->setAlignment( Qt::AlignTop );
- GroupButtonsLayout->setSpacing( 6 );
- GroupButtonsLayout->setMargin( 11 );
- buttonCancel = new QPushButton( GroupButtons, "buttonCancel" );
- buttonCancel->setText( tr( "SMESH_BUT_CLOSE" ) );
- buttonCancel->setAutoDefault( TRUE );
- buttonCancel->setDefault( TRUE );
- buttonCancel->setEnabled( TRUE ) ;
-
- GroupButtonsLayout->addWidget( buttonCancel, 0, 3 );
- buttonApply = new QPushButton( GroupButtons, "buttonApply" );
- buttonApply->setText( tr( "SMESH_BUT_APPLY" ) );
- buttonApply->setAutoDefault( TRUE );
- buttonApply->setDefault( FALSE );
- buttonApply->setEnabled( FALSE ) ;
-
- GroupButtonsLayout->addWidget( buttonApply, 0, 1 );
- QSpacerItem* spacer_9 = new QSpacerItem( 20, 20, QSizePolicy::Expanding, QSizePolicy::Minimum );
- GroupButtonsLayout->addItem( spacer_9, 0, 2 );
- buttonOk = new QPushButton( GroupButtons, "buttonOk" );
- buttonOk->setText( tr( "SMESH_BUT_OK" ) );
-
- buttonOk->setAutoDefault( TRUE );
- buttonOk->setDefault( FALSE );
- buttonOk->setEnabled( FALSE ) ;
-
- GroupButtonsLayout->addWidget( buttonOk, 0, 0 );
- SMESHGUI_EditHypothesesDlgLayout->addWidget( GroupButtons, 5, 0 );
-
- /***************************************************************/
- GroupC1 = new QGroupBox( this, "GroupC1" );
- GroupC1->setTitle( tr( "SMESH_ARGUMENTS" ) );
- GroupC1->setMinimumSize( QSize( 0, 0 ) );
- GroupC1->setFrameShape( QGroupBox::Box );
- GroupC1->setFrameShadow( QGroupBox::Sunken );
+ GroupC1 = new QGroupBox( tr( "SMESH_ARGUMENTS" ), this, "GroupC1" );
GroupC1->setColumnLayout(0, Qt::Vertical );
GroupC1->layout()->setSpacing( 0 );
GroupC1->layout()->setMargin( 0 );
- GroupC1Layout = new QGridLayout( GroupC1->layout() );
+ QGridLayout* GroupC1Layout = new QGridLayout( GroupC1->layout() );
GroupC1Layout->setAlignment( Qt::AlignTop );
GroupC1Layout->setSpacing( 6 );
GroupC1Layout->setMargin( 11 );
- TextLabelC1A1 = new QLabel( GroupC1, "TextLabelC1A1" );
- TextLabelC1A1->setText( tr( "SMESH_OBJECT_MESHorSUBMESH" ) );
- TextLabelC1A1->setMinimumSize( QSize( 50, 0 ) );
- TextLabelC1A1->setFrameShape( QLabel::NoFrame );
- TextLabelC1A1->setFrameShadow( QLabel::Plain );
+ TextLabelC1A1 = new QLabel( tr( "SMESH_OBJECT_MESHorSUBMESH" ), GroupC1, "TextLabelC1A1" );
GroupC1Layout->addWidget( TextLabelC1A1, 0, 0 );
SelectButtonC1A1 = new QPushButton( GroupC1, "SelectButtonC1A1" );
- SelectButtonC1A1->setText( tr( "" ) );
SelectButtonC1A1->setPixmap( image0 );
- SelectButtonC1A1->setToggleButton( FALSE );
GroupC1Layout->addWidget( SelectButtonC1A1, 0, 1 );
LineEditC1A1 = new QLineEdit( GroupC1, "LineEditC1A1" );
GroupC1Layout->addWidget( LineEditC1A1, 0, 2 );
- TextLabelC1A2 = new QLabel( GroupC1, "TextLabelC1A2" );
- TextLabelC1A2->setText( tr( "SMESH_OBJECT_GEOM" ) );
- TextLabelC1A2->setMinimumSize( QSize( 50, 0 ) );
- TextLabelC1A2->setFrameShape( QLabel::NoFrame );
- TextLabelC1A2->setFrameShadow( QLabel::Plain );
+ TextLabelC1A2 = new QLabel( tr( "SMESH_OBJECT_GEOM" ), GroupC1, "TextLabelC1A2" );
GroupC1Layout->addWidget( TextLabelC1A2, 1, 0 );
SelectButtonC1A2 = new QPushButton( GroupC1, "SelectButtonC1A2" );
- SelectButtonC1A2->setText( tr( "" ) );
SelectButtonC1A2->setPixmap( image0 );
SelectButtonC1A2->setToggleButton( FALSE );
GroupC1Layout->addWidget( SelectButtonC1A2, 1, 1 );
LineEditC1A2 = new QLineEdit( GroupC1, "LineEditC1A2" );
GroupC1Layout->addWidget( LineEditC1A2, 1, 2 );
- GroupHypotheses = new QGroupBox( this, "GroupHypotheses" );
- GroupHypotheses->setTitle( tr( "SMESH_HYPOTHESES" ) );
+ SMESHGUI_EditHypothesesDlgLayout->addWidget( GroupC1, 0, 0 );
+
+ /***************************************************************/
+ GroupHypotheses = new QGroupBox( tr( "SMESH_HYPOTHESES" ), this, "GroupHypotheses" );
GroupHypotheses->setColumnLayout(0, Qt::Vertical );
GroupHypotheses->layout()->setSpacing( 0 );
GroupHypotheses->layout()->setMargin( 0 );
- grid_3 = new QGridLayout( GroupHypotheses->layout() );
- grid_3->setGeometry( QRect( 12, 18, 139, 110 ) );
+ QGridLayout* grid_3 = new QGridLayout( GroupHypotheses->layout() );
grid_3->setAlignment( Qt::AlignTop );
grid_3->setSpacing( 6 );
grid_3->setMargin( 11 );
- hbox_2 = new QHBoxLayout;
- hbox_2->setSpacing( 6 );
- hbox_2->setMargin( 0 );
-
- vbox = new QVBoxLayout;
- vbox->setSpacing( 6 );
- vbox->setMargin( 0 );
-
- TextHypDefinition = new QLabel( GroupHypotheses, "TextHypDefinition" );
- TextHypDefinition->setText( tr( "SMESH_AVAILABLE" ) );
- vbox->addWidget( TextHypDefinition );
+ TextHypDefinition = new QLabel( tr( "SMESH_AVAILABLE" ), GroupHypotheses, "TextHypDefinition" );
+ grid_3->addWidget( TextHypDefinition, 0, 0 );
ListHypDefinition = new QListBox( GroupHypotheses, "ListHypDefinition" );
- ListHypDefinition->setMinimumSize( 100, 50);
-// ListHypDefinition->setRowMode(4);
-// ListHypDefinition->setRowMode( QListBox::FixedNumber );
-// ListHypDefinition->setLineWidth( 4 );
-// ListHypDefinition->setColumnMode( QListBox::Variable );
-// ListHypDefinition->setVariableHeight( FALSE );
-// ListHypDefinition->insertItem( tr( "New Item" ) );
- vbox->addWidget( ListHypDefinition );
- hbox_2->addLayout( vbox );
-
- vbox_2 = new QVBoxLayout;
- vbox_2->setSpacing( 6 );
- vbox_2->setMargin( 0 );
-
- TextHypAssignation = new QLabel( GroupHypotheses, "TextHypAssignation" );
- TextHypAssignation->setText( tr( "SMESH_EDIT_USED" ) );
- vbox_2->addWidget( TextHypAssignation );
+ ListHypDefinition->setMinimumSize( 100, 100 );
+ grid_3->addWidget( ListHypDefinition, 1, 0 );
+
+ TextHypAssignation = new QLabel( tr( "SMESH_EDIT_USED" ), GroupHypotheses, "TextHypAssignation" );
+ grid_3->addWidget( TextHypAssignation, 0, 1 );
ListHypAssignation = new QListBox( GroupHypotheses, "ListHypAssignation" );
- ListHypAssignation->setMinimumSize( 100, 50);
-// ListHypAssignation->setRowMode(4);
-// ListHypAssignation->setRowMode( QListBox::FixedNumber );
-// ListHypAssignation->setLineWidth( 4 );
-// ListHypAssignation->setColumnMode( QListBox::Variable );
-// ListHypAssignation->setVariableHeight( FALSE );
-// ListHypAssignation->insertItem( tr( "New Item" ) );
- vbox_2->addWidget( ListHypAssignation );
- hbox_2->addLayout( vbox_2 );
-
- grid_3->addLayout( hbox_2, 0, 0 );
-
- SMESHGUI_EditHypothesesDlgLayout->addWidget( GroupHypotheses, 2, 0 );
-
- GroupAlgorithms = new QGroupBox( this, "GroupAlgorithms" );
- GroupAlgorithms->setTitle( tr( "SMESH_ADD_ALGORITHM" ) );
+ ListHypAssignation->setMinimumSize( 100, 100 );
+ grid_3->addWidget( ListHypAssignation, 1, 1 );
+
+ SMESHGUI_EditHypothesesDlgLayout->addWidget( GroupHypotheses, 1, 0 );
+
+ /***************************************************************/
+ GroupAlgorithms = new QGroupBox( tr( "SMESH_ADD_ALGORITHM" ), this, "GroupAlgorithms" );
GroupAlgorithms->setColumnLayout(0, Qt::Vertical );
GroupAlgorithms->layout()->setSpacing( 0 );
GroupAlgorithms->layout()->setMargin( 0 );
- grid_4 = new QGridLayout( GroupAlgorithms->layout() );
- grid_4->setGeometry( QRect( 12, 18, 139, 110 ) );
+ QGridLayout* grid_4 = new QGridLayout( GroupAlgorithms->layout() );
grid_4->setAlignment( Qt::AlignTop );
grid_4->setSpacing( 6 );
grid_4->setMargin( 11 );
- hbox_3 = new QHBoxLayout;
- hbox_3->setSpacing( 6 );
- hbox_3->setMargin( 0 );
-
- vbox_3 = new QVBoxLayout;
- vbox_3->setSpacing( 6 );
- vbox_3->setMargin( 0 );
-
- TextAlgoDefinition = new QLabel( GroupAlgorithms, "TextAlgoDefinition" );
- TextAlgoDefinition->setText( tr( "SMESH_AVAILABLE" ) );
- vbox_3->addWidget( TextAlgoDefinition );
+ TextAlgoDefinition = new QLabel( tr( "SMESH_AVAILABLE" ), GroupAlgorithms, "TextAlgoDefinition" );
+ grid_4->addWidget( TextAlgoDefinition, 0, 0 );
ListAlgoDefinition = new QListBox( GroupAlgorithms, "ListAlgoDefinition" );
- ListAlgoDefinition->setMinimumSize( 100, 50);
-// ListAlgoDefinition->setRowMode(4);
-// ListAlgoDefinition->setRowMode( QListBox::FixedNumber );
-// ListAlgoDefinition->setLineWidth( 4 );
-// ListAlgoDefinition->setColumnMode( QListBox::Variable );
-// ListAlgoDefinition->setVariableHeight( FALSE );
-// ListAlgoDefinition->insertItem( tr( "New Item" ) );
- vbox_3->addWidget( ListAlgoDefinition );
- hbox_3->addLayout( vbox_3 );
-
- vbox_4 = new QVBoxLayout;
- vbox_4->setSpacing( 6 );
- vbox_4->setMargin( 0 );
-
- TextAlgoAssignation = new QLabel( GroupAlgorithms, "TextAlgoAssignation" );
- TextAlgoAssignation->setText( tr( "SMESH_EDIT_USED" ) );
- vbox_4->addWidget( TextAlgoAssignation );
+ ListAlgoDefinition->setMinimumSize( 100, 100 );
+ grid_4->addWidget( ListAlgoDefinition, 1, 0 );
+
+ TextAlgoAssignation = new QLabel( tr( "SMESH_EDIT_USED" ), GroupAlgorithms, "TextAlgoAssignation" );
+ grid_4->addWidget( TextAlgoAssignation, 0, 1 );
ListAlgoAssignation = new QListBox( GroupAlgorithms, "ListAlgoAssignation" );
- ListAlgoAssignation ->setMinimumSize( 100, 50);
-// ListAlgoAssignation->setRowMode(4);
-// ListAlgoAssignation->setRowMode( QListBox::FixedNumber );
-// ListAlgoAssignation->setLineWidth( 4 );
-// ListAlgoAssignation->setColumnMode( QListBox::Variable );
-// ListAlgoAssignation->setVariableHeight( FALSE );
-// ListAlgoAssignation->insertItem( tr( "New Item" ) );
- vbox_4->addWidget( ListAlgoAssignation );
- hbox_3->addLayout( vbox_4 );
-
- grid_4->addLayout( hbox_3, 0, 0 );
- SMESHGUI_EditHypothesesDlgLayout->addWidget( GroupAlgorithms, 3, 0 );
-
- SMESHGUI_EditHypothesesDlgLayout->addWidget( GroupC1, 1, 0 );
+ ListAlgoAssignation ->setMinimumSize( 100, 100 );
+ grid_4->addWidget( ListAlgoAssignation, 1, 1 );
+
+ SMESHGUI_EditHypothesesDlgLayout->addWidget( GroupAlgorithms, 2, 0 );
+
/***************************************************************/
+ GroupButtons = new QGroupBox( this, "GroupButtons" );
+ GroupButtons->setColumnLayout(0, Qt::Vertical );
+ GroupButtons->layout()->setSpacing( 0 );
+ GroupButtons->layout()->setMargin( 0 );
+ QGridLayout* GroupButtonsLayout = new QGridLayout( GroupButtons->layout() );
+ GroupButtonsLayout->setAlignment( Qt::AlignTop );
+ GroupButtonsLayout->setSpacing( 6 );
+ GroupButtonsLayout->setMargin( 11 );
- Init(Sel) ;
+ buttonOk = new QPushButton( tr( "SMESH_BUT_OK" ), GroupButtons, "buttonOk" );
+ buttonOk->setAutoDefault( TRUE );
+ buttonOk->setDefault( FALSE );
+ GroupButtonsLayout->addWidget( buttonOk, 0, 0 );
+
+ buttonApply = new QPushButton( tr( "SMESH_BUT_APPLY" ), GroupButtons, "buttonApply" );
+ buttonApply->setAutoDefault( TRUE );
+ buttonApply->setDefault( FALSE );
+ GroupButtonsLayout->addWidget( buttonApply, 0, 1 );
+
+ GroupButtonsLayout->addItem( new QSpacerItem( 20, 20, QSizePolicy::Expanding, QSizePolicy::Minimum ), 0, 2 );
+
+ buttonCancel = new QPushButton( tr( "SMESH_BUT_CLOSE" ), GroupButtons, "buttonCancel" );
+ buttonCancel->setAutoDefault( TRUE );
+ buttonCancel->setDefault( TRUE );
+ buttonCancel->setEnabled( TRUE ) ;
+ GroupButtonsLayout->addWidget( buttonCancel, 0, 3 );
+
+ SMESHGUI_EditHypothesesDlgLayout->addWidget( GroupButtons, 4, 0 );
+ /***************************************************************/
+ Init(Sel) ;
}
//=================================================================================
void SMESHGUI_EditHypothesesDlg::Init( SALOME_Selection* Sel )
{
- GroupC1->show();
- myConstructorId = 0 ;
- Constructor1->setChecked( TRUE );
- myEditCurrentArgument = LineEditC1A1 ;
mySelection = Sel;
mySMESHGUI = SMESHGUI::GetSMESHGUI() ;
mySMESHGUI->SetActiveDialogBox( (QDialog*)this ) ;
InitHypDefinition();
InitAlgoDefinition();
- InitHypAssignation();
- InitAlgoAssignation();
-
myGeomFilter = new SALOME_TypeFilter( "GEOM" );
myMeshOrSubMeshFilter = new SMESH_TypeFilter( MESHorSUBMESH );
mySubMesh = SMESH::SMESH_subMesh::_nil();
/* signals and slots connections */
- connect( buttonCancel, SIGNAL( clicked() ), this, SLOT( ClickOnCancel() ) ) ;
- connect( GroupConstructors, SIGNAL(clicked(int) ), SLOT( ConstructorsClicked(int) ) );
+ connect( buttonOk, SIGNAL( clicked() ), this, SLOT( ClickOnOk() ) );
+ connect( buttonApply, SIGNAL( clicked() ), this, SLOT( ClickOnApply() ) );
+ connect( buttonCancel, SIGNAL( clicked() ), this, SLOT( ClickOnCancel() ) );
- connect( SelectButtonC1A1, SIGNAL (clicked() ), this, SLOT( SetEditCurrentArgument() ) ) ;
- connect( SelectButtonC1A2, SIGNAL (clicked() ), this, SLOT( SetEditCurrentArgument() ) ) ;
+ connect( SelectButtonC1A1, SIGNAL (clicked() ), this, SLOT( SetEditCurrentArgument() ) ) ;
+ connect( SelectButtonC1A2, SIGNAL (clicked() ), this, SLOT( SetEditCurrentArgument() ) ) ;
- connect( mySelection, SIGNAL( currentSelectionChanged() ), this, SLOT( SelectionIntoArgument() ) );
- connect( mySMESHGUI, SIGNAL ( SignalDeactivateActiveDialog() ), this, SLOT( DeactivateActiveDialog() ) ) ;
- connect( mySMESHGUI, SIGNAL ( SignalCloseAllDialogs() ), this, SLOT( ClickOnCancel() ) ) ;
+ connect( mySelection, SIGNAL( currentSelectionChanged() ), this, SLOT( SelectionIntoArgument() ) );
+ connect( mySMESHGUI, SIGNAL( SignalDeactivateActiveDialog() ), this, SLOT( DeactivateActiveDialog() ) ) ;
+ connect( mySMESHGUI, SIGNAL( SignalCloseAllDialogs() ), this, SLOT( ClickOnCancel() ) ) ;
- connect( ListHypAssignation, SIGNAL( clicked(QListBoxItem*) ), this, SLOT( removeItem(QListBoxItem*) ) );
- connect( ListAlgoAssignation, SIGNAL( clicked(QListBoxItem*) ), this, SLOT( removeItem(QListBoxItem*) ) );
+ connect( ListHypAssignation, SIGNAL( doubleClicked(QListBoxItem*) ), this, SLOT( removeItem(QListBoxItem*) ) );
+ connect( ListAlgoAssignation, SIGNAL( doubleClicked(QListBoxItem*) ), this, SLOT( removeItem(QListBoxItem*) ) );
- connect( ListHypDefinition, SIGNAL( clicked(QListBoxItem*) ), this, SLOT( addItem(QListBoxItem*) ) );
- connect( ListAlgoDefinition, SIGNAL( clicked(QListBoxItem*) ), this, SLOT( addItem(QListBoxItem*) ) );
+ connect( ListHypDefinition, SIGNAL( doubleClicked(QListBoxItem*) ), this, SLOT( addItem(QListBoxItem*) ) );
+ connect( ListAlgoDefinition, SIGNAL( doubleClicked(QListBoxItem*) ), this, SLOT( addItem(QListBoxItem*) ) );
int x, y ;
mySMESHGUI->DefineDlgPosition( this, x, y ) ;
this->move( x, y ) ;
this->show() ;
+
+ LineEditC1A1->setFocus() ;
+ myEditCurrentArgument = LineEditC1A1;
+ mySelection->ClearFilters() ;
+ mySelection->AddFilter(myMeshOrSubMeshFilter) ;
+
SelectionIntoArgument();
- return ;
+ UpdateControlState();
}
//=================================================================================
-// function : ConstructorsClicked()
-// purpose : Radio button management
+// function : ClickOnOk()
+// purpose :
//=================================================================================
-void SMESHGUI_EditHypothesesDlg::ConstructorsClicked(int constructorId)
+void SMESHGUI_EditHypothesesDlg::ClickOnOk()
{
- return ;
+ if ( ClickOnApply() )
+ ClickOnCancel() ;
}
+//=================================================================================
+// function : ClickOnApply()
+// purpose :
+//=================================================================================
+bool SMESHGUI_EditHypothesesDlg::ClickOnApply()
+{
+ bool aRes = false;
+
+ QAD_WaitCursor wc;
+
+ QAD_Operation* op = new QAD_Operation( mySMESHGUI->GetActiveStudy() );
+
+ // start transaction
+ op->start();
+
+ if ( !myMesh->_is_nil() )
+ aRes = StoreMesh();
+ else if ( !mySubMesh->_is_nil() )
+ aRes = StoreSubMesh();
+
+ if ( aRes )
+ // commit transaction
+ op->finish();
+ else
+ // abort transaction
+ op->abort();
+
+ return aRes;
+}
+
+
//=================================================================================
// function : ClickOnCancel()
// purpose :
//=================================================================================
void SMESHGUI_EditHypothesesDlg::ClickOnCancel()
{
- disconnect( mySelection, 0, this, 0 );
- mySMESHGUI->ResetState() ;
- mySelection->ClearFilters() ;
- reject() ;
- return ;
+ close();
}
//=================================================================================
void SMESHGUI_EditHypothesesDlg::SelectionIntoArgument()
{
- myEditCurrentArgument->setText("") ;
QString aString = "";
int nbSel = mySMESHGUI->GetNameOfSelectedIObjects(mySelection, aString) ;
-
- switch (myConstructorId)
- {
- case 0:
- {
- if ( myEditCurrentArgument == LineEditC1A1 ) {
- if ( nbSel != 1 ) {
- myOkHypothesis = false;
- myOkAlgorithm = false;
- myMesh = SMESH::SMESH_Mesh::_nil();
- mySubMesh = SMESH::SMESH_subMesh::_nil();
- InitHypAssignation();
- InitAlgoAssignation();
- InitGeom();
- return ;
- } else {
- Standard_Boolean testResult ;
- Handle(SALOME_InteractiveObject) IO = mySelection->firstIObject() ;
- myMesh = mySMESHGUI->ConvertIOinMesh(IO, testResult) ;
- if( !testResult ) {
- myMesh = SMESH::SMESH_Mesh::_nil();
-
- mySubMesh = mySMESHGUI->ConvertIOinSubMesh(IO, testResult) ;
- if( !testResult ) {
- mySubMesh = SMESH::SMESH_subMesh::_nil();
- InitHypAssignation();
- InitAlgoAssignation();
- InitGeom();
- return ;
- }
- }
- InitHypAssignation();
- InitAlgoAssignation();
- InitGeom();
- }
- } else if ( myEditCurrentArgument == LineEditC1A2 ) {
- if ( nbSel != 1 ) {
- myOkHypothesis = false;
- myOkAlgorithm = false;
- myGeomShape = GEOM::GEOM_Shape::_nil();
- InitHypAssignation();
- InitAlgoAssignation();
- InitGeom();
- return ;
- } else {
- Standard_Boolean testResult ;
- Handle(SALOME_InteractiveObject) IO = mySelection->firstIObject() ;
- myGeomShape = mySMESHGUI->ConvertIOinGEOMShape(IO, testResult) ;
- if( !testResult ) {
- myGeomShape = GEOM::GEOM_Shape::_nil();
- InitHypAssignation();
- InitAlgoAssignation();
- InitGeom();
- return ;
- }
- InitHypAssignation();
- InitAlgoAssignation();
- InitGeom();
- }
- }
- break;
+
+ if ( myEditCurrentArgument == LineEditC1A1 ) {
+ if ( nbSel != 1 ) {
+ myMesh = SMESH::SMESH_Mesh::_nil();
+ mySubMesh = SMESH::SMESH_subMesh::_nil();
+ aString = "";
+ } else {
+ Standard_Boolean testResult ;
+ Handle(SALOME_InteractiveObject) IO = mySelection->firstIObject() ;
+ myMesh = mySMESHGUI->ConvertIOinMesh(IO, testResult) ;
+ if( !testResult ) {
+ myMesh = SMESH::SMESH_Mesh::_nil();
+ mySubMesh = mySMESHGUI->ConvertIOinSubMesh(IO, testResult) ;
+ if( !testResult ) {
+ mySubMesh = SMESH::SMESH_subMesh::_nil();
+ aString = "";
+ }
}
}
-
- myEditCurrentArgument->setText(aString) ;
+ myEditCurrentArgument->setText( aString );
+
+ myGeomShape = GEOM::GEOM_Shape::_nil(); // InitGeom() will try to retrieve a shape from myMesh or mySubMesh
+ InitGeom();
+
+ myImportedMesh = myGeomShape->_is_nil();
+
+ InitHypAssignation();
+ InitAlgoAssignation();
+ }
+ else if ( myEditCurrentArgument == LineEditC1A2 ) {
+ if ( nbSel != 1 )
+ myGeomShape = GEOM::GEOM_Shape::_nil();
+ else {
+ Standard_Boolean testResult ;
+ Handle(SALOME_InteractiveObject) IO = mySelection->firstIObject() ;
+ myGeomShape = mySMESHGUI->ConvertIOinGEOMShape(IO, testResult) ;
+ if( !testResult )
+ myGeomShape = GEOM::GEOM_Shape::_nil();
+ }
+ InitGeom();
+ }
+
+ UpdateControlState();
}
void SMESHGUI_EditHypothesesDlg::SetEditCurrentArgument()
{
QPushButton* send = (QPushButton*)sender();
- switch (myConstructorId)
- {
- case 0: /* default constructor */
- {
- if(send == SelectButtonC1A1) {
- LineEditC1A1->setFocus() ;
- myEditCurrentArgument = LineEditC1A1;
- mySelection->ClearFilters() ;
- mySelection->AddFilter(myMeshOrSubMeshFilter) ;
- } else if (send == SelectButtonC1A2) {
- LineEditC1A2->setFocus() ;
- myEditCurrentArgument = LineEditC1A2;
- mySelection->ClearFilters() ;
- mySelection->AddFilter(myGeomFilter) ;
- }
- SelectionIntoArgument() ;
- break;
- }
- }
- return ;
+ if(send == SelectButtonC1A1) {
+ LineEditC1A1->setFocus() ;
+ myEditCurrentArgument = LineEditC1A1;
+ mySelection->ClearFilters() ;
+ mySelection->AddFilter(myMeshOrSubMeshFilter) ;
+ } else if (send == SelectButtonC1A2) {
+ LineEditC1A2->setFocus() ;
+ myEditCurrentArgument = LineEditC1A2;
+ mySelection->ClearFilters() ;
+ mySelection->AddFilter(myGeomFilter) ;
+ }
+ SelectionIntoArgument() ;
}
//=================================================================================
//=================================================================================
void SMESHGUI_EditHypothesesDlg::DeactivateActiveDialog()
{
- if ( GroupConstructors->isEnabled() ) {
+ if ( GroupC1->isEnabled() ) {
disconnect( mySelection, 0, this, 0 );
- GroupConstructors->setEnabled(false) ;
GroupC1->setEnabled(false) ;
GroupButtons->setEnabled(false) ;
}
void SMESHGUI_EditHypothesesDlg::ActivateThisDialog()
{
mySMESHGUI->EmitSignalDeactivateDialog() ;
- GroupConstructors->setEnabled(true) ;
GroupC1->setEnabled(true) ;
GroupButtons->setEnabled(true) ;
connect ( mySelection, SIGNAL( currentSelectionChanged() ), this, SLOT( SelectionIntoArgument() ) );
- return ;
}
//=================================================================================
void SMESHGUI_EditHypothesesDlg::enterEvent(QEvent* e)
{
- if ( GroupConstructors->isEnabled() )
- return ;
- ActivateThisDialog() ;
- return ;
+ if ( !GroupC1->isEnabled() )
+ ActivateThisDialog();
}
//=================================================================================
void SMESHGUI_EditHypothesesDlg::closeEvent( QCloseEvent* e )
{
- this->ClickOnCancel() ;
- return ;
+ disconnect( mySelection, 0, this, 0 );
+ mySMESHGUI->ResetState() ;
+ mySelection->ClearFilters() ;
+ QDialog::closeEvent( e );
}
+
//=================================================================================
-// function : TextChangedInLineEdit()
+// function : removeItem()
// purpose :
//=================================================================================
-void SMESHGUI_EditHypothesesDlg::TextChangedInLineEdit(const QString& newText)
-{
- QLineEdit* send = (QLineEdit*)sender();
- QString newT = strdup(newText) ;
-
- return ;
-}
-
-void SMESHGUI_EditHypothesesDlg::removeItem(QListBoxItem* i)
+void SMESHGUI_EditHypothesesDlg::removeItem(QListBoxItem* item)
{
- if (!i) return;
+ const QObject* aSender = sender();
- SMESHGUI_StudyAPI myStudyAPI = mySMESHGUI->GetStudyAPI();
- int index = ListHypAssignation->index( i );
- if ( index != -1 ) {
- if (mapNameIOR.find( string((const char*)(i->text())) ) != mapNameIOR.end()) {
- SMESH::SMESH_Hypothesis_var Hyp =
- SMESH::SMESH_Hypothesis::_narrow( myStudyAPI.StringToIOR( mapNameIOR[ string((const char*)(i->text())) ].c_str() ) );
-
- if ( !myMesh->_is_nil() ) {
- SALOMEDS::SObject_var aMesh = myStudyAPI.FindMesh(myMesh);
- mySMESHGUI->RemoveHypothesisOrAlgorithmOnMesh(aMesh, Hyp);
- // mySMESHGUI->GetStudyAPI().ModifiedMesh( aMesh, false );
- mySMESHGUI->GetActiveStudy()->updateObjBrowser();
- }
- if ( !mySubMesh->_is_nil() ) {
- SALOMEDS::SObject_var aSubMesh = myStudyAPI.FindSubMesh(mySubMesh);
- mySMESHGUI->RemoveHypothesisOrAlgorithmOnMesh(aSubMesh, Hyp);
- // mySMESHGUI->GetStudyAPI().ModifiedMesh( aSubMesh, false );
- mySMESHGUI->GetActiveStudy()->updateObjBrowser();
- }
-
- ListHypAssignation->removeItem( index );
- }
- return;
- }
- index = ListAlgoAssignation->index( i );
- if ( index != -1 ) {
- if (mapNameIOR.find( string((const char*)(i->text())) ) != mapNameIOR.end()) {
- SMESH::SMESH_Hypothesis_var Hyp =
- SMESH::SMESH_Hypothesis::_narrow( myStudyAPI.StringToIOR(mapNameIOR[ string((const char*)(i->text())) ].c_str()) );
-
- if ( !myMesh->_is_nil() ) {
- SALOMEDS::SObject_var aMesh = myStudyAPI.FindMesh(myMesh);
- mySMESHGUI->RemoveHypothesisOrAlgorithmOnMesh(aMesh, Hyp);
- // mySMESHGUI->GetStudyAPI().ModifiedMesh( aMesh, false );
- mySMESHGUI->GetActiveStudy()->updateObjBrowser();
- }
- if ( !mySubMesh->_is_nil() ) {
- SALOMEDS::SObject_var aSubMesh = myStudyAPI.FindSubMesh(mySubMesh);
- mySMESHGUI->RemoveHypothesisOrAlgorithmOnMesh(aSubMesh, Hyp);
- // mySMESHGUI->GetStudyAPI().ModifiedMesh( aSubMesh, false );
- mySMESHGUI->GetActiveStudy()->updateObjBrowser();
- }
+ if (!item) return;
- ListAlgoAssignation->removeItem( index );
- }
+ if ( aSender == ListHypAssignation ) {
+ ListHypAssignation->removeItem( ListHypAssignation->index( item ) );
+ }
+ else if ( aSender == ListAlgoAssignation ) {
+ ListAlgoAssignation->removeItem( ListAlgoAssignation->index( item ) );
}
+
+ UpdateControlState();
}
// function : addItem()
// purpose :
//=================================================================================
-void SMESHGUI_EditHypothesesDlg::addItem(QListBoxItem* i)
+void SMESHGUI_EditHypothesesDlg::addItem(QListBoxItem* item)
{
+ const QObject* aSender = sender();
+
+ if (!item) return;
+
+ ListBoxIOR* i = 0;
+ if ( item->rtti() == ListBoxIOR::RTTI_IOR )
+ i = (ListBoxIOR*)item;
if (!i) return;
+
+ bool isFound = false;
- SMESHGUI_StudyAPI myStudyAPI = mySMESHGUI->GetStudyAPI();
- if ( ListHypDefinition->findItem( i->text() ) ) {
- if ( !ListHypAssignation->findItem( i->text() ) ) {
- ListHypAssignation->insertItem( i->text() );
-
- if (mapNameIOR.find( string((const char*)(i->text())) ) != mapNameIOR.end()) {
- SMESH::SMESH_Hypothesis_var Hyp =
- SMESH::SMESH_Hypothesis::_narrow( myStudyAPI.StringToIOR(mapNameIOR[ string((const char*)(i->text())) ].c_str()) );
-
- if ( !myMesh->_is_nil() )
- mySMESHGUI->AddHypothesisOnMesh(myMesh, Hyp);
- if ( !mySubMesh->_is_nil() )
- mySMESHGUI->AddHypothesisOnSubMesh(mySubMesh, Hyp);
+ if ( aSender == ListHypDefinition ) {
+ for ( int j = 0, n = ListHypAssignation->count(); !isFound && j < n; j++ ) {
+ if ( ListHypAssignation->item( j )->rtti() == ListBoxIOR::RTTI_IOR ) {
+ ListBoxIOR* anItem = (ListBoxIOR*)ListHypAssignation->item( j );
+ isFound = !strcmp( anItem->GetIOR(), i->GetIOR() );
}
}
- return;
+ if ( !isFound )
+ ListBoxIOR* anItem = new ListBoxIOR( ListHypAssignation,
+ strdup( i->GetIOR() ),
+ strdup( i->text().latin1() ) );
}
- if ( ListAlgoDefinition->findItem( i->text() ) ) {
- if ( !ListAlgoAssignation->findItem( i->text() ) ) {
- ListAlgoAssignation->insertItem( i->text() );
-
- if (mapNameIOR.find( string((const char*)(i->text())) ) != mapNameIOR.end()) {
- SMESH::SMESH_Hypothesis_var Hyp =
- SMESH::SMESH_Hypothesis::_narrow( myStudyAPI.StringToIOR(mapNameIOR[ string((const char*)(i->text())) ].c_str()) );
-
- if ( !myMesh->_is_nil() )
- mySMESHGUI->AddAlgorithmOnMesh(myMesh, Hyp);
- if ( !mySubMesh->_is_nil() )
- mySMESHGUI->AddAlgorithmOnSubMesh(mySubMesh, Hyp);
+ else if ( aSender == ListAlgoDefinition ) {
+ for ( int j = 0, n = ListAlgoAssignation->count(); !isFound && j < n; j++ ) {
+ if ( ListAlgoAssignation->item( j )->rtti() == ListBoxIOR::RTTI_IOR ) {
+ ListBoxIOR* anItem = (ListBoxIOR*)ListAlgoAssignation->item( j );
+ isFound = !strcmp( anItem->GetIOR(), i->GetIOR() );
}
}
+ if ( !isFound )
+ ListBoxIOR* anItem = new ListBoxIOR( ListAlgoAssignation,
+ strdup( i->GetIOR() ),
+ strdup( i->text().latin1() ) );
}
- mySMESHGUI->GetActiveStudy()->updateObjBrowser();
+
+ UpdateControlState();
}
//=================================================================================
void SMESHGUI_EditHypothesesDlg::InitHypDefinition()
{
+ ListHypDefinition->clear();
+
SALOMEDS::SComponent_var father = mySMESHGUI->GetStudy()->FindComponent("MESH");
+ if ( father->_is_nil() )
+ return;
+
SALOMEDS::SObject_var HypothesisRoot;
SALOMEDS::GenericAttribute_var anAttr;
SALOMEDS::AttributeName_var aName;
for (; it->More();it->Next()) {
SALOMEDS::SObject_var Obj = it->Value();
if (Obj->FindAttribute(anAttr, "AttributeName") ) {
- aName = SALOMEDS::AttributeName::_narrow(anAttr);
- ListHypDefinition->insertItem(aName->Value());
-
- if (Obj->FindAttribute(anAttr, "AttributeIOR")) {
- anIOR = SALOMEDS::AttributeIOR::_narrow(anAttr);
- mapNameIOR[ aName->Value() ] = anIOR->Value();
- }
+ aName = SALOMEDS::AttributeName::_narrow(anAttr);
+ if (Obj->FindAttribute(anAttr, "AttributeIOR")) {
+ anIOR = SALOMEDS::AttributeIOR::_narrow(anAttr);
+ ListBoxIOR* anItem = new ListBoxIOR( ListHypDefinition,
+ anIOR->Value(),
+ aName->Value() );
+ }
}
}
}
{
MESSAGE ( " InitHypAssignation " << myMesh->_is_nil() )
MESSAGE ( " InitHypAssignation " << mySubMesh->_is_nil() )
+
+ myMapOldHypos.clear();
ListHypAssignation->clear();
- SMESHGUI_StudyAPI myStudyAPI = mySMESHGUI->GetStudyAPI();
- int Tag_RefOnAppliedHypothesis = 2;
- SALOMEDS::SObject_var AHR, aRef;
+ if ( myImportedMesh )
+ return;
+
+ SALOMEDS::SObject_var aMorSM, AHR, aRef;
SALOMEDS::GenericAttribute_var anAttr;
SALOMEDS::AttributeName_var aName;
+ SALOMEDS::AttributeIOR_var anIOR;
+ SMESHGUI_StudyAPI myStudyAPI = mySMESHGUI->GetStudyAPI();
- if ( !myMesh->_is_nil() ) {
- SALOMEDS::SObject_var aMesh = myStudyAPI.FindMesh( myMesh );
- if ( aMesh->FindSubObject (2, AHR)) {
- SALOMEDS::ChildIterator_var it = mySMESHGUI->GetStudy()->NewChildIterator(AHR);
- for (; it->More();it->Next()) {
- SALOMEDS::SObject_var Obj = it->Value();
- if ( Obj->ReferencedObject(aRef) ) {
- if (aRef->FindAttribute(anAttr, "AttributeName") ) {
- aName = SALOMEDS::AttributeName::_narrow(anAttr);
- ListHypAssignation->insertItem(aName->Value());
+ if ( !myMesh->_is_nil() )
+ aMorSM = myStudyAPI.FindObject( myMesh );
+ else if ( !mySubMesh->_is_nil() )
+ aMorSM = myStudyAPI.FindObject( mySubMesh );
+
+ if ( !aMorSM->_is_nil() && aMorSM->FindSubObject (2, AHR)) {
+ SALOMEDS::ChildIterator_var it = mySMESHGUI->GetStudy()->NewChildIterator(AHR);
+ for (; it->More();it->Next()) {
+ SALOMEDS::SObject_var Obj = it->Value();
+ if ( Obj->ReferencedObject(aRef) ) {
+ if (aRef->FindAttribute(anAttr, "AttributeName") ) {
+ aName = SALOMEDS::AttributeName::_narrow(anAttr);
+ if (aRef->FindAttribute(anAttr, "AttributeIOR")) {
+ anIOR = SALOMEDS::AttributeIOR::_narrow(anAttr);
+ ListBoxIOR* anItem = new ListBoxIOR( ListHypAssignation,
+ anIOR->Value(),
+ aName->Value() );
+ myMapOldHypos[ anIOR->Value() ] = ListHypAssignation->index( anItem );
}
}
}
}
}
- if ( !mySubMesh->_is_nil() ) {
- SALOMEDS::SObject_var aSubMesh = myStudyAPI.FindSubMesh( mySubMesh );
- if ( aSubMesh->FindSubObject (2, AHR)) {
- SALOMEDS::ChildIterator_var it = mySMESHGUI->GetStudy()->NewChildIterator(AHR);
- for (; it->More();it->Next()) {
- SALOMEDS::SObject_var Obj = it->Value();
- if ( Obj->ReferencedObject(aRef) ) {
- if (aRef->FindAttribute(anAttr, "AttributeName") ) {
- aName = SALOMEDS::AttributeName::_narrow(anAttr);
- ListHypAssignation->insertItem(aName->Value());
- }
- }
- }
- }
- }
}
//=================================================================================
//=================================================================================
void SMESHGUI_EditHypothesesDlg::InitAlgoDefinition()
{
+ ListAlgoDefinition->clear();
+
SALOMEDS::SComponent_var father = mySMESHGUI->GetStudy()->FindComponent("MESH");
+ if ( father->_is_nil() )
+ return;
+
SALOMEDS::SObject_var AlgorithmsRoot;
SALOMEDS::GenericAttribute_var anAttr;
SALOMEDS::AttributeName_var aName;
SALOMEDS::AttributeIOR_var anIOR;
- int Tag_AlgorithmsRoot = 2;
if (father->FindSubObject (2, AlgorithmsRoot)) {
SALOMEDS::ChildIterator_var it = mySMESHGUI->GetStudy()->NewChildIterator(AlgorithmsRoot);
for (; it->More();it->Next()) {
SALOMEDS::SObject_var Obj = it->Value();
if (Obj->FindAttribute(anAttr, "AttributeName") ) {
- aName = SALOMEDS::AttributeName::_narrow(anAttr);
- ListAlgoDefinition->insertItem(aName->Value());
-
- if (Obj->FindAttribute(anAttr, "AttributeIOR")) {
- anIOR = SALOMEDS::AttributeIOR::_narrow(anAttr);
- mapNameIOR[ aName->Value() ] = anIOR->Value();
- }
+ aName = SALOMEDS::AttributeName::_narrow(anAttr);
+ if (Obj->FindAttribute(anAttr, "AttributeIOR")) {
+ anIOR = SALOMEDS::AttributeIOR::_narrow(anAttr);
+ ListBoxIOR* anItem = new ListBoxIOR( ListAlgoDefinition,
+ anIOR->Value(),
+ aName->Value() );
+ }
}
}
}
{
MESSAGE ( " InitAlgoAssignation " << myMesh->_is_nil() )
MESSAGE ( " InitAlgoAssignation " << mySubMesh->_is_nil() )
+
+ myMapOldAlgos.clear();
ListAlgoAssignation->clear();
- SMESHGUI_StudyAPI myStudyAPI = mySMESHGUI->GetStudyAPI();
- int Tag_RefOnAppliedAlgorithms = 3;
- SALOMEDS::SObject_var AHR, aRef;
+ if ( myImportedMesh )
+ return;
+
+ SALOMEDS::SObject_var aMorSM, AHR, aRef;
SALOMEDS::GenericAttribute_var anAttr;
SALOMEDS::AttributeName_var aName;
-
- if ( !myMesh->_is_nil() ) {
- SALOMEDS::SObject_var aMesh = myStudyAPI.FindMesh( myMesh );
- if ( aMesh->FindSubObject (3, AHR) ) {
- SALOMEDS::ChildIterator_var it = mySMESHGUI->GetStudy()->NewChildIterator(AHR);
- for (; it->More();it->Next()) {
- SALOMEDS::SObject_var Obj = it->Value();
- if ( Obj->ReferencedObject(aRef) ) {
- if (aRef->FindAttribute(anAttr, "AttributeName") ) {
- aName = SALOMEDS::AttributeName::_narrow(anAttr);
- ListAlgoAssignation->insertItem(aName->Value());
- }
- }
- }
- }
- }
- if ( !mySubMesh->_is_nil() ) {
- SALOMEDS::SObject_var aSubMesh = myStudyAPI.FindSubMesh( mySubMesh );
- if ( aSubMesh->FindSubObject (3, AHR) ) {
- SALOMEDS::ChildIterator_var it = mySMESHGUI->GetStudy()->NewChildIterator(AHR);
- for (; it->More();it->Next()) {
- SALOMEDS::SObject_var Obj = it->Value();
- if ( Obj->ReferencedObject(aRef) ) {
- if (aRef->FindAttribute(anAttr, "AttributeName") ) {
- aName = SALOMEDS::AttributeName::_narrow(anAttr);
- ListAlgoAssignation->insertItem(aName->Value());
+ SALOMEDS::AttributeIOR_var anIOR;
+ SMESHGUI_StudyAPI myStudyAPI = mySMESHGUI->GetStudyAPI();
+
+ if ( !myMesh->_is_nil() )
+ aMorSM = myStudyAPI.FindObject( myMesh );
+ else if ( !mySubMesh->_is_nil() )
+ aMorSM = myStudyAPI.FindObject( mySubMesh );
+
+ if ( !aMorSM->_is_nil() && aMorSM->FindSubObject (3, AHR)) {
+ SALOMEDS::ChildIterator_var it = mySMESHGUI->GetStudy()->NewChildIterator(AHR);
+ for (; it->More();it->Next()) {
+ SALOMEDS::SObject_var Obj = it->Value();
+ if ( Obj->ReferencedObject(aRef) ) {
+ if (aRef->FindAttribute(anAttr, "AttributeName") ) {
+ aName = SALOMEDS::AttributeName::_narrow(anAttr);
+ if (aRef->FindAttribute(anAttr, "AttributeIOR")) {
+ anIOR = SALOMEDS::AttributeIOR::_narrow(anAttr);
+ ListBoxIOR* anItem = new ListBoxIOR( ListAlgoAssignation,
+ anIOR->Value(),
+ aName->Value() );
+ myMapOldAlgos[ anIOR->Value() ] = ListAlgoAssignation->index( anItem );
}
}
}
LineEditC1A2->setText("") ;
SMESHGUI_StudyAPI myStudyAPI = mySMESHGUI->GetStudyAPI();
- if ( !myMesh->_is_nil() ) {
- SALOMEDS::SObject_var aMesh = myStudyAPI.FindMesh( myMesh );
+ if ( myGeomShape->_is_nil() && !myMesh->_is_nil() ) {
+ SALOMEDS::SObject_var aMesh = myStudyAPI.FindObject( myMesh );
if ( !aMesh->_is_nil() )
myGeomShape = myStudyAPI.GetShapeOnMeshOrSubMesh(aMesh);
}
- if ( !mySubMesh->_is_nil() ) {
- SALOMEDS::SObject_var aSubMesh = myStudyAPI.FindSubMesh( mySubMesh );
+ if ( myGeomShape->_is_nil() && !mySubMesh->_is_nil() ) {
+ SALOMEDS::SObject_var aSubMesh = myStudyAPI.FindObject( mySubMesh );
if ( !aSubMesh->_is_nil() )
myGeomShape = myStudyAPI.GetShapeOnMeshOrSubMesh(aSubMesh);
}
SALOMEDS::SObject_var aSO = mySMESHGUI->GetStudy()->FindObjectIOR( myGeomShape->Name() );
if ( !aSO->_is_nil() ) {
if (aSO->FindAttribute(anAttr, "AttributeName") ) {
- aName = SALOMEDS::AttributeName::_narrow(anAttr);
- LineEditC1A2->setText( QString(aName->Value()) ) ;
+ aName = SALOMEDS::AttributeName::_narrow(anAttr);
+ LineEditC1A2->setText( QString(aName->Value()) ) ;
+ }
+ }
+ }
+}
+
+//=================================================================================
+// function : UpdateControlState()
+// purpose :
+//=================================================================================
+void SMESHGUI_EditHypothesesDlg::UpdateControlState()
+{
+ bool isEnabled = ( !myMesh ->_is_nil() && !myGeomShape->_is_nil() && ListHypAssignation->count() && ListAlgoAssignation->count() ) ||
+ ( !mySubMesh->_is_nil() && !myGeomShape->_is_nil() && ( ListHypAssignation->count() || ListAlgoAssignation->count() ) );
+
+ buttonOk ->setEnabled( isEnabled && !myImportedMesh );
+ buttonApply->setEnabled( isEnabled && !myImportedMesh );
+
+ SelectButtonC1A2 ->setEnabled( ALLOW_CHANGE_SHAPE && !myImportedMesh );
+ LineEditC1A2 ->setEnabled( ALLOW_CHANGE_SHAPE && !myImportedMesh );
+ ListHypDefinition ->setEnabled( !myImportedMesh );
+ ListHypAssignation ->setEnabled( !myImportedMesh );
+ ListAlgoDefinition ->setEnabled( !myImportedMesh );
+ ListAlgoAssignation->setEnabled( !myImportedMesh );
+}
+
+//=================================================================================
+// function : StoreMesh()
+// purpose :
+//=================================================================================
+bool SMESHGUI_EditHypothesesDlg::StoreMesh()
+{
+ SMESHGUI_StudyAPI myStudyAPI = mySMESHGUI->GetStudyAPI();
+ MapIOR anOldHypos, aNewHypos;
+ if ( myGeomShape->_is_nil() )
+ return false;
+ // 1. Check whether the geometric shape has changed
+ SALOMEDS::SObject_var aMeshSO = myStudyAPI.FindObject( myMesh );
+ GEOM::GEOM_Shape_var aIniGeomShape = myStudyAPI.GetShapeOnMeshOrSubMesh( aMeshSO );
+ bool bShapeChanged = aIniGeomShape->_is_nil() || !aIniGeomShape->_is_equivalent( myGeomShape );
+ if ( bShapeChanged ) {
+ // VSR : TODO : Set new shape - not supported yet by SMESH engine
+ // 1) remove all old hypotheses and algorithms and also submeshes
+ // 2) set new shape
+ }
+ MapIOR::iterator it;
+ // 2. remove not used hypotheses from the mesh
+ for ( it = myMapOldHypos.begin(); it != myMapOldHypos.end(); ++it ) {
+ string ior = it->first;
+ int index = findItem( ListHypAssignation, ior );
+ if ( index < 0 ) {
+ CORBA::Object_var anObject = myStudyAPI.StringToIOR( ior.c_str() );
+ if ( !CORBA::is_nil( anObject ) ) {
+ SMESH::SMESH_Hypothesis_var aHyp = SMESH::SMESH_Hypothesis::_narrow( anObject );
+ if ( !aHyp->_is_nil() )
+ if ( !mySMESHGUI->RemoveHypothesisOrAlgorithmOnMesh( aMeshSO, aHyp ) )
+ return false;
+ }
+ }
+ }
+ // 3. remove not used algorithms from the mesh
+ for ( it = myMapOldAlgos.begin(); it != myMapOldAlgos.end(); ++it ) {
+ string ior = it->first;
+ int index = findItem( ListAlgoAssignation, ior );
+ if ( index < 0 ) {
+ CORBA::Object_var anObject = myStudyAPI.StringToIOR( ior.c_str() );
+ if ( !CORBA::is_nil( anObject ) ) {
+ SMESH::SMESH_Hypothesis_var aHyp = SMESH::SMESH_Hypothesis::_narrow( anObject );
+ if ( !aHyp->_is_nil() )
+ if ( !mySMESHGUI->RemoveHypothesisOrAlgorithmOnMesh( aMeshSO, aHyp ) )
+ return false;
+ }
+ }
+ }
+ // 4. Add new hypotheses
+ for ( int i = 0; i < ListHypAssignation->count(); i++ ) {
+ if ( ListHypAssignation->item( i )->rtti() == ListBoxIOR::RTTI_IOR ) {
+ ListBoxIOR* anItem = ( ListBoxIOR* )( ListHypAssignation->item( i ) );
+ if ( anItem ) {
+ string ior = anItem->GetIOR();
+ if ( myMapOldHypos.find( ior ) == myMapOldHypos.end() ) {
+ CORBA::Object_var anObject = myStudyAPI.StringToIOR( ior.c_str() );
+ if ( !CORBA::is_nil( anObject ) ) {
+ SMESH::SMESH_Hypothesis_var aHyp = SMESH::SMESH_Hypothesis::_narrow( anObject );
+ if ( !aHyp->_is_nil() )
+ if ( !mySMESHGUI->AddHypothesisOnMesh( myMesh, aHyp ) )
+ return false;
+ }
+ }
+ }
+ }
+ }
+ // 4. Add new algorithms
+ for ( int i = 0; i < ListAlgoAssignation->count(); i++ ) {
+ if ( ListAlgoAssignation->item( i )->rtti() == ListBoxIOR::RTTI_IOR ) {
+ ListBoxIOR* anItem = ( ListBoxIOR* )( ListAlgoAssignation->item( i ) );
+ if ( anItem ) {
+ string ior = anItem->GetIOR();
+ if ( myMapOldAlgos.find( ior ) == myMapOldAlgos.end() ) {
+ CORBA::Object_var anObject = myStudyAPI.StringToIOR( ior.c_str() );
+ if ( !CORBA::is_nil( anObject ) ) {
+ SMESH::SMESH_Hypothesis_var aHyp = SMESH::SMESH_Hypothesis::_narrow( anObject );
+ if ( !aHyp->_is_nil() )
+ if ( !mySMESHGUI->AddAlgorithmOnMesh( myMesh, aHyp ) )
+ return false;
+ }
+ }
+ }
+ }
+ }
+ return true;
+}
+
+//=================================================================================
+// function : StoreSubMesh()
+// purpose :
+//=================================================================================
+bool SMESHGUI_EditHypothesesDlg::StoreSubMesh()
+{
+ SMESHGUI_StudyAPI myStudyAPI = mySMESHGUI->GetStudyAPI();
+ MapIOR anOldHypos, aNewHypos;
+ if ( myGeomShape->_is_nil() )
+ return false;
+ // 1. Check whether the geometric shape has changed
+ SALOMEDS::SObject_var aSubMeshSO = myStudyAPI.FindObject( mySubMesh );
+ GEOM::GEOM_Shape_var aIniGeomShape = myStudyAPI.GetShapeOnMeshOrSubMesh( aSubMeshSO );
+ bool bShapeChanged = aIniGeomShape->_is_nil() || !aIniGeomShape->_is_equivalent( myGeomShape );
+ if ( bShapeChanged ) {
+ // VSR : TODO : Set new shape - not supported yet by engine
+ // 1) remove all old hypotheses and algorithms
+ // 2) set new shape
+ }
+ MapIOR::iterator it;
+ // 2. remove not used hypotheses from the submesh
+ for ( it = myMapOldHypos.begin(); it != myMapOldHypos.end(); ++it ) {
+ string ior = it->first;
+ int index = findItem( ListHypAssignation, ior );
+ if ( index < 0 ) {
+ CORBA::Object_var anObject = myStudyAPI.StringToIOR( ior.c_str() );
+ if ( !CORBA::is_nil( anObject ) ) {
+ SMESH::SMESH_Hypothesis_var aHyp = SMESH::SMESH_Hypothesis::_narrow( anObject );
+ if ( !aHyp->_is_nil() )
+ if ( !mySMESHGUI->RemoveHypothesisOrAlgorithmOnMesh( aSubMeshSO, aHyp ) )
+ return false;
+ }
+ }
+ }
+ // 3. remove not used algorithms from the submesh
+ for ( it = myMapOldAlgos.begin(); it != myMapOldAlgos.end(); ++it ) {
+ string ior = it->first;
+ int index = findItem( ListAlgoAssignation, ior );
+ if ( index < 0 ) {
+ CORBA::Object_var anObject = myStudyAPI.StringToIOR( ior.c_str() );
+ if ( !CORBA::is_nil( anObject ) ) {
+ SMESH::SMESH_Hypothesis_var aHyp = SMESH::SMESH_Hypothesis::_narrow( anObject );
+ if ( !aHyp->_is_nil() )
+ if ( !mySMESHGUI->RemoveHypothesisOrAlgorithmOnMesh( aSubMeshSO, aHyp ) )
+ return false;
+ }
+ }
+ }
+ // 4. Add new hypotheses
+ for ( int i = 0; i < ListHypAssignation->count(); i++ ) {
+ if ( ListHypAssignation->item( i )->rtti() == ListBoxIOR::RTTI_IOR ) {
+ ListBoxIOR* anItem = ( ListBoxIOR* )( ListHypAssignation->item( i ) );
+ if ( anItem ) {
+ string ior = anItem->GetIOR();
+ if ( myMapOldHypos.find( ior ) == myMapOldHypos.end() ) {
+ CORBA::Object_var anObject = myStudyAPI.StringToIOR( ior.c_str() );
+ if ( !CORBA::is_nil( anObject ) ) {
+ SMESH::SMESH_Hypothesis_var aHyp = SMESH::SMESH_Hypothesis::_narrow( anObject );
+ if ( !aHyp->_is_nil() )
+ if ( !mySMESHGUI->AddHypothesisOnSubMesh( mySubMesh, aHyp ) )
+ return false;
+ }
+ }
+ }
+ }
+ }
+ // 4. Add new algorithms
+ for ( int i = 0; i < ListAlgoAssignation->count(); i++ ) {
+ if ( ListAlgoAssignation->item( i )->rtti() == ListBoxIOR::RTTI_IOR ) {
+ ListBoxIOR* anItem = ( ListBoxIOR* )( ListAlgoAssignation->item( i ) );
+ if ( anItem ) {
+ string ior = anItem->GetIOR();
+ if ( myMapOldAlgos.find( ior ) == myMapOldAlgos.end() ) {
+ CORBA::Object_var anObject = myStudyAPI.StringToIOR( ior.c_str() );
+ if ( !CORBA::is_nil( anObject ) ) {
+ SMESH::SMESH_Hypothesis_var aHyp = SMESH::SMESH_Hypothesis::_narrow( anObject );
+ if ( !aHyp->_is_nil() )
+ if ( !mySMESHGUI->AddAlgorithmOnSubMesh( mySubMesh, aHyp ) )
+ return false;
+ }
+ }
}
}
}
+ return true;
}
#include "SMESH_TypeFilter.hxx"
// QT Includes
-#include <qvariant.h>
#include <qdialog.h>
// IDL Headers
#include <map>
#include <string>
-using namespace std;
-
-class QVBoxLayout;
-class QHBoxLayout;
-class QGridLayout;
-class QButtonGroup;
class QGroupBox;
class QLabel;
class QLineEdit;
class QPushButton;
-class QRadioButton;
class QListBox;
class QListBoxItem;
class SMESHGUI;
+typedef map<string, int> MapIOR;
//=================================================================================
// class : SMESHGUI_EditHypothesesDlg
SMESHGUI_EditHypothesesDlg( QWidget* parent = 0, const char* name = 0, SALOME_Selection* Sel = 0, bool modal = FALSE, WFlags fl = 0 );
~SMESHGUI_EditHypothesesDlg();
-private:
+protected:
+ virtual void closeEvent( QCloseEvent* e );
+ virtual void enterEvent ( QEvent* );
+private:
void Init( SALOME_Selection* Sel ) ;
- void closeEvent( QCloseEvent* e ) ;
- void enterEvent ( QEvent * ) ;
void InitHypDefinition();
void InitAlgoDefinition();
void InitGeom();
+ void UpdateControlState();
+
+ bool StoreMesh();
+ bool StoreSubMesh();
+
+private:
SMESHGUI* mySMESHGUI ;
SALOME_Selection* mySelection ;
GEOM::GEOM_Shape_var myGeomShape ;
- int myConstructorId ;
QLineEdit* myEditCurrentArgument;
SMESH::SMESH_Mesh_var myMesh;
Handle(SALOME_TypeFilter) myGeomFilter;
Handle(SMESH_TypeFilter) myMeshOrSubMeshFilter;
- map<string,string> mapNameIOR;
-
- SALOME_ListIO HypoList;
- SALOME_ListIO AlgoList;
-
- bool myOkHypothesis;
- bool myOkAlgorithm;
+ MapIOR myMapOldHypos, myMapOldAlgos;
- SMESH::SMESH_Hypothesis_var myHypothesis;
- SMESH::SMESH_Hypothesis_var myAlgorithm;
-
- SMESH::ListOfHypothesis_var myLHypothesis;
- SMESH::ListOfHypothesis_var myLAlgorithm;
+ bool myImportedMesh;
- QButtonGroup* GroupConstructors;
- QRadioButton* Constructor1;
QGroupBox* GroupButtons;
QPushButton* buttonOk;
- QPushButton* buttonCancel;
QPushButton* buttonApply;
- QGroupBox* GroupC1;
+ QPushButton* buttonCancel;
+ QGroupBox* GroupC1;
QLabel* TextLabelC1A1;
QPushButton* SelectButtonC1A1;
QLineEdit* LineEditC1A1;
-
QLabel* TextLabelC1A2;
QPushButton* SelectButtonC1A2;
QLineEdit* LineEditC1A2;
- QGroupBox* GroupHypotheses;
- QLabel* TextHypDefinition;
- QListBox* ListHypDefinition;
- QLabel* TextHypAssignation;
- QListBox* ListHypAssignation;
+ QGroupBox* GroupHypotheses;
+ QLabel* TextHypDefinition;
+ QListBox* ListHypDefinition;
+ QLabel* TextHypAssignation;
+ QListBox* ListHypAssignation;
- QGroupBox* GroupAlgorithms;
- QLabel* TextAlgoDefinition;
- QListBox* ListAlgoDefinition;
- QLabel* TextAlgoAssignation;
- QListBox* ListAlgoAssignation;
+ QGroupBox* GroupAlgorithms;
+ QLabel* TextAlgoDefinition;
+ QListBox* ListAlgoDefinition;
+ QLabel* TextAlgoAssignation;
+ QListBox* ListAlgoAssignation;
private slots:
-
- void ConstructorsClicked(int constructorId);
+ void ClickOnOk();
+ bool ClickOnApply();
void ClickOnCancel();
void SetEditCurrentArgument() ;
void SelectionIntoArgument() ;
void DeactivateActiveDialog() ;
void ActivateThisDialog() ;
- void TextChangedInLineEdit(const QString& newText) ;
void removeItem(QListBoxItem*);
void addItem(QListBoxItem*);
-
-protected:
- QGridLayout* SMESHGUI_EditHypothesesDlgLayout;
- QGridLayout* GroupConstructorsLayout;
- QGridLayout* GroupButtonsLayout;
- QGridLayout* GroupC1Layout;
-
- QGridLayout* grid_3;
- QGridLayout* grid_4;
-
- QHBoxLayout* hbox_2;
- QHBoxLayout* hbox_3;
-
- QVBoxLayout* vbox;
- QVBoxLayout* vbox_2;
- QVBoxLayout* vbox_3;
- QVBoxLayout* vbox_4;
-
};
#endif // DIALOGBOX_EDIT_HYPOTHESES_H
--- /dev/null
+// SMESHGUI_Filter : Filters for VTK viewer
+//
+// Copyright (C) 2003 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
+// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
+//
+// This library 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.
+//
+// This library 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 this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+//
+// See http://www.opencascade.org/SALOME/ or email : webmaster.salome@opencascade.org
+//
+//
+//
+// File : SMESHGUI_Filter.cxx
+// Author : Sergey LITONIN
+// Module : SMESH
+
+#include "SMESHGUI_Filter.h"
+
+#include <vtkCell.h>
+
+#include <gp_Vec.hxx>
+#include <Precision.hxx>
+#include "SMESH_Actor.h"
+#include "SMESHGUI.h"
+
+IMPLEMENT_STANDARD_HANDLE(SMESHGUI_Filter, VTKViewer_Filter)
+IMPLEMENT_STANDARD_RTTIEXT(SMESHGUI_Filter, VTKViewer_Filter)
+
+/*
+ Class : SMESHGUI_Filter
+ Description : Selection filter for VTK viewer. This class aggregate object
+ of SMESH_Filter class and uses it for verification of criterion
+*/
+
+//=======================================================================
+// name : SMESHGUI_Filter::SMESHGUI_Filter
+// Purpose : Constructor
+//=======================================================================
+SMESHGUI_Filter::SMESHGUI_Filter()
+{
+ myActor = 0;
+}
+
+SMESHGUI_Filter::~SMESHGUI_Filter()
+{
+}
+
+//=======================================================================
+// name : SMESHGUI_Filter::IsValid
+// Purpose : Verify whether entry id satisfies to criterion of the filter
+//=======================================================================
+bool SMESHGUI_Filter::IsValid( const int theCellId ) const
+{
+ if ( myActor == 0 || myPred->_is_nil() )
+ return false;
+
+ SMESH_Actor* anActor = ( SMESH_Actor* )myActor;
+
+ int aMeshId = anActor->GetElemObjId( theCellId );
+
+ return myPred->IsSatisfy( aMeshId );
+}
+
+//=======================================================================
+// name : SMESHGUI_Filter::SetPredicate
+// Purpose : Set new pridicate to the filter
+//=======================================================================
+void SMESHGUI_Filter::SetPredicate( SMESH::Predicate_ptr thePred )
+{
+ myPred = thePred;
+}
+
+//=======================================================================
+// name : SMESHGUI_Filter::GetActor
+// Purpose : Get actor of the filter
+//=======================================================================
+SALOME_Actor* SMESHGUI_Filter::GetActor() const
+{
+ return myActor;
+}
+
+//=======================================================================
+// name : SMESHGUI_Filter::SetActor
+// Purpose : Set new actor
+//=======================================================================
+void SMESHGUI_Filter::SetActor( SALOME_Actor* theActor )
+{
+ if ( myActor == theActor )
+ return;
+ VTKViewer_Filter::SetActor( theActor );
+
+ if ( myActor != 0 && !myPred->_is_nil() )
+ {
+ Handle(SALOME_InteractiveObject) anIO = myActor->getIO();
+ if ( !anIO.IsNull() )
+ {
+ Standard_Boolean aRes = false;
+ SMESH::SMESH_Mesh_ptr aMeshPtr = SMESHGUI::GetSMESHGUI()->ConvertIOinMesh( anIO, aRes );
+ if ( aRes )
+ myPred->SetMesh( aMeshPtr );
+ }
+ }
+}
--- /dev/null
+// SMESHGUI_Filter : Filters for VTK viewer
+//
+// Copyright (C) 2003 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
+// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
+//
+// This library 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.
+//
+// This library 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 this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+//
+// See http://www.opencascade.org/SALOME/ or email : webmaster.salome@opencascade.org
+//
+//
+//
+// File : SMESHGUI_Filter.h
+// Author : Sergey LITONIN
+// Module : SMESH
+
+#ifndef SMESHGUI_Filter_HeaderFile
+#define SMESHGUI_Filter_HeaderFile
+
+#include "VTKViewer_Filter.h"\r
+\r
+#include <SALOMEconfig.h>
+#include CORBA_SERVER_HEADER(SMESH_Filter)
+
+class SALOME_Actor;
+
+
+DEFINE_STANDARD_HANDLE(SMESHGUI_Filter, VTKViewer_Filter)
+
+/*
+ Class : SMESHGUI_Filter
+ Description : Selection filter for VTK viewer
+*/
+
+class SMESHGUI_Filter : public VTKViewer_Filter
+{
+
+public:
+ SMESHGUI_Filter();
+ virtual ~SMESHGUI_Filter();
+
+ virtual bool IsValid( const int theCellId ) const;
+
+ virtual void SetActor( SALOME_Actor* );
+ SALOME_Actor* GetActor() const;\r
+\r
+ void SetPredicate( SMESH::Predicate_ptr );
+\r
+private:
+\r
+ SMESH::Predicate_var myPred;
+
+public:
+ DEFINE_STANDARD_RTTI(SMESHGUI_Filter)
+};
+
+#endif
--- /dev/null
+// SMESH SMESHGUI : GUI for SMESH component
+//
+// Copyright (C) 2003 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
+// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
+//
+// This library 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.
+//
+// This library 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 this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+//
+// See http://www.opencascade.org/SALOME/ or email : webmaster.salome@opencascade.org
+//
+//
+//
+// File : SMESHGUI_FilterDlg.cxx
+// Author : Sergey LITONIN
+// Module : SMESH
+
+#include "SMESHGUI.h"
+#include "SMESHGUI_FilterDlg.h"
+#include "SMESHGUI_Filter.h"
+#include "SMESH_Actor.h"
+#include "VTKViewer_InteractorStyleSALOME.h"
+#include "VTKViewer_ViewFrame.h"
+#include "QAD_RightFrame.h"
+#include "SALOME_ListIteratorOfListIO.hxx"
+#include "SALOMEGUI_QtCatchCorbaException.hxx"
+
+
+#include <TColStd_MapOfInteger.hxx>
+
+#include <qframe.h>
+#include <qlayout.h>
+#include <qlineedit.h>
+#include <qpushbutton.h>
+#include <qgroupbox.h>
+#include <qtable.h>
+#include <qstringlist.h>
+#include <qlayout.h>
+#include <qwidgetstack.h>
+#include <qapplication.h>
+#include <qcombobox.h>
+#include <qfontmetrics.h>
+#include <qmessagebox.h>
+#include <qlabel.h>
+#include <qbuttongroup.h>
+#include <qradiobutton.h>
+#include <qregexp.h>
+#include <qlistbox.h>
+#include <qcheckbox.h>
+
+#define SPACING 5
+#define MARGIN 10
+
+static int maxLength( const QStringList& theList, const QFontMetrics& theMetrics )
+{
+ int aRes = 0;
+ QStringList::const_iterator anIter;
+ for ( anIter = theList.begin(); anIter != theList.end(); ++anIter )
+ aRes = Max( aRes, theMetrics.width( *anIter ) );
+ return aRes;
+}
+
+/*
+ Class : SMESHGUI_FilterDlg::Table
+ Description : Table used by this dialog
+*/
+
+class SMESHGUI_FilterDlg::Table : public QTable
+{
+public:
+ Table( QWidget* parent = 0 );
+ Table( int numRows, int numCols, QWidget* parent = 0 );
+ virtual ~Table();
+
+ void SetEditable( const bool state, const int row, const int col );
+ bool IsEditable( const int row, const int col ) const;
+
+ virtual bool eventFilter( QObject *o, QEvent *e );
+ virtual void insertRows( int row, int count = 1 );
+ virtual QString text( int row, int col ) const;
+};
+
+SMESHGUI_FilterDlg::Table::Table( QWidget* parent )
+: QTable( parent, "SMESHGUI_FilterDlg::Table" )
+{
+}
+
+SMESHGUI_FilterDlg::Table::Table( int numRows, int numCols, QWidget* parent )
+: QTable( numRows, numCols, parent, "SMESHGUI_FilterDlg::Table" )
+{
+}
+
+SMESHGUI_FilterDlg::Table::~Table()
+{
+}
+
+void SMESHGUI_FilterDlg::Table::SetEditable( const bool isEditable, const int row, const int col )
+{
+ QTableItem* anItem = item( row, col );
+ if( anItem )
+ takeItem( anItem );
+
+ if ( !isEditable )
+ {
+ setItem( row, col, new QTableItem( this, QTableItem::Never, "" ) );
+ }
+ else
+ {
+ setItem( row, col, new QTableItem( this, QTableItem::OnTyping, "" ) );
+ }
+}
+
+bool SMESHGUI_FilterDlg::Table::IsEditable( const int row, const int col ) const
+{
+ QTableItem* anItem = item( row, col );
+ return anItem == 0 || anItem->editType() != QTableItem::Never;
+}
+
+void SMESHGUI_FilterDlg::Table::insertRows( int row, int count )
+{
+ int anEditRow = currEditRow();
+ int anEditCol = currEditCol();
+
+// printf( "sln: anEditRow = %d, anEditCol = %d\n", anEditRow, anEditCol );
+
+ if ( anEditRow >= 0 && anEditCol >= 0 )
+ endEdit( anEditRow, anEditCol, true, false );
+
+ QTable::insertRows( row, count );
+}
+
+QString SMESHGUI_FilterDlg::Table::text( int row, int col ) const
+{
+ int anEditRow = currEditRow();
+ int anEditCol = currEditCol();
+
+ if ( anEditRow >= 0 && anEditCol >= 0 && anEditRow == row && anEditCol == col )
+ ((Table*)this)->endEdit( row, col, true, false );
+
+ return QTable::text( row, col );
+}
+
+bool SMESHGUI_FilterDlg::Table::eventFilter( QObject *o, QEvent *e )
+{
+ return QTable::eventFilter( o, e );
+}
+
+/*
+ Class : SMESHGUI_FilterDlg
+ Description : Dialog to specify filters for VTK viewer
+*/
+
+
+//=======================================================================
+// name : SMESHGUI_FilterDlg::SMESHGUI_FilterDlg
+// Purpose : Constructor
+//=======================================================================
+SMESHGUI_FilterDlg::SMESHGUI_FilterDlg( QWidget* theParent,
+ const int theType,
+ const bool theModal,
+ const char* theName )
+: QDialog( theParent, theName, theModal,
+ WStyle_Customize | WStyle_NormalBorder | WStyle_Title | WStyle_SysMenu )
+{
+ myType = theType;
+
+ setCaption( tr( "CAPTION" ) );
+
+ QVBoxLayout* aDlgLay = new QVBoxLayout( this, MARGIN, SPACING );
+
+ myMainFrame = createMainFrame ( this );
+ QFrame* aBtnFrame = createButtonFrame( this, theModal );
+
+ aDlgLay->addWidget( myMainFrame );
+ aDlgLay->addWidget( aBtnFrame );
+
+ aDlgLay->setStretchFactor( myMainFrame, 1 );
+
+ Init( myType );
+}
+
+
+//=======================================================================
+// name : SMESHGUI_FilterDlg::createMainFrame
+// Purpose : Create frame containing dialog's input fields
+//=======================================================================
+QFrame* SMESHGUI_FilterDlg::createMainFrame( QWidget* theParent )
+{
+ QGroupBox* aMainFrame = new QGroupBox( 1, Qt::Horizontal, theParent );
+ aMainFrame->setFrameStyle( QFrame::NoFrame );
+ aMainFrame->setInsideMargin( 0 );
+
+ // filter frame
+
+ QGroupBox* aFilterGrp = new QGroupBox( 1, Qt::Horizontal, tr ( "Filter" ), aMainFrame );
+ QFrame* aFilterFrame = new QFrame( aFilterGrp );
+
+ myTableGrp = new QGroupBox( 1, Qt::Horizontal, aFilterFrame );
+ myTableGrp->setFrameStyle( QFrame::NoFrame );
+ myTableGrp->setInsideMargin( 0 );
+
+ myTables[ myType ] = createTable( myTableGrp, myType );
+ myAddBtn = new QPushButton( tr( "ADD" ), aFilterFrame );
+ myRemoveBtn = new QPushButton( tr( "REMOVE" ), aFilterFrame );
+ myClearBtn = new QPushButton( tr( "CLEAR" ), aFilterFrame );
+
+ QGridLayout* aLay = new QGridLayout( aFilterFrame, 4, 2, 0, SPACING );
+
+ aLay->addMultiCellWidget( myTableGrp, 0, 3, 0, 0 );
+ aLay->addWidget( myAddBtn, 0, 1 );
+ aLay->addWidget( myRemoveBtn, 1, 1 );
+ aLay->addWidget( myClearBtn, 2, 1 );
+ aLay->setColStretch( 0, 1 );
+ aLay->setColStretch( 1, 0 );
+
+ mySetInViewer = new QCheckBox( tr( "SET_IN_VIEWER" ), aFilterGrp );
+ mySetInViewer->setChecked( true );
+
+ QSpacerItem* aVSpacer = new QSpacerItem( 0, 0, QSizePolicy::Minimum, QSizePolicy::Expanding );
+ aLay->addItem( aVSpacer, 3, 1 );
+
+ // other controls
+ mySourceGrp = createSourceGroup( aMainFrame );
+
+ // signals and slots
+ connect( myAddBtn, SIGNAL( clicked() ), this, SLOT( onAddBtn() ) );
+ connect( myRemoveBtn, SIGNAL( clicked() ), this, SLOT( onRemoveBtn() ) );
+ connect( myClearBtn, SIGNAL( clicked() ), this, SLOT( onClearBtn() ) );
+
+ return aMainFrame;
+}
+
+//=======================================================================
+// name : SMESHGUI_FilterDlg::createSourceFrame
+// Purpose : Create frame containing source radio button
+//=======================================================================
+QButtonGroup* SMESHGUI_FilterDlg::createSourceGroup( QWidget* theParent )
+{
+ QButtonGroup* aGrp = new QButtonGroup( 1, Qt::Vertical, tr( "SOURCE" ), theParent );
+
+ QRadioButton* aMeshBtn = new QRadioButton( tr( "MESH" ), aGrp );
+ QRadioButton* aSelBtn = new QRadioButton( tr( "SELECTION" ), aGrp );
+ QRadioButton* aGrpBtn = new QRadioButton( tr( "CURRENT_GROUP" ), aGrp );
+// QRadioButton* aNoneBtn = new QRadioButton( tr( "NONE" ), aGrp );
+
+ aGrp->insert( aMeshBtn, Mesh );
+ aGrp->insert( aSelBtn, Selection );
+ aGrp->insert( aGrpBtn, Dialog );
+// aGrp->insert( aNoneBtn, None );
+
+ aGrp->setButton( Selection );
+
+ return aGrp;
+}
+
+//=======================================================================
+// name : SMESHGUI_FilterDlg::createTable
+// Purpose : Create table
+//=======================================================================
+SMESHGUI_FilterDlg::Table* SMESHGUI_FilterDlg::createTable( QWidget* theParent,
+ const int theType )
+{
+ // create table
+ Table* aTable= new Table( 0, 5, theParent );
+
+ QHeader* aHeaders = aTable->horizontalHeader();
+
+ QFontMetrics aMetrics( aHeaders->font() );
+
+ int aLenCr = abs( maxLength( getCriteria( theType ), aMetrics ) -
+ aMetrics.width( tr( "CRITERION" ) ) ) / aMetrics.width( ' ' ) + 5;
+
+ int aLenCo = abs( maxLength( getCriteria( theType ), aMetrics ) -
+ aMetrics.width( tr( "COMPARE" ) ) ) / aMetrics.width( ' ' ) + 5;
+
+ QString aCrStr;
+ aCrStr.fill( ' ', aLenCr );
+ QString aCoStr;
+ aCoStr.fill( ' ', 10 );
+
+ aHeaders->setLabel( 0, tr( "CRITERION" ) + aCrStr );
+ aHeaders->setLabel( 1, tr( "COMPARE" ) + aCoStr );
+ aHeaders->setLabel( 2, tr( "THRESHOLD_VALUE" ) );
+ aHeaders->setLabel( 3, tr( "UNARY" ) );
+ aHeaders->setLabel( 4, tr( "BINARY" ) + " " );
+
+ // set geometry of the table
+
+ for ( int i = 0; i <= 4; i++ )
+ aTable->adjustColumn( i );
+
+ aTable->updateGeometry();
+ QSize aSize = aTable->sizeHint();
+ int aWidth = aSize.width();
+ aTable->setMinimumSize( QSize( aWidth, aWidth / 2 ) );
+ aTable->setSizePolicy( QSizePolicy( QSizePolicy::MinimumExpanding, QSizePolicy::MinimumExpanding) );
+
+ if ( theType == SMESH::EDGE )
+ connect( aTable, SIGNAL( valueChanged( int, int ) ),
+ this, SLOT( onCriterionChanged( int, int ) ) );
+
+ return aTable;
+}
+
+//=======================================================================
+// name : SMESHGUI_FilterDlg::createButtonFrame
+// Purpose : Create frame containing buttons
+//=======================================================================
+QFrame* SMESHGUI_FilterDlg::createButtonFrame( QWidget* theParent, const bool theModal )
+{
+ QGroupBox* aGrp = new QGroupBox( 1, Qt::Vertical, theParent );
+
+ myOkBtn = new QPushButton( tr( "SMESH_BUT_OK" ), aGrp );
+ myApplyBtn = new QPushButton( tr( "SMESH_BUT_APPLY" ), aGrp );
+ QLabel* aLbl = new QLabel( aGrp );
+ myCloseBtn = new QPushButton( tr( "SMESH_BUT_CANCEL" ), aGrp );
+
+ aLbl->setSizePolicy( QSizePolicy( QSizePolicy::Expanding, QSizePolicy::Fixed ) );
+
+ connect( myOkBtn, SIGNAL( clicked() ), SLOT( onOk() ) );
+ connect( myCloseBtn, SIGNAL( clicked() ), SLOT( onClose() ) ) ;
+ connect( myApplyBtn, SIGNAL( clicked() ), SLOT( onApply() ) );
+
+ if ( theModal )
+ myApplyBtn->hide();
+
+ return aGrp;
+}
+
+//=======================================================================
+// name : SMESHGUI_FilterDlg::~SMESHGUI_FilterDlg
+// Purpose : Destructor
+//=======================================================================
+SMESHGUI_FilterDlg::~SMESHGUI_FilterDlg()
+{
+}
+
+//=======================================================================
+// name : SMESHGUI_FilterDlg::Init
+// Purpose : Init dialog fields, connect signals and slots, show dialog
+//=======================================================================
+void SMESHGUI_FilterDlg::Init( const int theType )
+{
+ mySourceWg = 0;
+ mySelection = 0;
+ myType = theType;
+ myMesh = SMESH::SMESH_Mesh::_nil();
+
+ // activate corresponding tab
+ if ( !myTables.contains( myType ) )
+ myTables[ myType ] = createTable( myTableGrp, myType );
+
+ TableMap::iterator anIter;
+ for ( anIter = myTables.begin(); anIter != myTables.end(); ++anIter )
+ if ( anIter.key() == theType )
+ anIter.data()->show();
+ else
+ anIter.data()->hide();
+
+ // set caption
+ setCaption( myType == SMESH::EDGE ? tr( "EDGES_TLT" ) : tr( "FACES_TLT" ) );
+
+ qApp->processEvents();
+ updateGeometry();
+ adjustSize();
+ setEnabled( true );
+
+ mySMESHGUI = SMESHGUI::GetSMESHGUI() ;
+ mySMESHGUI->SetActiveDialogBox( ( QDialog* )this ) ;
+
+ connect( mySMESHGUI, SIGNAL( SignalDeactivateActiveDialog() ), SLOT( onDeactivate() ) );
+ connect( mySMESHGUI, SIGNAL( SignalCloseAllDialogs() ), SLOT( onClose() ) );
+
+ int x, y ;
+ mySMESHGUI->DefineDlgPosition( this, x, y );
+ this->move( x, y );
+
+ this->show();
+
+ return;
+}
+
+//=======================================================================
+// name : SMESHGUI_FilterDlg::onOk
+// Purpose : SLOT called when "Ok" button pressed.
+// Assign filters VTK viewer and close dialog
+//=======================================================================
+void SMESHGUI_FilterDlg::onOk()
+{
+ if ( onApply() )
+ {
+ disconnect( mySMESHGUI, 0, this, 0 );
+ mySMESHGUI->ResetState() ;
+ accept();
+ }
+
+}
+
+//=======================================================================
+// name : SMESHGUI_FilterDlg::onClose
+// Purpose : SLOT called when "Close" button pressed. Close dialog
+//=======================================================================
+void SMESHGUI_FilterDlg::onClose()
+{
+ disconnect( mySMESHGUI, 0, this, 0 );
+ mySMESHGUI->ResetState() ;
+ reject() ;
+ return ;
+}
+
+//=======================================================================
+// name : SMESHGUI_FilterDlg::onDeactivate
+// Purpose : SLOT called when dialog must be deativated
+//=======================================================================
+void SMESHGUI_FilterDlg::onDeactivate()
+{
+ setEnabled( false );
+}
+
+//=======================================================================
+// name : SMESHGUI_FilterDlg::enterEvent
+// Purpose : Event filter
+//=======================================================================
+void SMESHGUI_FilterDlg::enterEvent( QEvent* )
+{
+// mySMESHGUI->EmitSignalDeactivateDialog();
+ setEnabled( true );
+}
+
+
+//=================================================================================
+// function : closeEvent()
+// purpose :
+//=================================================================================
+void SMESHGUI_FilterDlg::closeEvent( QCloseEvent* e )
+{
+ onClose() ;
+}
+
+//=======================================================================
+// name : SMESHGUI_FilterDlg::getCriteria
+// Purpose : Retrieve list of ids from given widget
+//=======================================================================
+void SMESHGUI_FilterDlg::getIdsFromWg( const QWidget* theWg, QValueList<int>& theRes ) const
+{
+ theRes.clear();
+ if ( theWg == 0 )
+ return;
+
+ if ( theWg->inherits( "QListBox" ) )
+ {
+ QListBox* aListBox = ( QListBox* )theWg;
+ bool b;
+ for ( int i = 0, n = aListBox->count(); i < n; i++ )
+ {
+ int anId = aListBox->text( i ).toInt( &b );
+ if ( b )
+ theRes.append( anId );
+ }
+ }
+ else if ( theWg->inherits( "QLineEdit" ) )
+ {
+ QLineEdit* aLineEdit = ( QLineEdit* )theWg;
+ QString aStr = aLineEdit->text();
+ QRegExp aRegExp( "(\\d+)" );
+ bool b;
+ int aPos = 0;
+ while ( aPos >= 0 )
+ {
+ aPos = aRegExp.search( aStr, aPos );
+ if ( aPos > -1 )
+ {
+ int anId = aRegExp.cap( 1 ).toInt( &b );
+ if ( b )
+ theRes.append( anId );
+ aPos += aRegExp.matchedLength();
+ }
+ }
+ }
+}
+
+//=======================================================================
+// name : SMESHGUI_FilterDlg::getSelMode
+// Purpose : Get criteria for specified type
+//=======================================================================
+Selection_Mode SMESHGUI_FilterDlg::getSelMode( const int theType ) const
+{
+ switch ( theType )
+ {
+ case SMESH::NODE : return NodeSelection;
+ case SMESH::EDGE : return EdgeSelection;
+ case SMESH::FACE : return FaceSelection;
+ case SMESH::VOLUME : return VolumeSelection;
+ default : return ActorSelection;
+ }
+
+}
+
+//=======================================================================
+// name : SMESHGUI_FilterDlg::getCriteria
+// Purpose : Get criteria for specified type
+//=======================================================================
+void SMESHGUI_FilterDlg::setIdsToWg( QWidget* theWg, const QValueList<int>& theIds )
+{
+ if ( theWg == 0 )
+ return;
+
+ if ( theWg->inherits( "QListBox" ) )
+ {
+ QListBox* aListBox = ( QListBox* )theWg;
+ aListBox->clear();
+
+ QStringList aStrList;
+ QValueList<int>::const_iterator anIter;
+ for ( anIter = theIds.begin(); anIter != theIds.end(); ++anIter )
+ aStrList.append( QString( "%1" ).arg( *anIter ) );
+
+ aListBox->insertStringList( aStrList );
+ }
+ else if ( theWg->inherits( "QLineEdit" ) )
+ {
+ QLineEdit* aLineEdit = ( QLineEdit* )theWg;
+ QString aStr;
+ QValueList<int>::const_iterator anIter;
+
+ for ( anIter = theIds.begin(); anIter != theIds.end(); ++ anIter )
+ aStr += QString( "%1 " ).arg( *anIter );
+
+ if ( !aStr.isEmpty() )
+ aStr.remove( aStr.length() - 1, 1 );
+
+ aLineEdit->setText( aStr );
+ }
+}
+
+//=======================================================================
+// name : SMESHGUI_FilterDlg::getCriteria
+// Purpose : Get criteria for specified type
+//=======================================================================
+const QStringList& SMESHGUI_FilterDlg::getCriteria( const int theType ) const
+{
+ if ( theType == SMESH::EDGE )
+ {
+ static QStringList aCriteria;
+ if ( aCriteria.isEmpty() )
+ {
+ aCriteria.append( tr( "FREE_BORDERS" ) );
+ aCriteria.append( tr( "MULTI_BORDERS" ) );
+ aCriteria.append( tr( "LENGTH" ) );
+ }
+ return aCriteria;
+ }
+ else if ( theType == SMESH::FACE )
+ {
+ static QStringList aCriteria;
+ if ( aCriteria.isEmpty() )
+ {
+ aCriteria.append( tr( "ASPECT_RATIO" ) );
+ aCriteria.append( tr( "WARPING" ) );
+ aCriteria.append( tr( "MINIMUM_ANGLE" ) );
+ aCriteria.append( tr( "TAPER" ) );
+ aCriteria.append( tr( "SKEW" ) );
+ aCriteria.append( tr( "AREA" ) );
+ }
+ return aCriteria;
+ }
+ else
+ {
+ static QStringList aCriteria;
+ return aCriteria;
+ }
+}
+
+//=======================================================================
+// name : SMESHGUI_FilterDlg::getCompare
+// Purpose : Get operation of comparison
+//=======================================================================
+const QStringList& SMESHGUI_FilterDlg::getCompare () const
+{
+ static QStringList aList;
+
+ if ( aList.isEmpty() )
+ {
+ aList.append( tr( "LESS_THAN" ) );
+ aList.append( tr( "MORE_THAN" ) );
+ aList.append( tr( "EQUAL_TO" ) );
+ }
+
+ return aList;
+}
+
+//=======================================================================
+// name : SMESHGUI_FilterDlg::getCriterionItem
+// Purpose : Get combo table item for criteria of specified type
+//=======================================================================
+QTableItem* SMESHGUI_FilterDlg::getCriterionItem( QTable* theParent , const int theType )
+{
+ return new QComboTableItem( theParent, getCriteria( theType ) );
+}
+
+//=======================================================================
+// name : SMESHGUI_FilterDlg::getCompareItem
+// Purpose : Get combo table item for operation of comparision
+//=======================================================================
+QTableItem* SMESHGUI_FilterDlg::getCompareItem( QTable* theParent )
+{
+ return new QComboTableItem( theParent, getCompare() );
+}
+
+//=======================================================================
+// name : SMESHGUI_FilterDlg::getLogOpItem
+// Purpose :
+//=======================================================================
+QTableItem* SMESHGUI_FilterDlg::getLogOpItem( QTable* theParent )
+{
+ static QStringList aList;
+ if ( aList.isEmpty() )
+ {
+ aList.append( tr( "AND" ) );
+ aList.append( tr( "OR" ) );
+ }
+
+ return new QComboTableItem( theParent, aList );
+}
+
+//=======================================================================
+// name : SMESHGUI_FilterDlg::getNotItem
+// Purpose : Get check table item
+//=======================================================================
+QTableItem* SMESHGUI_FilterDlg::getNotItem( QTable* theParent )
+{
+ return new QCheckTableItem( theParent, tr( "NOT" ) );
+}
+
+//=======================================================================
+// name : SMESHGUI_FilterDlg::getCurrType
+// Purpose : Get current entity type
+//=======================================================================
+int SMESHGUI_FilterDlg::getCurrType() const
+{
+ return myType;
+}
+
+//=======================================================================
+// name : SMESHGUI_FilterDlg::getCriterion
+// Purpose :
+//=======================================================================
+int SMESHGUI_FilterDlg::getCriterion( const int theType, const int theRow ) const
+{
+ QComboTableItem* anItem = ( QComboTableItem* )myTables[ getCurrType() ]->item( theRow, 0 );
+ return anItem->currentItem();
+}
+
+//=======================================================================
+// name : SMESHGUI_FilterDlg::addRow
+// Purpose :
+//=======================================================================
+void SMESHGUI_FilterDlg::addRow( Table* theTable, const int theType )
+{
+ theTable->insertRows( theTable->numRows() );
+ int aCurrRow = theTable->numRows() - 1;
+
+ // Criteria
+ theTable->setItem( aCurrRow, 0, getCriterionItem( theTable, theType ) );
+
+ // Compare
+ theTable->setItem( aCurrRow, 1, getCompareItem( theTable ) );
+
+ //Logical operation NOT
+ theTable->setItem( aCurrRow, 3, getNotItem( theTable ) );
+
+ // Logical binary operation for previous value
+ if ( aCurrRow > 0 )
+ theTable->setItem( aCurrRow - 1, 4, getLogOpItem( theTable ) );
+ theTable->SetEditable( false, aCurrRow, 4 );
+
+ onCriterionChanged( aCurrRow, 0 );
+}
+
+//=======================================================================
+// name : SMESHGUI_FilterDlg::onAddBtn
+// Purpose : SLOT. Called then "Add" button pressed.
+// Adds new string to table
+//=======================================================================
+void SMESHGUI_FilterDlg::onAddBtn()
+{
+ // QTable
+ int aType = getCurrType();
+ Table* aTable = myTables[ aType ];
+
+ addRow( aTable, aType );
+
+ updateBtnState();
+
+}
+
+//=======================================================================
+// name : SMESHGUI_FilterDlg::onCriterionChanged()
+// Purpose : SLOT. Called then contents of table changed
+// Provides reaction on change of criterion
+//=======================================================================
+void SMESHGUI_FilterDlg::onCriterionChanged( int row, int col )
+{
+ int aType = getCurrType();
+ if ( aType != SMESH::EDGE || col != 0 )
+ return;
+
+ Table* aTable = myTables[ aType ];
+ QComboTableItem* aCompareItem = (QComboTableItem*)aTable->item( row, 1 );
+
+ if ( getCriterion( aType, row ) != FreeBorders )
+ {
+ if ( aCompareItem->count() == 0 )
+ aCompareItem->setStringList( getCompare() );
+
+ QString aText = aTable->text( row, 2 );
+ aTable->SetEditable( true, row, 2 );
+ aTable->setText( row, 2, aText );
+ }
+ else
+ {
+ if ( aCompareItem->count() > 0 )
+ aCompareItem->setStringList( QStringList() );
+ aTable->SetEditable( false, row, 2 );
+ }
+}
+
+//=======================================================================
+// name : SMESHGUI_FilterDlg::onRemoveBtn
+// Purpose : SLOT. Called then "Remove" button pressed.
+// Removes current string from table
+//=======================================================================
+void SMESHGUI_FilterDlg::onRemoveBtn()
+{
+ Table* aTable = myTables[ getCurrType() ];
+
+ if ( aTable->numRows() == 0 )
+ return;
+
+ QMemArray<int> aRows;
+ for ( int i = 0, n = aTable->numRows(); i < n; i++ )
+ {
+ if ( aTable->isRowSelected( i ) )
+ {
+ aRows.resize( aRows.size() + 1 );
+ aRows[ aRows.size() - 1 ] = i;
+ }
+ }
+
+ aTable->removeRows( aRows );
+
+ // remove control of binary logical operation from last row
+ if ( aTable->numRows() > 0 )
+ aTable->SetEditable( false, aTable->numRows() - 1, 4 );
+
+ updateBtnState();
+}
+
+//=======================================================================
+// name : SMESHGUI_FilterDlg::onClearBtn
+// Purpose : SLOT. Called then "Clear" button pressed.
+// Removes all strings from table
+//=======================================================================
+void SMESHGUI_FilterDlg::onClearBtn()
+{
+ QTable* aTable = myTables[ getCurrType() ];
+
+ if ( aTable->numRows() == 0 )
+ return;
+
+ while ( aTable->numRows() > 0 )
+ aTable->removeRow( 0 );
+
+ updateBtnState();
+}
+
+//=======================================================================
+// name : SMESHGUI_FilterDlg::updateBtnState
+// Purpose : Update button state
+//=======================================================================
+void SMESHGUI_FilterDlg::updateBtnState()
+{
+ myRemoveBtn->setEnabled( myTables[ getCurrType() ]->numRows() > 0 );
+ myClearBtn->setEnabled( myTables[ getCurrType() ]->numRows() > 0 );
+}
+
+//=======================================================================
+// name : SMESHGUI_FilterDlg::isValid
+// Purpose : Verify validity of input data
+//=======================================================================
+bool SMESHGUI_FilterDlg::isValid() const
+{
+ Table* aTable = myTables[ getCurrType() ];
+ for ( int i = 0, n = aTable->numRows(); i < n; i++ )
+ {
+ bool isEditable = aTable->IsEditable( i ,2 );
+ bool aRes = false;
+ int aThreshold = ( int )aTable->text( i, 2 ).toDouble( &aRes );
+ if ( isEditable && !aRes )
+ {
+ QMessageBox::information( mySMESHGUI->GetDesktop(),
+ tr( "SMESH_INSUFFICIENT_DATA" ), tr( "ERROR" ),
+ QMessageBox::Ok );
+ return false;
+ }
+ else if ( getCurrType() == SMESH::EDGE &&
+ getCriterion( SMESH::EDGE, i ) == MultiBorders &&
+ aThreshold == 1 )
+ {
+ QMessageBox::information( mySMESHGUI->GetDesktop(),
+ tr( "SMESH_INSUFFICIENT_DATA" ), tr( "MULTIEDGES_ERROR" ),
+ QMessageBox::Ok );
+ return false;
+ }
+ }
+
+ return true;
+}
+
+//=======================================================================
+// name : SMESHGUI_FilterDlg::GetResultIds
+// Purpose : Get filtered ids
+//=======================================================================
+/*void SMESHGUI_FilterDlg::GetResultIds( SMESH::SMESH_Mesh_ptr theMesh,
+ QValueList<int>& theIds ) const
+{
+ if ( !myPredicate->_is_nil() )
+ theIds = myInputIds;
+ else
+ myPredicate->SetMesh( theMesh );
+
+ theIds.clear();
+ QValueList<int>::const_iterator anIter;
+ for ( anIter = myInputIds.begin(); anIter != myInputIds.end(); ++anIter )
+ if ( myPredicate->IsSatisfy( *anIter ) )
+ theIds.append( *anIter );
+}
+*/
+
+//=======================================================================
+// name : SMESHGUI_FilterDlg::SetSourceWg
+// Purpose : Set widget of parent dialog containing idsto be filtered if
+// user select corresponding source radio button
+//=======================================================================
+void SMESHGUI_FilterDlg::SetSourceWg( QWidget* theWg )
+{
+ mySourceWg = theWg;
+}
+
+//=======================================================================
+// name : SMESHGUI_FilterDlg::SetGroupIds
+// Purpose : Set mesh
+//=======================================================================
+void SMESHGUI_FilterDlg::SetMesh( SMESH::SMESH_Mesh_ptr theMesh )
+{
+ myMesh = theMesh;
+}
+
+//=======================================================================
+// name : SMESHGUI_FilterDlg::SetSelection
+// Purpose : Get filtered ids
+//=======================================================================
+void SMESHGUI_FilterDlg::SetSelection( SALOME_Selection* theSel )
+{
+ mySelection = theSel;
+}
+
+//=======================================================================
+// name : SMESHGUI_FilterDlg::onApply
+// Purpose : SLOT called when "Apply" button pressed.
+// Assign filters to VTK viewer
+//=======================================================================
+bool SMESHGUI_FilterDlg::onApply()
+{
+ if ( !isValid() )
+ return false;
+
+ try
+ {
+ int aCurrType = getCurrType();
+
+ SMESH::Predicate_ptr aPredicate = createPredicate( aCurrType );
+
+ if ( mySetInViewer->isChecked() )
+ insertFilterInViewer( aPredicate );
+
+ if ( !aPredicate->_is_nil() )
+ {
+ QValueList<int> aResultIds;
+ filterSource( aCurrType, aPredicate, aResultIds );
+ selectInViewer( aCurrType, aResultIds );
+ }
+ }
+ catch( const SALOME::SALOME_Exception& S_ex )
+ {
+ QtCatchCorbaException( S_ex );
+ }
+ catch( ... )
+ {
+ }
+
+ return true;
+}
+
+//=======================================================================
+// name : SMESHGUI_FilterDlg::createPredicate
+// Purpose : Create predicate for given type
+//=======================================================================
+SMESH::Predicate_ptr SMESHGUI_FilterDlg::createPredicate( const int theType )
+{
+ SMESH::FilterManager_ptr aFilterMgr = mySMESHGUI->GetFilterMgr();
+ if ( aFilterMgr->_is_nil() )
+ return SMESH::Predicate::_nil();
+
+ QTable* aTable = myTables[ theType ];
+ if ( aTable == 0 )
+ return SMESH::Predicate::_nil();
+
+ // CREATE two lists ( PREDICATES and LOG OP )
+
+ // Criterion
+ QValueList<SMESH::Predicate_ptr> aPredicates;
+ QValueList<int> aLogOps;
+ for ( int i = 0, n = aTable->numRows(); i < n; i++ )
+ {
+ int aCriterion = getCriterion( theType, i );
+
+ SMESH::Predicate_ptr aPredicate = SMESH::Predicate::_nil();
+ SMESH::NumericalFunctor_ptr aFunctor = SMESH::NumericalFunctor::_nil();
+
+ if ( theType == SMESH::EDGE )
+ {
+ switch ( aCriterion )
+ {
+ case FreeBorders:
+ aPredicate = aFilterMgr->CreateFreeBorders();
+ break;
+ case MultiBorders:
+ aFunctor = aFilterMgr->CreateMultiConnection();
+ break;
+ case Length:
+ aFunctor = aFilterMgr->CreateLength();
+ break;
+ default:
+ continue;
+ }
+ }
+ else
+ {
+ switch ( aCriterion )
+ {
+ case AspectRatio:
+ aFunctor = aFilterMgr->CreateAspectRatio();
+ break;
+ case Warping:
+ aFunctor = aFilterMgr->CreateWarping();
+ break;
+ case MinimumAngle:
+ aFunctor = aFilterMgr->CreateMinimumAngle();
+ break;
+ case Taper:
+ aFunctor = aFilterMgr->CreateTaper();
+ break;
+ case Skew:
+ aFunctor = aFilterMgr->CreateSkew();
+ break;
+ case Area:
+ aFunctor = aFilterMgr->CreateArea();
+ break;
+ default:
+ continue;
+ }
+ }
+
+ // Comparator
+ if ( !aFunctor->_is_nil() && aPredicate->_is_nil() )
+ {
+ QComboTableItem* aCombo = (QComboTableItem*)aTable->item( i, 1 );
+ int aCompareOp = aCombo->currentItem();
+ double aThreshold = aTable->text( i, 2 ).toDouble();
+
+ SMESH::Comparator_ptr aComparator = SMESH::Comparator::_nil();
+
+ if ( aCompareOp == LessThan )
+ aComparator = aFilterMgr->CreateLessThan();
+ else if ( aCompareOp == MoreThan )
+ aComparator = aFilterMgr->CreateMoreThan();
+ else if ( aCompareOp == EqualTo )
+ aComparator = aFilterMgr->CreateEqualTo();
+ else
+ continue;
+
+ aComparator->SetNumFunctor( aFunctor );
+ aComparator->SetMargin( aThreshold );
+
+ aPredicate = aComparator;
+ }
+
+ // Logical not
+ QCheckTableItem* anItem = (QCheckTableItem*)aTable->item( i, 3 );
+ if ( anItem->isChecked() )
+ {
+ SMESH::LogicalNOT_ptr aNotPred = aFilterMgr->CreateLogicalNOT();
+ aNotPred->SetPredicate( aPredicate );
+ aPredicate = aNotPred;
+ }
+
+ // logical op
+ int aLogOp = ( i == n - 1 ) ? LO_Undefined
+ : ( (QComboTableItem*)aTable->item( i, 4 ) )->currentItem();
+ aPredicates.append( aPredicate );
+ aLogOps.append( aLogOp );
+
+ } // for
+
+ // CREATE ONE PREDICATE FROM PREVIOUSLY CREATED MAP
+
+ // combine all "AND" operations
+
+ QValueList<SMESH::Predicate_ptr> aResList;
+
+ QValueList<SMESH::Predicate_ptr>::iterator aPredIter;
+ QValueList<int>::iterator aLogOpIter;
+
+ SMESH::Predicate_ptr aPrevPredicate = SMESH::Predicate::_nil();
+ int aPrevLogOp = LO_Undefined;
+
+ for ( aPredIter = aPredicates.begin(), aLogOpIter = aLogOps.begin();
+ aPredIter != aPredicates.end() && aLogOpIter != aLogOps.end();
+ ++aPredIter, ++aLogOpIter )
+ {
+ int aCurrLogOp = *aLogOpIter;
+
+ SMESH::Predicate_ptr aCurrPred = SMESH::Predicate::_nil();
+
+ if ( aPrevLogOp == LO_And )
+ {
+
+ SMESH::LogicalBinary_ptr aBinaryPred = aFilterMgr->CreateLogicalAND();
+ aBinaryPred->SetPredicate1( aPrevPredicate );
+ aBinaryPred->SetPredicate2( *aPredIter );
+ aCurrPred = aBinaryPred;
+ }
+ else
+ aCurrPred = *aPredIter;
+
+ if ( aCurrLogOp != LO_And )
+ aResList.append( aCurrPred );
+
+ aPrevPredicate = aCurrPred;
+ aPrevLogOp = aCurrLogOp;
+ }
+
+ // combine all "OR" operations
+
+ SMESH::Predicate_ptr aResPredicate = SMESH::Predicate::_nil();
+
+ if ( aResList.count() == 1 )
+ aResPredicate = aResList.first();
+ else if ( aResList.count() > 1 )
+ {
+ QValueList<SMESH::Predicate_ptr>::iterator anIter = aResList.begin();
+ aResPredicate = *anIter;
+ anIter++;
+ for ( ; anIter != aResList.end(); ++anIter )
+ {
+ SMESH::LogicalBinary_ptr aBinaryPred = aFilterMgr->CreateLogicalOR();
+ aBinaryPred->SetPredicate1( aResPredicate );
+ aBinaryPred->SetPredicate2( *anIter );
+ aResPredicate = aBinaryPred;
+ }
+ }
+
+ return aResPredicate;
+}
+
+//=======================================================================
+// name : SMESHGUI_FilterDlg::insertFilterInViewer
+// Purpose : Insert filter in viewer
+//=======================================================================
+void SMESHGUI_FilterDlg::insertFilterInViewer( SMESH::Predicate_ptr thePred )
+{
+ VTKViewer_InteractorStyleSALOME* aStyle = ((VTKViewer_ViewFrame*)mySMESHGUI->GetActiveStudy()->
+ getActiveStudyFrame()->getRightFrame()->getViewFrame())->
+ getRWInteractor()->GetInteractorStyleSALOME();
+
+ if ( thePred->_is_nil() )
+ {
+ if ( myType == SMESH::EDGE )
+ aStyle->RemoveEdgeFilter();
+ else if ( myType == SMESH::FACE )
+ aStyle->RemoveFaceFilter();
+ }
+ else
+ {
+ Handle(SMESHGUI_Filter) aFilter = new SMESHGUI_Filter();
+ aFilter->SetPredicate( thePred );
+ if ( myType == SMESH::EDGE )
+ aStyle->SetEdgeFilter( aFilter );
+ else if ( myType == SMESH::FACE )
+ aStyle->SetFaceFilter( aFilter );
+ }
+}
+
+//=======================================================================
+// name : SMESHGUI_FilterDlg::filterSource
+// Purpose : Filter source ids
+//=======================================================================
+void SMESHGUI_FilterDlg::filterSource( const int theType,
+ SMESH::Predicate_ptr thePred,
+ QValueList<int>& theResIds )
+{
+ theResIds.clear();
+
+ int aSourceId = mySourceGrp->id( mySourceGrp->selected() );
+
+ if ( aSourceId == Mesh )
+ {
+ if ( myMesh->_is_nil() )
+ return;
+ SMESH::FilterManager_ptr aFilterMgr = mySMESHGUI->GetFilterMgr();
+ SMESH::Filter_var aFilter = aFilterMgr->CreateFilter();
+ aFilter->SetPredicate( thePred );
+ SMESH::long_array_var anIds = aFilter->GetElementsId( myMesh );
+ for ( int i = 0, n = anIds->length(); i < n; i++ )
+ theResIds.append( anIds[ i ] );
+ }
+ else if ( aSourceId == Selection )
+ {
+ filterSelectionSource( theType, thePred, theResIds );
+ }
+ else if ( aSourceId == Dialog )
+ {
+ // retrieve ids from dialog
+ QValueList<int> aDialogIds;
+ getIdsFromWg( mySourceWg, aDialogIds );
+
+ if ( myMesh->_is_nil() )
+ {
+ theResIds = aDialogIds;
+ return;
+ }
+
+ // filter ids
+ thePred->SetMesh( myMesh );
+ QValueList<int>::const_iterator anIter;
+ for ( anIter = aDialogIds.begin(); anIter != aDialogIds.end(); ++ anIter )
+ if ( thePred->IsSatisfy( *anIter ) )
+ theResIds.append( *anIter );
+
+ // set ids to the dialog
+ setIdsToWg( mySourceWg, theResIds );
+ }
+}
+
+//=======================================================================
+// name : SMESHGUI_FilterDlg::filterSelectionSource
+// Purpose : Filter source selection
+//=======================================================================
+void SMESHGUI_FilterDlg::filterSelectionSource( const int theType,
+ SMESH::Predicate_ptr thePred,
+ QValueList<int>& theResIds )
+{
+ theResIds.clear();
+ if ( myMesh->_is_nil() || mySelection == 0 )
+ return;
+
+ // Create map of entities to be filtered
+ TColStd_MapOfInteger aToBeFiltered;
+ Standard_Boolean aRes = false;
+ SALOME_ListIteratorOfListIO anIter( mySelection->StoredIObjects() );
+
+ for ( ; anIter.More(); anIter.Next() )
+ {
+ // process sub mesh
+ SMESH::SMESH_subMesh_ptr aSubMesh = mySMESHGUI->ConvertIOinSubMesh( anIter.Value(), aRes );
+ if ( aRes && !aSubMesh->_is_nil() )
+ {
+ if ( aSubMesh->GetFather()->GetId() == myMesh->GetId() )
+ {
+ SMESH::long_array_var anIds =
+ theType == SMESH::NODE ? aSubMesh->GetNodesId() : aSubMesh->GetElementsId();
+ for ( int i = 0, n = anIds->length(); i < n; i++ )
+ aToBeFiltered.Add( anIds[ i ] );
+ }
+ }
+
+ // process group
+ SMESH::SMESH_Group_ptr aGroup = mySMESHGUI->ConvertIOinSMESHGroup( anIter.Value(), aRes );
+ if ( aRes && !aGroup->_is_nil() )
+ {
+ if ( aGroup->GetType() == theType && aGroup->GetMesh()->GetId() == myMesh->GetId() )
+ {
+ SMESH::long_array_var anIds = aGroup->GetListOfID();
+ for ( int i = 0, n = anIds->length(); i < n; i++ )
+ aToBeFiltered.Add( anIds[ i ] );
+ }
+ }
+
+ // process mesh
+ SMESH::SMESH_Mesh_ptr aMeshPtr = mySMESHGUI->ConvertIOinMesh( anIter.Value(), aRes );
+ if ( aRes && !aMeshPtr->_is_nil() && aMeshPtr->GetId() == myMesh->GetId() )
+ {
+ TColStd_MapOfInteger aVtkMap;
+ mySelection->GetIndex( anIter.Value(), aVtkMap );
+
+ if ( aVtkMap.Extent() > 0 )
+ {
+ SMESH_Actor *anActor = mySMESHGUI->FindActorByEntry(
+ anIter.Value()->getEntry(), aRes, true );
+ if ( aRes && anActor != 0 )
+ {
+ TColStd_MapIteratorOfMapOfInteger aVtkMapIter( aVtkMap );
+ for ( ; aVtkMapIter.More(); aVtkMapIter.Next() )
+ aToBeFiltered.Add( theType == SMESH::NODE
+ ? anActor->GetNodeObjId( aVtkMapIter.Key() )
+ : anActor->GetElemObjId( aVtkMapIter.Key() ) );
+ }
+ }
+ }
+ }
+
+ // Filter entities
+ thePred->SetMesh( myMesh );
+ TColStd_MapIteratorOfMapOfInteger aResIter( aToBeFiltered );
+ for ( ; aResIter.More(); aResIter.Next() )
+ if ( thePred->IsSatisfy( aResIter.Key() ) )
+ theResIds.append( aResIter.Key() );
+}
+
+//=======================================================================
+// name : SMESHGUI_FilterDlg::selectInViewer
+// Purpose : Select given entities in viewer
+//=======================================================================
+void SMESHGUI_FilterDlg::selectInViewer( const int theType, const QValueList<int>& theIds )
+{
+ if ( mySelection == 0 || myMesh->_is_nil() )
+ return;
+
+ // Set new selection mode if necessary
+ Selection_Mode aSelMode = getSelMode( theType );
+ if ( aSelMode != mySelection->SelectionMode() )
+ {
+ mySelection->ClearIObjects();
+ mySelection->ClearFilters();
+ if ( aSelMode == NodeSelection )
+ mySMESHGUI->ViewNodes();
+ QAD_Application::getDesktop()->SetSelectionMode( aSelMode );
+ }
+
+ Standard_Boolean aRes = false;
+ SMESH_Actor* anActor = mySMESHGUI->FindActor( myMesh, aRes, true );
+ if ( !aRes || anActor == 0 || !anActor->hasIO() )
+ return;
+
+ Handle(SALOME_InteractiveObject) anIO = anActor->getIO();
+ mySelection->ClearIObjects();
+ mySelection->AddIObject( anIO, false );
+
+ TColStd_MapOfInteger aMap;
+ QValueList<int>::const_iterator anIter;
+ for ( anIter = theIds.begin(); anIter != theIds.end(); ++anIter )
+ {
+ std::vector<int> aVtkList = anActor->GetElemVtkId( *anIter );
+ std::vector<int>::iterator it;
+ for ( it = aVtkList.begin(); it != aVtkList.end(); ++it )
+ aMap.Add( *it );
+ }
+
+ mySelection->AddOrRemoveIndex( anIO, aMap, false, true );
+
+}
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
--- /dev/null
+// SMESH SMESHGUI : GUI for SMESH component\r
+//\r
+// Copyright (C) 2003 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,\r
+// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS \r
+// \r
+// This library is free software; you can redistribute it and/or \r
+// modify it under the terms of the GNU Lesser General Public \r
+// License as published by the Free Software Foundation; either \r
+// version 2.1 of the License. \r
+// \r
+// This library is distributed in the hope that it will be useful, \r
+// but WITHOUT ANY WARRANTY; without even the implied warranty of \r
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU \r
+// Lesser General Public License for more details. \r
+// \r
+// You should have received a copy of the GNU Lesser General Public \r
+// License along with this library; if not, write to the Free Software \r
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA \r
+// \r
+// See http://www.opencascade.org/SALOME/ or email : webmaster.salome@opencascade.org \r
+//\r
+//\r
+//\r
+// File : SMESHGUI_FilterDlg.h\r
+// Author : Sergey LITONIN\r
+// Module : SMESH\r
+\r
+\r
+#ifndef SMESHGUI_FilterDlg_H\r
+#define SMESHGUI_FilterDlg_H\r
+\r
+#include <qdialog.h>\r
+#include <qmap.h>\r
+#include <qvaluelist.h>\r
+#include <SALOME_Selection.h>\r
+\r
+#include <SALOMEconfig.h>\r
+#include CORBA_SERVER_HEADER(SMESH_Filter)\r
+#include CORBA_SERVER_HEADER(SMESH_Mesh)\r
+\r
+class QCloseEvent;\r
+class QWidgetStack;\r
+class QStringList;\r
+class QTableItem;\r
+class QFrame;\r
+class QEvent;\r
+class QPushButton;\r
+class QTable;\r
+class SALOME_Selection;\r
+class SMESHGUI;\r
+class QComboBox;\r
+class QButtonGroup;\r
+class QCheckBox;\r
+class QGroupBox;\r
+\r
+\r
+/*\r
+ Class : SMESHGUI_FilterDlg\r
+ Description : Dialog to specify filters for VTK viewer\r
+*/\r
+\r
+class SMESHGUI_FilterDlg : public QDialog\r
+{ \r
+ Q_OBJECT\r
+\r
+ class Table;\r
+\r
+ // Edge criteria\r
+ enum { FreeBorders = 0, MultiBorders, Length }; \r
+\r
+ // Face criteria\r
+ enum { AspectRatio = 0, Warping, MinimumAngle, Taper, Skew, Area }; \r
+\r
+ // Comparision\r
+ enum { LessThan = 0, MoreThan, EqualTo };\r
+\r
+ // Logical operations\r
+ enum { LO_And = 0, LO_Or, LO_Undefined };\r
+\r
+ // Source elements to be selected\r
+ enum { Mesh, Selection, Dialog, None };\r
+\r
+ typedef QMap<int, Table*> TableMap;\r
+\r
+public:\r
+ SMESHGUI_FilterDlg( QWidget* parent, \r
+ const int type,\r
+ const bool theModal = true,\r
+ const char* name = 0 );\r
+ virtual ~SMESHGUI_FilterDlg();\r
+\r
+ void Init( const int type );\r
+\r
+ void SetSelection( SALOME_Selection* );\r
+ void SetMesh( SMESH::SMESH_Mesh_ptr );\r
+ void SetSourceWg( QWidget* );\r
+\r
+private slots:\r
+\r
+ void onAddBtn();\r
+ void onRemoveBtn();\r
+ void onClearBtn();\r
+ void onCriterionChanged( int, int );\r
+\r
+ void onOk();\r
+ bool onApply();\r
+ void onClose();\r
+ void onDeactivate();\r
+\r
+private:\r
+\r
+ void closeEvent( QCloseEvent* e );\r
+ void enterEvent ( QEvent * );\r
+\r
+ void updateBtnState();\r
+\r
+ // dialog creation\r
+ QFrame* createButtonFrame( QWidget*, const bool );\r
+ QFrame* createMainFrame( QWidget* );\r
+ Table* createTable( QWidget*, const int );\r
+ QButtonGroup* createSourceGroup( QWidget* );\r
+ void addRow( Table*, const int );\r
+ QTableItem* getCriterionItem( QTable*, const int );\r
+ QTableItem* getCompareItem( QTable* );\r
+ QTableItem* getNotItem( QTable* );\r
+ QTableItem* getLogOpItem( QTable* );\r
+ const QStringList& getCriteria( const int theType ) const;\r
+ const QStringList& getCompare () const;\r
+ \r
+ // query\r
+ int getCurrType() const;\r
+ int getCriterion( const int theType, const int theRow ) const;\r
+\r
+ // execution\r
+ bool isValid() const;\r
+ SMESH::Predicate_ptr createPredicate( const int theType );\r
+ void insertFilterInViewer( SMESH::Predicate_ptr thePred );\r
+ void selectInViewer( const int theType,\r
+ const QValueList<int>& theIds );\r
+ void filterSource( const int theType,\r
+ SMESH::Predicate_ptr thePred,\r
+ QValueList<int>& theResIds );\r
+ void filterSelectionSource( const int theType,\r
+ SMESH::Predicate_ptr thePred,\r
+ QValueList<int>& theResIds );\r
+ void getIdsFromWg( const QWidget*, QValueList<int>& ) const;\r
+ void setIdsToWg( QWidget*, const QValueList<int>& );\r
+ Selection_Mode getSelMode( const int ) const;\r
+\r
+private:\r
+\r
+ // widgets\r
+ QFrame* myMainFrame;\r
+ QGroupBox* myTableGrp;\r
+\r
+ TableMap myTables;\r
+ QPushButton* myAddBtn;\r
+ QPushButton* myRemoveBtn;\r
+ QPushButton* myClearBtn;\r
+ QButtonGroup* mySourceGrp;\r
+ QCheckBox* mySetInViewer;\r
+\r
+ QPushButton* myOkBtn;\r
+ QPushButton* myApplyBtn;\r
+ QPushButton* myCloseBtn;\r
+\r
+ // initial fields\r
+ int myType;\r
+ SMESHGUI* mySMESHGUI;\r
+ SALOME_Selection* mySelection;\r
+ SMESH::SMESH_Mesh_ptr myMesh;\r
+ QWidget* mySourceWg;\r
+};\r
+\r
+#endif\r
+\r
+\r
+\r
+\r
+\r
+\r
+\r
+\r
+\r
+\r
+\r
+\r
+\r
+\r
+\r
+\r
+\r
+\r
+\r
+\r
--- /dev/null
+// SMESH SMESHGUI : GUI for SMESH component
+//
+// Copyright (C) 2003 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
+// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
+//
+// This library 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.
+//
+// This library 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 this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+//
+// See http://www.salome-platform.org or email : webmaster.salome@opencascade.org
+//
+//
+//
+// File : SMESHGUI_GroupDlg.cxx
+// Author : Natalia KOPNOVA
+// Module : SMESH
+// $Header$
+
+using namespace std;
+#include "SMESHGUI_GroupDlg.h"
+#include "SMESHGUI_FilterDlg.h"
+
+#include "SMESHGUI.h"
+#include "SALOMEGUI_QtCatchCorbaException.hxx"
+#include "SALOME_ListIteratorOfListIO.hxx"
+#include "VTKViewer_InteractorStyleSALOME.h"
+#include "VTKViewer_ViewFrame.h"
+#include "QAD_Application.h"
+#include "QAD_Desktop.h"
+#include "QAD_MessageBox.h"
+#include "QAD_RightFrame.h"
+#include "utilities.h"
+
+#include "SMESH_Actor.h"
+
+// QT Includes
+#include <qbuttongroup.h>
+#include <qgroupbox.h>
+#include <qhbox.h>
+#include <qlabel.h>
+#include <qlineedit.h>
+#include <qpushbutton.h>
+#include <qradiobutton.h>
+#include <qcheckbox.h>
+#include <qlayout.h>
+#include <qlistbox.h>
+#include <qimage.h>
+#include <qpixmap.h>
+#include <qmemarray.h>
+
+// STL includes
+#include <vector>
+#include <algorithm>
+
+//=================================================================================
+// class : SMESHGUI_GroupDlg()
+// purpose :
+//=================================================================================
+SMESHGUI_GroupDlg::SMESHGUI_GroupDlg( QWidget* parent, const char* name, SALOME_Selection* theSel,
+ SMESH::SMESH_Mesh_ptr theMesh, bool modal, WFlags fl )
+ : QDialog( parent, name, modal, WStyle_Customize | WStyle_NormalBorder | WStyle_Title | WStyle_SysMenu | WDestructiveClose )
+{
+ if ( !name ) setName( "SMESHGUI_GroupDlg" );
+ initDialog(theSel, true);
+ init(theMesh);
+
+ /* Move widget on the botton right corner of main widget */
+ int x, y ;
+ mySMESHGUI->DefineDlgPosition(this, x, y);
+ this->move(x, y);
+}
+
+SMESHGUI_GroupDlg::SMESHGUI_GroupDlg( QWidget* parent, const char* name, SALOME_Selection* theSel,
+ SMESH::SMESH_Group_ptr theGroup, bool modal, WFlags fl )
+ : QDialog( parent, name, modal, WStyle_Customize | WStyle_NormalBorder | WStyle_Title | WStyle_SysMenu | WDestructiveClose )
+{
+ if ( !name ) setName( "SMESHGUI_GroupDlg" );
+ initDialog(theSel, false);
+ init(theGroup);
+
+ /* Move widget on the botton right corner of main widget */
+ int x, y ;
+ mySMESHGUI->DefineDlgPosition(this, x, y);
+ this->move(x, y);
+}
+
+void SMESHGUI_GroupDlg::initDialog(SALOME_Selection* theSel, bool create)
+{
+ myFilterDlg = 0;
+
+ QPixmap image0(QAD_Desktop::getResourceManager()->loadPixmap( "SMESH",tr("ICON_SELECT")));
+
+ if (create)
+ setCaption( tr( "SMESH_CREATE_GROUP_TITLE" ) );
+ else
+ setCaption( tr( "SMESH_EDIT_GROUP_TITLE" ) );
+ setSizeGripEnabled( TRUE );
+
+ QVBoxLayout* aMainLayout = new QVBoxLayout(this, 11, 6);
+
+ /***************************************************************/
+ myTypeGroup = new QButtonGroup(1, Qt::Vertical, this, "Group types");
+ myTypeGroup->setTitle(tr("SMESH_ELEMENTS_TYPE"));
+ myTypeGroup->setExclusive(true);
+
+ QStringList types;
+ types.append(tr("MESH_NODE"));
+ types.append(tr("SMESH_EDGE"));
+ types.append(tr("SMESH_FACE"));
+ types.append(tr("SMESH_VOLUME"));
+ QRadioButton* rb;
+ for (int i = 0; i < types.count(); i++) {
+ rb = new QRadioButton(types[i], myTypeGroup);
+ }
+ myTypeGroup->setEnabled(create);
+ myTypeId = -1;
+
+ /***************************************************************/
+ QHBox* aNameBox = new QHBox(this, "name box");
+ QLabel* aName = new QLabel(aNameBox, "name label");
+ aName->setText(tr("SMESH_NAME"));
+ aName->setMinimumSize(50,0);
+ myName = new QLineEdit(aNameBox, "name");
+
+ /***************************************************************/
+ QGroupBox* aContentBox = new QGroupBox(1, Qt::Horizontal, this, "content box");
+ aContentBox->setTitle(tr("SMESH_CONTENT"));
+ QFrame* aContent = new QFrame(aContentBox, "content");
+ QGridLayout* aLayout = new QGridLayout(aContent, 7, 4);
+ aLayout->setSpacing(6);
+ aLayout->setAutoAdd(false);
+
+ QLabel* aLabel = new QLabel(aContent, "elements label");
+ aLabel->setText(tr("SMESH_ID_ELEMENTS"));
+ myElements = new QListBox(aContent, "elements list");
+ myElements->setSelectionMode(QListBox::Extended);
+ // myElements->setMinimumHeight(150);
+
+ myFilter = new QPushButton(aContent, "filter");
+ myFilter->setText(tr("SMESH_BUT_FILTER"));
+ QPushButton* aAddBtn = new QPushButton(aContent, "add");
+ aAddBtn->setText(tr("SMESH_BUT_ADD"));
+ QPushButton* aRemoveBtn = new QPushButton(aContent, "remove");
+ aRemoveBtn->setText(tr("SMESH_BUT_REMOVE"));
+ QPushButton* aSortBtn = new QPushButton(aContent, "sort");
+ aSortBtn->setText(tr("SMESH_BUT_SORT"));
+
+ aLayout->addWidget(aLabel, 0, 0);
+ aLayout->addMultiCellWidget(myElements, 1, 6, 0, 0);
+ aLayout->addWidget(myFilter, 1, 2);
+ aLayout->addWidget(aAddBtn, 3, 2);
+ aLayout->addWidget(aRemoveBtn, 4, 2);
+ aLayout->addWidget(aSortBtn, 6, 2);
+
+ aLayout->setColStretch(0, 1);
+ aLayout->addColSpacing(1, 20);
+ aLayout->addColSpacing(3, 20);
+ aLayout->setRowStretch(2, 1);
+ aLayout->setRowStretch(5, 1);
+
+ aContentBox->setMinimumHeight(aContent->sizeHint().height() +
+ aContentBox->sizeHint().height());
+
+ /***************************************************************/
+ QGroupBox* aSelectBox = new QGroupBox(3, Qt::Horizontal, this, "select box");
+ aSelectBox->setTitle(tr("SMESH_SELECT_FROM"));
+
+ mySelectSubMesh = new QCheckBox(aSelectBox, "submesh checkbox");
+ mySelectSubMesh->setText(tr("SMESH_SUBMESH"));
+ mySelectSubMesh->setMinimumSize(50, 0);
+ mySubMeshBtn = new QPushButton(aSelectBox, "submesh button");
+ mySubMeshBtn->setText("");
+ mySubMeshBtn->setPixmap(image0);
+ mySubMeshLine = new QLineEdit(aSelectBox, "submesh line");
+ mySubMeshLine->setReadOnly(true);
+ onSelectSubMesh(false);
+
+ mySelectGroup = new QCheckBox(aSelectBox, "group checkbox");
+ mySelectGroup->setText(tr("SMESH_GROUP"));
+ mySelectGroup->setMinimumSize(50, 0);
+ myGroupBtn = new QPushButton(aSelectBox, "group button");
+ myGroupBtn->setText("");
+ myGroupBtn->setPixmap(image0);
+ myGroupLine = new QLineEdit(aSelectBox, "group line");
+ myGroupLine->setReadOnly(true);
+ onSelectGroup(false);
+
+ aSelectBox->setMinimumHeight(mySubMeshBtn->sizeHint().height() +
+ myGroupBtn->sizeHint().height() +
+ aSelectBox->sizeHint().height());
+
+ /***************************************************************/
+ QFrame* aButtons = new QFrame(this, "button box");
+ aButtons->setFrameStyle(QFrame::Box | QFrame::Sunken);
+ QHBoxLayout* aBtnLayout = new QHBoxLayout(aButtons, 11, 6);
+ aBtnLayout->setAutoAdd(false);
+
+ QPushButton* aOKBtn = new QPushButton(aButtons, "ok");
+ aOKBtn->setText(tr("SMESH_BUT_OK"));
+ aOKBtn->setAutoDefault(true);
+ aOKBtn->setDefault(true);
+ QPushButton* aApplyBtn = new QPushButton(aButtons, "apply");
+ aApplyBtn->setText(tr("SMESH_BUT_APPLY"));
+ aApplyBtn->setAutoDefault(true);
+ QPushButton* aCloseBtn = new QPushButton(aButtons, "close");
+ aCloseBtn->setText(tr("SMESH_BUT_CLOSE"));
+ aCloseBtn->setAutoDefault(true);
+
+ aBtnLayout->addWidget(aOKBtn);
+ aBtnLayout->addWidget(aApplyBtn);
+ aBtnLayout->addStretch();
+ aBtnLayout->addWidget(aCloseBtn);
+
+ /***************************************************************/
+ aMainLayout->addWidget(myTypeGroup);
+ aMainLayout->addWidget(aNameBox);
+ aMainLayout->addWidget(aContentBox);
+ aMainLayout->addWidget(aSelectBox);
+ aMainLayout->addWidget(aButtons);
+
+ /* signals and slots connections */
+ connect(myTypeGroup, SIGNAL(clicked(int)), this, SLOT(onTypeChanged(int)));
+
+ connect(myName, SIGNAL(textChanged(const QString&)), this, SLOT(onNameChanged(const QString&)));
+ connect(myElements, SIGNAL(selectionChanged()), this, SLOT(onListSelectionChanged()));
+
+ connect(myFilter, SIGNAL(clicked()), this, SLOT(setFilters()));
+ connect(aAddBtn, SIGNAL(clicked()), this, SLOT(onAdd()));
+ connect(aRemoveBtn, SIGNAL(clicked()), this, SLOT(onRemove()));
+ connect(aSortBtn, SIGNAL(clicked()), this, SLOT(onSort()));
+
+ connect(mySelectSubMesh, SIGNAL(toggled(bool)), this, SLOT(onSelectSubMesh(bool)));
+ connect(mySelectGroup, SIGNAL(toggled(bool)), this, SLOT(onSelectGroup(bool)));
+ connect(mySubMeshBtn, SIGNAL(clicked()), this, SLOT(setCurrentSelection()));
+ connect(myGroupBtn, SIGNAL(clicked()), this, SLOT(setCurrentSelection()));
+
+ connect(aOKBtn, SIGNAL(clicked()), this, SLOT(onOK()));
+ connect(aApplyBtn, SIGNAL(clicked()), this, SLOT(onApply()));
+ connect(aCloseBtn, SIGNAL(clicked()), this, SLOT(onClose()));
+
+ /* Init selection */
+ mySelection = theSel;
+ mySMESHGUI = SMESHGUI::GetSMESHGUI();
+ mySMESHGUI->SetActiveDialogBox(this);
+ mySMESHGUI->SetState(800);
+
+ mySelectionMode = -1;
+ mySubMeshFilter = new SMESH_TypeFilter(SUBMESH);
+ myGroupFilter = new SMESH_TypeFilter(GROUP);
+
+ connect(mySMESHGUI, SIGNAL(SignalDeactivateActiveDialog()), this, SLOT(onClose()));
+ connect(mySMESHGUI, SIGNAL(SignalCloseAllDialogs()), this, SLOT(onClose()));
+ connect(mySelection, SIGNAL(currentSelectionChanged()), this, SLOT(onObjectSelectionChanged()));
+
+ updateButtons();
+}
+
+//=================================================================================
+// function : ~SMESHGUI_GroupDlg()
+// purpose : Destroys the object and frees any allocated resources
+//=================================================================================
+SMESHGUI_GroupDlg::~SMESHGUI_GroupDlg()
+{
+ // no need to delete child widgets, Qt does it all for us
+}
+
+
+//=================================================================================
+// function : Init()
+// purpose :
+//=================================================================================
+void SMESHGUI_GroupDlg::init(SMESH::SMESH_Mesh_ptr theMesh)
+{
+ /* init data from current selection */
+ myMesh = SMESH::SMESH_Mesh::_duplicate(theMesh);
+ myGroup = SMESH::SMESH_Group::_nil();
+
+ Standard_Boolean aResult;
+ myActor = mySMESHGUI->FindActor(myMesh, aResult, true);
+ mySMESHGUI->SetPickable(myActor);
+
+ myTypeGroup->setButton(0);
+ onTypeChanged(0);
+}
+
+//=================================================================================
+// function : Init()
+// purpose :
+//=================================================================================
+void SMESHGUI_GroupDlg::init(SMESH::SMESH_Group_ptr theGroup)
+{
+
+ myMesh = theGroup->GetMesh();
+ myGroup = SMESH::SMESH_Group::_duplicate(theGroup);
+
+ Standard_Boolean aResult;
+ myActor = mySMESHGUI->FindActor(myMesh, aResult, true);
+ if ( !myActor )
+ myActor = mySMESHGUI->FindActor(myGroup, aResult, true);
+ mySMESHGUI->SetPickable(myActor);
+
+ int aType = 0;
+ switch(theGroup->GetType()) {
+ case SMESH::NODE: aType= 0; break;
+ case SMESH::EDGE: aType = 1; break;
+ case SMESH::FACE: aType = 2; break;
+ case SMESH::VOLUME: aType = 3; break;
+ }
+ myTypeGroup->setButton(aType);
+ onTypeChanged(aType);
+
+ myName->setText(myGroup->GetName());
+ myName->home(false);
+
+ if (!theGroup->IsEmpty()) {
+ SMESH::long_array_var anElements = myGroup->GetListOfID();
+ int k = anElements->length();
+ for (int i = 0; i < k; i++) {
+ myIdList.append(anElements[i]);
+ myElements->insertItem(QString::number(anElements[i]));
+ }
+ myElements->selectAll(true);
+ }
+}
+
+
+//=================================================================================
+// function : updateButtons()
+// purpose :
+//=================================================================================
+void SMESHGUI_GroupDlg::updateButtons()
+{
+ bool enable = !myName->text().stripWhiteSpace().isEmpty() && myElements->count() > 0;
+ QPushButton* aBtn;
+ aBtn = (QPushButton*) child("ok", "QPushButton");
+ if (aBtn) aBtn->setEnabled(enable);
+ aBtn = (QPushButton*) child("apply", "QPushButton");
+ if (aBtn) aBtn->setEnabled(enable);
+}
+
+//=================================================================================
+// function : onNameChanged()
+// purpose :
+//=================================================================================
+void SMESHGUI_GroupDlg::onNameChanged(const QString& text)
+{
+ updateButtons();
+}
+
+//=================================================================================
+// function : onTypeChanged()
+// purpose : Radio button management
+//=================================================================================
+void SMESHGUI_GroupDlg::onTypeChanged(int id)
+{
+ if (myTypeId != id) {
+ myElements->clear();
+ if (myCurrentLineEdit == 0)
+ setSelectionMode(id);
+ myFilter->setEnabled(id == 1 || id == 2);
+ }
+ myTypeId = id;
+}
+
+//=================================================================================
+// function : setSelectionMode()
+// purpose : Radio button management
+//=================================================================================
+void SMESHGUI_GroupDlg::setSelectionMode(int theMode)
+{
+ if (mySelectionMode != theMode) {
+ mySelection->ClearIObjects();
+ mySelection->ClearFilters();
+ if (mySelectionMode == 0)
+ mySMESHGUI->EraseSimulationActors();
+ if (theMode < 4) {
+ if (theMode == 0) {
+ mySMESHGUI->ViewNodes();
+ QAD_Application::getDesktop()->SetSelectionMode(NodeSelection, true);
+ }
+ else if (theMode == 1) {
+ QAD_Application::getDesktop()->SetSelectionMode(EdgeSelection, true);
+ }
+ else if (theMode == 2) {
+ QAD_Application::getDesktop()->SetSelectionMode(FaceSelection, true);
+ }
+ else {
+ QAD_Application::getDesktop()->SetSelectionMode(VolumeSelection, true);
+ }
+ }
+ else {
+ QAD_Application::getDesktop()->SetSelectionMode(ActorSelection, true);
+ if (theMode == 4)
+ mySelection->AddFilter(mySubMeshFilter);
+ else if (theMode == 5)
+ mySelection->AddFilter(myGroupFilter);
+ }
+ mySelectionMode = theMode;
+ }
+}
+
+//=================================================================================
+// function : onApply()
+// purpose :
+//=================================================================================
+bool SMESHGUI_GroupDlg::onApply()
+{
+ if (!myName->text().stripWhiteSpace().isEmpty() && myElements->count() > 0) {
+ mySelection->ClearIObjects();
+ if (myGroup->_is_nil()) {
+ SMESH::ElementType aType = SMESH::ALL;
+ switch(myTypeId) {
+ case 0: aType = SMESH::NODE; break;
+ case 1: aType = SMESH::EDGE; break;
+ case 2: aType = SMESH::FACE; break;
+ case 3: aType = SMESH::VOLUME; break;
+ }
+ SMESH::long_array_var anIdList = new SMESH::long_array;
+ int i, k = myElements->count();
+ anIdList->length(k);
+ QListBoxItem* anItem;
+ for (i = 0, anItem = myElements->firstItem(); anItem != 0; i++, anItem = anItem->next()) {
+ anIdList[i] = anItem->text().toInt();
+ }
+
+ myGroup = mySMESHGUI->AddGroup(myMesh, aType, myName->text());
+ myGroup->Add(anIdList);
+
+ /* init for next operation */
+ myName->setText("");
+ myElements->clear();
+ myGroup = SMESH::SMESH_Group::_nil();
+ }
+ else {
+ myGroup->SetName(myName->text());
+
+ QValueList<int> aAddList;
+ QValueList<int>::iterator anIt;
+ QListBoxItem* anItem;
+ for (anItem = myElements->firstItem(); anItem != 0; anItem = anItem->next()) {
+ int anId = anItem->text().toInt();
+ if ((anIt = myIdList.find(anId)) == myIdList.end())
+ aAddList.append(anId);
+ else
+ myIdList.remove(anIt);
+ }
+ if (!aAddList.empty()) {
+ SMESH::long_array_var anIdList = new SMESH::long_array;
+ anIdList->length(aAddList.count());
+ int i;
+ for (i = 0, anIt = aAddList.begin(); anIt != aAddList.end(); anIt++, i++)
+ anIdList[i] = *anIt;
+ myGroup->Add(anIdList);
+ }
+ if (!myIdList.empty()) {
+ SMESH::long_array_var anIdList = new SMESH::long_array;
+ anIdList->length(myIdList.count());
+ int i;
+ for (i = 0, anIt = myIdList.begin(); anIt != myIdList.end(); anIt++, i++)
+ anIdList[i] = *anIt;
+ myGroup->Remove(anIdList);
+ }
+ /* init for next operation */
+ myIdList.clear();
+ for (anItem = myElements->firstItem(); anItem != 0; anItem = anItem->next())
+ myIdList.append(anItem->text().toInt());
+ }
+
+ mySMESHGUI->GetActiveStudy()->updateObjBrowser(true);
+ mySelection->ClearIObjects();
+ return true;
+ }
+ return false;
+}
+
+//=================================================================================
+// function : onOK()
+// purpose :
+//=================================================================================
+void SMESHGUI_GroupDlg::onOK()
+{
+ if ( onApply() )
+ onClose();
+}
+
+//=================================================================================
+// function : onClose()
+// purpose :
+//=================================================================================
+void SMESHGUI_GroupDlg::onClose()
+{
+ close();
+}
+
+
+static bool busy = false;
+//=================================================================================
+// function : onListSelectionChanged()
+// purpose : Called when selection in element list is changed
+//=================================================================================
+void SMESHGUI_GroupDlg::onListSelectionChanged()
+{
+ // MESSAGE("SMESHGUI_GroupDlg::onListSelectionChanged(); myActor = " << myActor);
+ if (busy || !myActor) return;
+ busy = true;
+
+ if (myCurrentLineEdit == 0) {
+ mySelection->ClearIObjects();
+ TColStd_MapOfInteger aIndexes;
+ QListBoxItem* anItem;
+ for (anItem = myElements->firstItem(); anItem != 0; anItem = anItem->next()) {
+ if (anItem->isSelected()) {
+ std::vector<int> aVtkList;
+ if (myTypeId == 0)
+ aVtkList = myActor->GetNodeVtkId(anItem->text().toInt());
+ else
+ aVtkList = myActor->GetElemVtkId(anItem->text().toInt());
+
+ if (aVtkList.size() > 0) {
+ std::vector<int>::iterator it;
+ for (it = aVtkList.begin(); it != aVtkList.end(); ++it) {
+ aIndexes.Add(*it);
+ }
+ }
+ }
+ }
+ mySelection->AddOrRemoveIndex(myActor->getIO(), aIndexes, false, false);
+ mySelection->AddIObject(myActor->getIO());
+ }
+ busy = false;
+}
+
+//=================================================================================
+// function : onObjectSelectionChanged()
+// purpose : Called when selection in 3D view or ObjectBrowser is changed
+//=================================================================================
+void SMESHGUI_GroupDlg::onObjectSelectionChanged()
+{
+ if (busy) return;
+ busy = true;
+
+ int aNbSel = mySelection->IObjectCount();
+ myElements->clearSelection();
+
+ if (myCurrentLineEdit) {
+ myCurrentLineEdit->setText("") ;
+ QString aString = "";
+ if (aNbSel >= 1) {
+ if (aNbSel > 1) {
+ if (myCurrentLineEdit = mySubMeshLine)
+ aString = tr("SMESH_SUBMESH_SELECTED").arg(aNbSel);
+ else if (myCurrentLineEdit = myGroupLine)
+ aString = tr("SMESH_GROUP_SELECTED").arg(aNbSel);
+ }
+ else {
+ aString = mySelection->firstIObject()->getName();
+ }
+ }
+
+ myCurrentLineEdit->setText(aString) ;
+ myCurrentLineEdit->home( false );
+ }
+ else {
+ if (aNbSel == 1) {
+ QString aListStr = "";
+ int aNbItems = 0;
+ if (myTypeId == 0) {
+ aNbItems = mySMESHGUI->GetNameOfSelectedNodes(mySelection, aListStr);
+ }
+ else {
+ aNbItems = mySMESHGUI->GetNameOfSelectedElements(mySelection, aListStr);
+ }
+ if (aNbItems > 0) {
+ QStringList anElements = QStringList::split(" ", aListStr);
+ QListBoxItem* anItem = 0;
+ for (QStringList::iterator it = anElements.begin(); it != anElements.end(); ++it) {
+ anItem = myElements->findItem(*it, Qt::ExactMatch);
+ if (anItem) myElements->setSelected(anItem, true);
+ }
+ }
+ }
+ }
+ busy = false;
+}
+
+
+//=================================================================================
+// function : onSelectSubMesh()
+// purpose : Called when selection in 3D view or ObjectBrowser is changed
+//=================================================================================
+void SMESHGUI_GroupDlg::onSelectSubMesh(bool on)
+{
+ if (on) {
+ if (mySelectGroup->isChecked()) {
+ mySelectGroup->setChecked(false);
+ }
+ myCurrentLineEdit = mySubMeshLine;
+ setSelectionMode(4);
+ }
+ else {
+ mySubMeshLine->setText("");
+ myCurrentLineEdit = 0;
+ if (myTypeId != -1)
+ setSelectionMode(myTypeId);
+ }
+ mySubMeshBtn->setEnabled(on);
+ mySubMeshLine->setEnabled(on);
+}
+
+//=================================================================================
+// function : (onSelectGroup)
+// purpose : Called when selection in 3D view or ObjectBrowser is changed
+//=================================================================================
+void SMESHGUI_GroupDlg::onSelectGroup(bool on)
+{
+ if (on) {
+ if (mySelectSubMesh->isChecked()) {
+ mySelectSubMesh->setChecked(false);
+ }
+ myCurrentLineEdit = myGroupLine;
+ setSelectionMode(5);
+ }
+ else {
+ myGroupLine->setText("");
+ myCurrentLineEdit = 0;
+ if (myTypeId != -1)
+ setSelectionMode(myTypeId);
+ }
+ myGroupBtn->setEnabled(on);
+ myGroupLine->setEnabled(on);
+}
+
+//=================================================================================
+// function : setCurrentSelection()
+// purpose :
+//=================================================================================
+void SMESHGUI_GroupDlg::setCurrentSelection()
+{
+ QPushButton* send = (QPushButton*)sender();
+ myCurrentLineEdit = 0;
+ if (send == mySubMeshBtn) {
+ myCurrentLineEdit = mySubMeshLine;
+ onObjectSelectionChanged();
+ }
+ else if (send == myGroupBtn) {
+ myCurrentLineEdit = myGroupLine;
+ onObjectSelectionChanged();
+ }
+}
+
+
+//=================================================================================
+// function : setFilters()
+// purpose : SLOT. Called when "Filter" button pressed.
+//=================================================================================
+void SMESHGUI_GroupDlg::setFilters()
+{
+ SMESH::ElementType aType = SMESH::ALL;
+ switch ( myTypeId )
+ {
+ case 0 : aType = SMESH::NODE; break;
+ case 1 : aType = SMESH::EDGE; break;
+ case 2 : aType = SMESH::FACE; break;
+ case 3 : aType = SMESH::VOLUME; break;
+ default: return;
+ }
+
+ if ( myFilterDlg == 0 )
+ myFilterDlg = new SMESHGUI_FilterDlg( this, aType, true );
+ else
+ myFilterDlg->Init( aType );
+
+ myFilterDlg->SetSelection( mySelection );
+ myFilterDlg->SetMesh( myMesh );
+ myFilterDlg->SetSourceWg( myElements );
+
+ if ( myFilterDlg->exec() != QDialog::Accepted )
+ return;
+
+ if ( mySelectSubMesh->isChecked() || mySelectGroup->isChecked() )
+ {
+ mySelectionMode = myTypeId;
+ mySelectSubMesh->setChecked( false );
+ mySelectGroup->setChecked( false );
+ }
+}
+
+//=================================================================================
+// function : onAdd()
+// purpose :
+//=================================================================================
+void SMESHGUI_GroupDlg::onAdd()
+{
+ int aNbSel = mySelection->IObjectCount();
+ if (aNbSel == 0) return;
+
+ busy = true;
+
+ SMESH::ElementType aType = SMESH::ALL;
+ switch(myTypeId) {
+ case 0: aType = SMESH::NODE; break;
+ case 1: aType = SMESH::EDGE; break;
+ case 2: aType = SMESH::FACE; break;
+ case 3: aType = SMESH::VOLUME; break;
+ }
+
+ if (myCurrentLineEdit == 0) {
+ if (aNbSel != 1) { busy = false; return; }
+ QString aListStr = "";
+ int aNbItems = 0;
+ if (myTypeId == 0) {
+ aNbItems = mySMESHGUI->GetNameOfSelectedNodes(mySelection, aListStr);
+ }
+ else {
+ aNbItems = mySMESHGUI->GetNameOfSelectedElements(mySelection, aListStr);
+ }
+ if (aNbItems > 0) {
+ QStringList anElements = QStringList::split(" ", aListStr);
+ QListBoxItem* anItem = 0;
+ for (QStringList::iterator it = anElements.begin(); it != anElements.end(); ++it) {
+ anItem = myElements->findItem(*it, Qt::ExactMatch);
+ if (!anItem) {
+ anItem = new QListBoxText(*it);
+ myElements->insertItem(anItem);
+ }
+ myElements->setSelected(anItem, true);
+ }
+ }
+ }
+ else if (myCurrentLineEdit == mySubMeshLine) {
+ Standard_Boolean aRes;
+ SALOME_ListIteratorOfListIO anIt(mySelection->StoredIObjects());
+ for (; anIt.More(); anIt.Next()) {
+ SMESH::SMESH_subMesh_var aSubMesh = mySMESHGUI->ConvertIOinSubMesh(anIt.Value(), aRes);
+ if (aRes && !aSubMesh->_is_nil()) {
+ // check if mesh is the same
+ if (aSubMesh->GetFather()->GetId() == myMesh->GetId()) {
+ if (aType == SMESH::NODE) {
+ try {
+ SMESH::long_array_var anElements = aSubMesh->GetNodesId();
+ int k = anElements->length();
+ QListBoxItem* anItem = 0;
+ for (int i = 0; i < k; i++) {
+ QString aText = QString::number(anElements[i]);
+ anItem = myElements->findItem(aText, Qt::ExactMatch);
+ if (!anItem) {
+ anItem = new QListBoxText(aText);
+ myElements->insertItem(anItem);
+ }
+ myElements->setSelected(anItem, true);
+ }
+ }
+ catch (const SALOME::SALOME_Exception& ex) {
+ QtCatchCorbaException(ex);
+ }
+ }
+ else {
+ try {
+ SMESH::long_array_var anElements = aSubMesh->GetElementsId();
+ int k = anElements->length();
+ QListBoxItem* anItem = 0;
+ for (int i = 0; i < k; i++) {
+ QString aText = QString::number(anElements[i]);
+ anItem = myElements->findItem(aText, Qt::ExactMatch);
+ if (!anItem) {
+ anItem = new QListBoxText(aText);
+ myElements->insertItem(anItem);
+ }
+ myElements->setSelected(anItem, true);
+ }
+ }
+ catch (const SALOME::SALOME_Exception& ex) {
+ QtCatchCorbaException(ex);
+ }
+ }
+ }
+ }
+ }
+ mySelectSubMesh->setChecked(false);
+ busy = false;
+ onListSelectionChanged();
+ }
+ else if (myCurrentLineEdit == myGroupLine) {
+ Standard_Boolean aRes;
+ SALOME_ListIteratorOfListIO anIt(mySelection->StoredIObjects());
+ for (; anIt.More(); anIt.Next()) {
+ SMESH::SMESH_Group_var aGroup = mySMESHGUI->ConvertIOinSMESHGroup(anIt.Value(), aRes);
+ if (aRes && !aGroup->_is_nil()) {
+ // check if mesh is the same
+ if (aGroup->GetType() == aType && aGroup->GetMesh()->GetId() == myMesh->GetId()) {
+ SMESH::long_array_var anElements = aGroup->GetListOfID();
+ int k = anElements->length();
+ QListBoxItem* anItem = 0;
+ for (int i = 0; i < k; i++) {
+ QString aText = QString::number(anElements[i]);
+ anItem = myElements->findItem(aText, Qt::ExactMatch);
+ if (!anItem) {
+ anItem = new QListBoxText(aText);
+ myElements->insertItem(anItem);
+ }
+ myElements->setSelected(anItem, true);
+ }
+ }
+ }
+ }
+ mySelectGroup->setChecked(false);
+ busy = false;
+ onListSelectionChanged();
+ }
+ busy = false;
+ // mySelection->ClearIObjects();
+ updateButtons();
+}
+
+//=================================================================================
+// function : onRemove()
+// purpose :
+//=================================================================================
+void SMESHGUI_GroupDlg::onRemove()
+{
+ busy = true;
+ if (myCurrentLineEdit == 0) {
+ for (int i = myElements->count(); i > 0; i--) {
+ if (myElements->isSelected(i-1)) {
+ myElements->removeItem(i-1);
+ }
+ }
+ }
+ else {
+ int aNbSel = mySelection->IObjectCount();
+ if (aNbSel == 0) { busy = false; return; }
+
+ SMESH::ElementType aType = SMESH::ALL;
+ switch(myTypeId) {
+ case 0: aType = SMESH::NODE; break;
+ case 1: aType = SMESH::EDGE; break;
+ case 2: aType = SMESH::FACE; break;
+ case 3: aType = SMESH::VOLUME; break;
+ }
+
+ if (myCurrentLineEdit == mySubMeshLine) {
+ Standard_Boolean aRes;
+ SALOME_ListIteratorOfListIO anIt(mySelection->StoredIObjects());
+ for (; anIt.More(); anIt.Next()) {
+ SMESH::SMESH_subMesh_var aSubMesh = mySMESHGUI->ConvertIOinSubMesh(anIt.Value(), aRes);
+ if (aRes && !aSubMesh->_is_nil()) {
+ // check if mesh is the same
+ if (aSubMesh->GetFather()->GetId() == myMesh->GetId()) {
+ if (aType == SMESH::NODE) {
+ try {
+ SMESH::long_array_var anElements = aSubMesh->GetNodesId();
+ int k = anElements->length();
+ QListBoxItem* anItem = 0;
+ for (int i = 0; i < k; i++) {
+ anItem = myElements->findItem(QString::number(anElements[i]), Qt::ExactMatch);
+ if (anItem) delete anItem;
+ }
+ }
+ catch (const SALOME::SALOME_Exception& ex) {
+ QtCatchCorbaException(ex);
+ }
+ }
+ else {
+ try {
+ SMESH::long_array_var anElements = aSubMesh->GetElementsId();
+ int k = anElements->length();
+ QListBoxItem* anItem = 0;
+ for (int i = 0; i < k; i++) {
+ anItem = myElements->findItem(QString::number(anElements[i]), Qt::ExactMatch);
+ if (anItem) delete anItem;
+ }
+ }
+ catch (const SALOME::SALOME_Exception& ex) {
+ QtCatchCorbaException(ex);
+ }
+ }
+ }
+ }
+ }
+ }
+ else if (myCurrentLineEdit == myGroupLine) {
+ Standard_Boolean aRes;
+ SALOME_ListIteratorOfListIO anIt(mySelection->StoredIObjects());
+ for (; anIt.More(); anIt.Next()) {
+ SMESH::SMESH_Group_var aGroup = mySMESHGUI->ConvertIOinSMESHGroup(anIt.Value(), aRes);
+ if (aRes && !aGroup->_is_nil()) {
+ // check if mesh is the same
+ if (aGroup->GetType() == aType && aGroup->GetMesh()->GetId() == myMesh->GetId()) {
+ SMESH::long_array_var anElements = aGroup->GetListOfID();
+ int k = anElements->length();
+ QListBoxItem* anItem = 0;
+ for (int i = 0; i < k; i++) {
+ anItem = myElements->findItem(QString::number(anElements[i]), Qt::ExactMatch);
+ if (anItem) delete anItem;
+ }
+ }
+ }
+ }
+ }
+ }
+ busy = false;
+ updateButtons();
+}
+
+//=================================================================================
+// function : onSort()
+// purpose :
+//=================================================================================
+void SMESHGUI_GroupDlg::onSort()
+{
+ // PAL5412: sorts items in ascending by "string" value
+ // myElements->sort(true);
+ // myElements->update();
+ int i, k = myElements->count();
+ if (k > 0) {
+ busy = true;
+ QStringList aSelected;
+ std::vector<int> anArray(k);
+ // QMemArray<int> anArray(k);
+ QListBoxItem* anItem;
+ // fill the array
+ for (anItem = myElements->firstItem(), i = 0; anItem != 0; anItem = anItem->next(), i++) {
+ anArray[i] = anItem->text().toInt();
+ if (anItem->isSelected())
+ aSelected.append(anItem->text());
+ }
+ // sort & update list
+ std::sort(anArray.begin(), anArray.end());
+ // anArray.sort();
+ myElements->clear();
+ for (i = 0; i < k; i++) {
+ myElements->insertItem(QString::number(anArray[i]));
+ }
+ for (QStringList::iterator it = aSelected.begin(); it != aSelected.end(); ++it) {
+ anItem = myElements->findItem(*it, Qt::ExactMatch);
+ if (anItem) myElements->setSelected(anItem, true);
+ }
+ busy = false;
+ }
+}
+
+//=================================================================================
+// function : closeEvent()
+// purpose :
+//=================================================================================
+void SMESHGUI_GroupDlg::closeEvent( QCloseEvent* e )
+{
+ QAD_StudyFrame* aStudyFrame = mySMESHGUI->GetActiveStudy()->getActiveStudyFrame();
+ if (aStudyFrame->getTypeView() == VIEW_VTK) {
+ mySMESHGUI->SetPickable();
+ if (mySelectionMode == 0)
+ mySMESHGUI->EraseSimulationActors();
+
+ // remove filters from viewer
+ VTKViewer_InteractorStyleSALOME* aStyle = ((VTKViewer_ViewFrame*)aStudyFrame->getRightFrame()->getViewFrame())->getRWInteractor()->GetInteractorStyleSALOME();
+ aStyle->RemoveEdgeFilter();
+ aStyle->RemoveFaceFilter();
+
+ }
+
+ mySelection->ClearIObjects();
+ QAD_Application::getDesktop()->SetSelectionMode(ActorSelection);
+ mySelection->ClearFilters();
+ mySMESHGUI->ResetState();
+
+ QDialog::closeEvent( e );
+}
--- /dev/null
+// SMESH SMESHGUI : GUI for SMESH component
+//
+// Copyright (C) 2003 CEA
+//
+// This library 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.
+//
+// This library 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 this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+//
+// See http://www.salome-platform.org or email : webmaster.salome@opencascade.org
+//
+//
+//
+// File : SMESHGUI_GroupDlg.h
+// Author : Natalia KOPNOVA
+// Module : SMESH
+// $Header$
+
+#ifndef DIALOGBOX_GROUP_H
+#define DIALOGBOX_GROUP_H
+
+#include "SALOME_Selection.h"
+#include "SMESH_TypeFilter.hxx"
+
+// QT Includes
+#include <qdialog.h>
+#include <qvaluelist.h>
+
+// IDL Headers
+#include <SALOMEconfig.h>
+#include CORBA_SERVER_HEADER(SMESH_Mesh)
+#include CORBA_SERVER_HEADER(SMESH_Group)
+
+class QLineEdit;
+class QButtonGroup;
+class QListBox;
+class QPushButton;
+class QCheckBox;
+class SMESHGUI;
+class SMESH_Actor;
+class SMESHGUI_FilterDlg;
+
+//=================================================================================
+// class : SMESHGUI_GroupDlg
+// purpose :
+//=================================================================================
+class SMESHGUI_GroupDlg : public QDialog
+{
+ Q_OBJECT
+
+public:
+ SMESHGUI_GroupDlg( QWidget* parent = 0, const char* name = 0, SALOME_Selection* theSel = 0,
+ SMESH::SMESH_Mesh_ptr theMesh = SMESH::SMESH_Mesh::_nil(),
+ bool modal = FALSE, WFlags fl = 0 );
+ SMESHGUI_GroupDlg( QWidget* parent, const char* name, SALOME_Selection* theSel,
+ SMESH::SMESH_Group_ptr theGroup, bool modal = FALSE, WFlags fl = 0 );
+ ~SMESHGUI_GroupDlg();
+
+public slots:
+
+ void onAdd();
+ void onRemove();
+
+
+private slots:
+
+ void onTypeChanged(int id);
+
+ void onOK();
+ void onClose();
+ bool onApply();
+
+ void onListSelectionChanged();
+ void onObjectSelectionChanged();
+
+ void onSelectSubMesh(bool on);
+ void onSelectGroup(bool on);
+ void setCurrentSelection();
+
+ void setFilters();
+ void onSort();
+
+ void onNameChanged(const QString& text);
+
+private:
+ void initDialog(SALOME_Selection* theSel, bool create);
+ void init(SMESH::SMESH_Mesh_ptr theMesh);
+ void init(SMESH::SMESH_Group_ptr theGroup);
+ void closeEvent(QCloseEvent* e);
+ void setSelectionMode(int theMode);
+ void updateButtons();
+
+ SMESHGUI* mySMESHGUI ; /* Current SMESHGUI object */
+ SALOME_Selection* mySelection ; /* User shape selection */
+ SMESH_Actor* myActor; /* Current mesh actor */
+ int myTypeId ; /* Current type id = radio button id */
+ QLineEdit* myCurrentLineEdit; /* Current LineEdit */
+
+ QButtonGroup* myTypeGroup;
+ QLineEdit* myName;
+ QListBox* myElements;
+ QPushButton* myFilter;
+
+ QCheckBox* mySelectSubMesh;
+ QPushButton* mySubMeshBtn;
+ QLineEdit* mySubMeshLine;
+
+ QCheckBox* mySelectGroup;
+ QPushButton* myGroupBtn;
+ QLineEdit* myGroupLine;
+
+ SMESH::SMESH_Mesh_var myMesh;
+ SMESH::SMESH_Group_var myGroup;
+ QValueList<int> myIdList;
+
+ int mySelectionMode;
+ Handle(SMESH_TypeFilter) mySubMeshFilter;
+ Handle(SMESH_TypeFilter) myGroupFilter;
+
+ SMESHGUI_FilterDlg* myFilterDlg;
+};
+
+#endif // DIALOGBOX_GROUP_H
--- /dev/null
+// SMESH SMESHGUI : GUI for SMESH component
+//
+// Copyright (C) 2003 CEA
+//
+// This library 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.
+//
+// This library 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 this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+//
+// See http://www.salome-platform.org or email : webmaster.salome@opencascade.org
+//
+//
+//
+// File : SMESHGUI_Hypotheses.h
+// Author : Julia DOROVSKIKH
+// Module : SMESH
+// $Header$
+
+#ifndef SMESHGUI_Hypotheses_HeaderFile
+#define SMESHGUI_Hypotheses_HeaderFile
+
+#include CORBA_SERVER_HEADER(SMESH_Hypothesis)
+
+// QT Includes
+#include <qstring.h>
+#include <qwidget.h>
+
+//=================================================================================
+// class : SMESHGUI_GenericHypothesisCreator
+// purpose :
+//=================================================================================
+class SMESHGUI_GenericHypothesisCreator
+{
+ public:
+ virtual void CreateHypothesis (const bool isAlgo, QWidget* parent) = 0;
+ virtual void EditHypothesis (SMESH::SMESH_Hypothesis_ptr theHyp) = 0;
+};
+
+//=================================================================================
+// class : HypothesisData
+// purpose :
+//=================================================================================
+class HypothesisData
+{
+ public:
+ HypothesisData (const QString& aPluginName,
+ const QString& aServerLibName,
+ const QString& aClientLibName,
+ const QString& aLabel,
+ const QString& anIconId) :
+ PluginName(aPluginName),
+ ServerLibName(aServerLibName),
+ ClientLibName(aClientLibName),
+ Label(aLabel),
+ IconId(anIconId)
+ {};
+
+ QString PluginName;
+ QString ServerLibName;
+ QString ClientLibName;
+ QString Label;
+ QString IconId;
+};
+
+#endif
#include "QAD_Application.h"
#include "QAD_Desktop.h"
+#include "QAD_MessageBox.h"
+#include "QAD_WaitCursor.h"
+#include "QAD_Operation.h"
+
#include "utilities.h"
// QT Includes
-#include <qbuttongroup.h>
#include <qgroupbox.h>
#include <qlabel.h>
#include <qlineedit.h>
#include <qpushbutton.h>
-#include <qradiobutton.h>
#include <qlayout.h>
-#include <qvariant.h>
-#include <qtooltip.h>
-#include <qwhatsthis.h>
-#include <qimage.h>
#include <qpixmap.h>
-
//=================================================================================
// class : SMESHGUI_InitMeshDlg()
// purpose : Constructs a SMESHGUI_InitMeshDlg which is a child of 'parent', with the
// TRUE to construct a modal dialog.
//=================================================================================
SMESHGUI_InitMeshDlg::SMESHGUI_InitMeshDlg( QWidget* parent, const char* name, SALOME_Selection* Sel, bool modal, WFlags fl )
- : QDialog( parent, name, modal, WStyle_Customize | WStyle_NormalBorder | WStyle_Title | WStyle_SysMenu )
+ : QDialog( parent, name, modal, WStyle_Customize | WStyle_NormalBorder | WStyle_Title | WStyle_SysMenu | WDestructiveClose )
{
- QPixmap image1(QAD_Desktop::getResourceManager()->loadPixmap( "SMESH",tr("ICON_DLG_INIT_MESH")));
QPixmap image0(QAD_Desktop::getResourceManager()->loadPixmap( "SMESH",tr("ICON_SELECT")));
if ( !name )
setName( "SMESHGUI_InitMeshDlg" );
- resize( 303, 175 );
setCaption( tr( "SMESH_INIT_MESH" ) );
setSizeGripEnabled( TRUE );
- SMESHGUI_InitMeshDlgLayout = new QGridLayout( this );
+ QGridLayout* SMESHGUI_InitMeshDlgLayout = new QGridLayout( this );
SMESHGUI_InitMeshDlgLayout->setSpacing( 6 );
SMESHGUI_InitMeshDlgLayout->setMargin( 11 );
/***************************************************************/
- GroupConstructors = new QButtonGroup( this, "GroupConstructors" );
- GroupConstructors->setTitle( tr( "SMESH_INIT" ) );
- GroupConstructors->setExclusive( TRUE );
- GroupConstructors->setColumnLayout(0, Qt::Vertical );
- GroupConstructors->layout()->setSpacing( 0 );
- GroupConstructors->layout()->setMargin( 0 );
- GroupConstructorsLayout = new QGridLayout( GroupConstructors->layout() );
- GroupConstructorsLayout->setAlignment( Qt::AlignTop );
- GroupConstructorsLayout->setSpacing( 6 );
- GroupConstructorsLayout->setMargin( 11 );
- Constructor1 = new QRadioButton( GroupConstructors, "Constructor1" );
- Constructor1->setText( tr( "" ) );
- Constructor1->setPixmap( image1 );
- Constructor1->setChecked( TRUE );
- Constructor1->setSizePolicy( QSizePolicy( (QSizePolicy::SizeType)1, (QSizePolicy::SizeType)0, Constructor1->sizePolicy().hasHeightForWidth() ) );
- Constructor1->setMinimumSize( QSize( 50, 0 ) );
- GroupConstructorsLayout->addWidget( Constructor1, 0, 0 );
- QSpacerItem* spacer = new QSpacerItem( 20, 20, QSizePolicy::Expanding, QSizePolicy::Minimum );
- GroupConstructorsLayout->addItem( spacer, 0, 1 );
- SMESHGUI_InitMeshDlgLayout->addWidget( GroupConstructors, 0, 0 );
-
- /***************************************************************/
- GroupButtons = new QGroupBox( this, "GroupButtons" );
- GroupButtons->setGeometry( QRect( 10, 10, 281, 48 ) );
- GroupButtons->setTitle( tr( "" ) );
- GroupButtons->setColumnLayout(0, Qt::Vertical );
- GroupButtons->layout()->setSpacing( 0 );
- GroupButtons->layout()->setMargin( 0 );
- GroupButtonsLayout = new QGridLayout( GroupButtons->layout() );
- GroupButtonsLayout->setAlignment( Qt::AlignTop );
- GroupButtonsLayout->setSpacing( 6 );
- GroupButtonsLayout->setMargin( 11 );
- buttonCancel = new QPushButton( GroupButtons, "buttonCancel" );
- buttonCancel->setText( tr( "SMESH_BUT_CLOSE" ) );
- buttonCancel->setAutoDefault( TRUE );
- GroupButtonsLayout->addWidget( buttonCancel, 0, 3 );
- buttonApply = new QPushButton( GroupButtons, "buttonApply" );
- buttonApply->setText( tr( "SMESH_BUT_APPLY" ) );
- buttonApply->setAutoDefault( TRUE );
- GroupButtonsLayout->addWidget( buttonApply, 0, 1 );
- QSpacerItem* spacer_9 = new QSpacerItem( 20, 20, QSizePolicy::Expanding, QSizePolicy::Minimum );
- GroupButtonsLayout->addItem( spacer_9, 0, 2 );
- buttonOk = new QPushButton( GroupButtons, "buttonOk" );
- buttonOk->setText( tr( "SMESH_BUT_OK" ) );
- buttonOk->setAutoDefault( TRUE );
- buttonOk->setDefault( TRUE );
- GroupButtonsLayout->addWidget( buttonOk, 0, 0 );
- SMESHGUI_InitMeshDlgLayout->addWidget( GroupButtons, 2, 0 );
-
- /***************************************************************/
- GroupC1 = new QGroupBox( this, "GroupC1" );
- GroupC1->setTitle( tr( "SMESH_ARGUMENTS" ) );
- GroupC1->setMinimumSize( QSize( 0, 0 ) );
- GroupC1->setFrameShape( QGroupBox::Box );
- GroupC1->setFrameShadow( QGroupBox::Sunken );
+ GroupC1 = new QGroupBox( tr( "SMESH_ARGUMENTS" ), this, "GroupC1" );
GroupC1->setColumnLayout(0, Qt::Vertical );
GroupC1->layout()->setSpacing( 0 );
GroupC1->layout()->setMargin( 0 );
- GroupC1Layout = new QGridLayout( GroupC1->layout() );
+ QGridLayout* GroupC1Layout = new QGridLayout( GroupC1->layout() );
GroupC1Layout->setAlignment( Qt::AlignTop );
GroupC1Layout->setSpacing( 6 );
GroupC1Layout->setMargin( 11 );
- TextLabelC1A1 = new QLabel( GroupC1, "TextLabelC1A1" );
- TextLabelC1A1->setText( tr( "SMESH_OBJECT_GEOM" ) );
- TextLabelC1A1->setMinimumSize( QSize( 50, 0 ) );
- TextLabelC1A1->setFrameShape( QLabel::NoFrame );
- TextLabelC1A1->setFrameShadow( QLabel::Plain );
- GroupC1Layout->addWidget( TextLabelC1A1, 0, 0 );
+ TextLabel_NameMesh = new QLabel( tr( "SMESH_NAME" ), GroupC1, "TextLabel_NameMesh" );
+ GroupC1Layout->addWidget( TextLabel_NameMesh, 0, 0 );
+ LineEdit_NameMesh = new QLineEdit( GroupC1, "LineEdit_NameMesh" );
+ GroupC1Layout->addWidget( LineEdit_NameMesh, 0, 2 );
+
+ TextLabelC1A1 = new QLabel( tr( "SMESH_OBJECT_GEOM" ), GroupC1, "TextLabelC1A1" );
+ GroupC1Layout->addWidget( TextLabelC1A1, 1, 0 );
SelectButtonC1A1 = new QPushButton( GroupC1, "SelectButtonC1A1" );
- SelectButtonC1A1->setText( tr( "" ) );
SelectButtonC1A1->setPixmap( image0 );
SelectButtonC1A1->setToggleButton( FALSE );
- GroupC1Layout->addWidget( SelectButtonC1A1, 0, 1 );
+ GroupC1Layout->addWidget( SelectButtonC1A1, 1, 1 );
LineEditC1A1 = new QLineEdit( GroupC1, "LineEditC1A1" );
- GroupC1Layout->addWidget( LineEditC1A1, 0, 2 );
+ GroupC1Layout->addWidget( LineEditC1A1, 1, 2 );
- TextLabel_NameMesh = new QLabel( GroupC1, "TextLabel_NameMesh" );
- TextLabel_NameMesh->setText( tr( "SMESH_NAME" ) );
- GroupC1Layout->addWidget( TextLabel_NameMesh, 1, 0 );
- LineEdit_NameMesh = new QLineEdit( GroupC1, "LineEdit_NameMesh" );
- GroupC1Layout->addWidget( LineEdit_NameMesh, 1, 2 );
-
- TextLabelC1A1Hyp = new QLabel( GroupC1, "TextLabelC1A1Hyp" );
- TextLabelC1A1Hyp->setText( tr( "SMESH_OBJECT_HYPOTHESIS" ) );
- TextLabelC1A1Hyp->setMinimumSize( QSize( 50, 0 ) );
- TextLabelC1A1Hyp->setFrameShape( QLabel::NoFrame );
- TextLabelC1A1Hyp->setFrameShadow( QLabel::Plain );
+ TextLabelC1A1Hyp = new QLabel( tr( "SMESH_OBJECT_HYPOTHESIS" ), GroupC1, "TextLabelC1A1Hyp" );
GroupC1Layout->addWidget( TextLabelC1A1Hyp, 2, 0 );
SelectButtonC1A1Hyp = new QPushButton( GroupC1, "SelectButtonC1A1Hyp" );
- SelectButtonC1A1Hyp->setText( tr( "" ) );
SelectButtonC1A1Hyp->setPixmap( image0 );
GroupC1Layout->addWidget( SelectButtonC1A1Hyp, 2, 1 );
LineEditC1A1Hyp = new QLineEdit( GroupC1, "LineEditC1A1Hyp" );
- LineEditC1A1Hyp->setSizePolicy( QSizePolicy( (QSizePolicy::SizeType)3, (QSizePolicy::SizeType)0, LineEditC1A1Hyp->sizePolicy().hasHeightForWidth() ) );
GroupC1Layout->addWidget( LineEditC1A1Hyp, 2, 2 );
- TextLabelC1A1Algo = new QLabel( GroupC1, "TextLabelC1A1Algo" );
- TextLabelC1A1Algo->setText( tr( "SMESH_OBJECT_ALGORITHM" ) );
- TextLabelC1A1Algo->setMinimumSize( QSize( 50, 0 ) );
- TextLabelC1A1Algo->setFrameShape( QLabel::NoFrame );
- TextLabelC1A1Algo->setFrameShadow( QLabel::Plain );
+ TextLabelC1A1Algo = new QLabel( tr( "SMESH_OBJECT_ALGORITHM" ), GroupC1, "TextLabelC1A1Algo" );
GroupC1Layout->addWidget( TextLabelC1A1Algo, 3, 0 );
SelectButtonC1A1Algo = new QPushButton( GroupC1, "SelectButtonC1A1Algo" );
- SelectButtonC1A1Algo->setText( tr( "" ) );
SelectButtonC1A1Algo->setPixmap( image0 );
GroupC1Layout->addWidget( SelectButtonC1A1Algo, 3, 1 );
LineEditC1A1Algo = new QLineEdit( GroupC1, "LineEditC1A1Algo" );
- LineEditC1A1Algo->setSizePolicy( QSizePolicy( (QSizePolicy::SizeType)3, (QSizePolicy::SizeType)0, LineEditC1A1Algo->sizePolicy().hasHeightForWidth() ) );
GroupC1Layout->addWidget( LineEditC1A1Algo, 3, 2 );
SMESHGUI_InitMeshDlgLayout->addWidget( GroupC1, 1, 0 );
+
/***************************************************************/
+ GroupButtons = new QGroupBox( this, "GroupButtons" );
+ GroupButtons->setColumnLayout(0, Qt::Vertical );
+ GroupButtons->layout()->setSpacing( 0 );
+ GroupButtons->layout()->setMargin( 0 );
+ QGridLayout* GroupButtonsLayout = new QGridLayout( GroupButtons->layout() );
+ GroupButtonsLayout->setAlignment( Qt::AlignTop );
+ GroupButtonsLayout->setSpacing( 6 );
+ GroupButtonsLayout->setMargin( 11 );
+
+ buttonOk = new QPushButton( tr( "SMESH_BUT_OK" ), GroupButtons, "buttonOk" );
+ buttonOk->setAutoDefault( TRUE );
+ buttonOk->setDefault( TRUE );
+ GroupButtonsLayout->addWidget( buttonOk, 0, 0 );
+
+ buttonApply = new QPushButton( tr( "SMESH_BUT_APPLY" ), GroupButtons, "buttonApply" );
+ buttonApply->setAutoDefault( TRUE );
+ GroupButtonsLayout->addWidget( buttonApply, 0, 1 );
+
+ GroupButtonsLayout->addItem( new QSpacerItem( 20, 20, QSizePolicy::Expanding, QSizePolicy::Minimum ), 0, 2 );
+
+ buttonCancel = new QPushButton( tr( "SMESH_BUT_CLOSE" ), GroupButtons, "buttonCancel" );
+ buttonCancel->setAutoDefault( TRUE );
+ GroupButtonsLayout->addWidget( buttonCancel, 0, 3 );
+
+ SMESHGUI_InitMeshDlgLayout->addWidget( GroupButtons, 2, 0 );
- Init(Sel) ;
+ /***************************************************************/
+ Init( Sel ) ;
}
//=================================================================================
void SMESHGUI_InitMeshDlg::Init( SALOME_Selection* Sel )
{
- GroupC1->show();
- myConstructorId = 0 ;
- Constructor1->setChecked( TRUE );
- myEditCurrentArgument = LineEditC1A1 ;
mySelection = Sel;
mySMESHGUI = SMESHGUI::GetSMESHGUI() ;
mySMESHGUI->SetActiveDialogBox( (QDialog*)this ) ;
- myGeomFilter = new SALOME_TypeFilter( "GEOM" );
- myAlgorithmFilter = new SMESH_TypeFilter( ALGORITHM );
+ myGeomFilter = new SALOME_TypeFilter( "GEOM" );
+ myAlgorithmFilter = new SMESH_TypeFilter( ALGORITHM );
myHypothesisFilter = new SMESH_TypeFilter( HYPOTHESIS );
- myNameMesh = "Mesh";
-
/* signals and slots connections */
- connect( buttonOk, SIGNAL( clicked() ), this, SLOT( ClickOnOk() ) );
- connect( buttonApply, SIGNAL( clicked() ), this, SLOT(ClickOnApply() ) );
+ connect( buttonOk, SIGNAL( clicked() ), this, SLOT( ClickOnOk() ) );
+ connect( buttonApply, SIGNAL( clicked() ), this, SLOT( ClickOnApply() ) );
connect( buttonCancel, SIGNAL( clicked() ), this, SLOT( ClickOnCancel() ) ) ;
- connect( GroupConstructors, SIGNAL(clicked(int) ), SLOT( ConstructorsClicked(int) ) );
- connect( SelectButtonC1A1, SIGNAL (clicked() ), this, SLOT( SetEditCurrentArgument() ) ) ;
- connect( LineEdit_NameMesh, SIGNAL (textChanged(const QString&) ), this, SLOT( TextChangedInLineEdit(const QString&) ) ) ;
-
- connect( SelectButtonC1A1Hyp, SIGNAL (clicked() ), this, SLOT( SetEditCurrentArgument() ) ) ;
+ connect( SelectButtonC1A1, SIGNAL (clicked() ), this, SLOT( SetEditCurrentArgument() ) ) ;
+ connect( SelectButtonC1A1Hyp, SIGNAL (clicked() ), this, SLOT( SetEditCurrentArgument() ) ) ;
connect( SelectButtonC1A1Algo, SIGNAL (clicked() ), this, SLOT( SetEditCurrentArgument() ) ) ;
- connect( mySelection, SIGNAL( currentSelectionChanged() ), this, SLOT( SelectionIntoArgument() ) );
- connect( mySMESHGUI, SIGNAL ( SignalDeactivateActiveDialog() ), this, SLOT( DeactivateActiveDialog() ) ) ;
- connect( mySMESHGUI, SIGNAL ( SignalCloseAllDialogs() ), this, SLOT( ClickOnCancel() ) ) ;
+ connect( mySelection, SIGNAL( currentSelectionChanged() ), this, SLOT( SelectionIntoArgument() ) );
+ connect( mySMESHGUI, SIGNAL( SignalDeactivateActiveDialog() ), this, SLOT( DeactivateActiveDialog() ) ) ;
+ connect( mySMESHGUI, SIGNAL( SignalCloseAllDialogs() ), this, SLOT( ClickOnCancel() ) ) ;
int x, y ;
mySMESHGUI->DefineDlgPosition( this, x, y ) ;
this->move( x, y ) ;
this->show() ;
- return ;
-}
+ LineEdit_NameMesh->setText( tr( "SMESH_OBJECT_MESH" ) );
+ LineEdit_NameMesh->setFocus() ;
+ myEditCurrentArgument = LineEditC1A1 ;
+ mySelection->ClearFilters() ;
+ mySelection->AddFilter( myGeomFilter ) ;
+ SelectionIntoArgument();
-//=================================================================================
-// function : ConstructorsClicked()
-// purpose : Radio button management
-//=================================================================================
-void SMESHGUI_InitMeshDlg::ConstructorsClicked(int constructorId)
-{
- return ;
+ UpdateControlState();
}
+
//=================================================================================
// function : ClickOnOk()
// purpose :
//=================================================================================
void SMESHGUI_InitMeshDlg::ClickOnOk()
{
- this->ClickOnApply() ;
- this->ClickOnCancel() ;
-
- return ;
+ if ( this->ClickOnApply() )
+ this->ClickOnCancel() ;
}
//=================================================================================
// function : ClickOnApply()
// purpose :
//=================================================================================
-void SMESHGUI_InitMeshDlg::ClickOnApply()
+bool SMESHGUI_InitMeshDlg::ClickOnApply()
{
- switch(myConstructorId)
- {
- case 0 :
- {
- MESSAGE ( " myNameMesh " << myNameMesh.isEmpty() )
- MESSAGE ( " myGeomShape " << myGeomShape->_is_nil() )
- if ( !myNameMesh.isEmpty() && !myNameMesh.isNull() && !myGeomShape->_is_nil() )
- myMesh = mySMESHGUI->InitMesh( myGeomShape, myNameMesh ) ;
-
- MESSAGE ( " myMesh " << myMesh->_is_nil() )
- MESSAGE ( " myOkHypothesis " )
- MESSAGE ( " myOkAlgorithm " )
- if( myOkHypothesis && !myMesh->_is_nil() ) {
- SALOME_ListIteratorOfListIO It( HypoList );
- for(;It.More();It.Next()) {
- Handle(SALOME_InteractiveObject) IObject = It.Value();
- Standard_Boolean testResult;
- myHypothesis = mySMESHGUI->ConvertIOinSMESHHypothesis(IObject, testResult) ;
- if( testResult )
- mySMESHGUI->AddHypothesisOnMesh(myMesh, myHypothesis) ;
+ QString myNameMesh = LineEdit_NameMesh->text().stripWhiteSpace();
+ if ( myNameMesh.isEmpty() ) {
+ QAD_MessageBox::warn1( this, tr( "SMESH_WRN_WARNING" ), tr( "SMESH_WRN_EMPTY_NAME" ), tr( "SMESH_BUT_OK" ) );
+ return false;
+ }
+
+ if ( myGeomShape->_is_nil() || !HypoList.count() || !AlgoList.count() )
+ return false;
+
+ QAD_WaitCursor wc;
+
+ QAD_Operation* op = new QAD_Operation( mySMESHGUI->GetActiveStudy() );
+
+ // start transaction
+ op->start();
+
+ // create mesh
+ SMESH::SMESH_Mesh_var aMesh = mySMESHGUI->InitMesh( myGeomShape, myNameMesh ) ;
+
+ if ( !aMesh->_is_nil() ) {
+ // assign hypotheses
+ for( int i = 0; i < HypoList.count(); i++ ) {
+ SALOMEDS::SObject_var aHypSO = mySMESHGUI->GetStudy()->FindObjectID( HypoList[i] );
+ if ( !aHypSO->_is_nil() ) {
+ CORBA::Object_var anObject = aHypSO->GetObject();
+ if ( !CORBA::is_nil( anObject ) ) {
+ SMESH::SMESH_Hypothesis_var aHyp = SMESH::SMESH_Hypothesis::_narrow( anObject );
+ if ( !aHyp->_is_nil() ) {
+ if ( !mySMESHGUI->AddHypothesisOnMesh( aMesh, aHyp ) ) {
+ // abort transaction
+ op->abort();
+ return false;
+ }
}
}
-
- if( myOkAlgorithm && !myMesh->_is_nil() ) {
- SALOME_ListIteratorOfListIO It( AlgoList );
- for(;It.More();It.Next()) {
- Handle(SALOME_InteractiveObject) IObject = It.Value();
- Standard_Boolean testResult;
- myAlgorithm = mySMESHGUI->ConvertIOinSMESHHypothesis(IObject, testResult) ;
- if( testResult )
- mySMESHGUI->AddAlgorithmOnMesh(myMesh, myAlgorithm) ;
+ }
+ }
+ // assign algorithms
+ for( int i = 0; i < AlgoList.count(); i++ ) {
+ SALOMEDS::SObject_var aHypSO = mySMESHGUI->GetStudy()->FindObjectID( AlgoList[i] );
+ if ( !aHypSO->_is_nil() ) {
+ CORBA::Object_var anObject = aHypSO->GetObject();
+ if ( !CORBA::is_nil( anObject ) ) {
+ SMESH::SMESH_Hypothesis_var aHyp = SMESH::SMESH_Hypothesis::_narrow( anObject );
+ if ( !aHyp->_is_nil() ) {
+ if ( !mySMESHGUI->AddAlgorithmOnMesh( aMesh, aHyp ) ) {
+ // abort transaction
+ op->abort();
+ return false;
+ }
}
}
- break ;
}
}
+ }
+ // commit transaction
+ op->finish();
+ return true;
}
//=================================================================================
void SMESHGUI_InitMeshDlg::ClickOnCancel()
{
- mySelection->ClearFilters() ;
- disconnect( mySelection, 0, this, 0 );
- mySMESHGUI->ResetState() ;
- reject() ;
- return ;
+ close();
}
//=================================================================================
void SMESHGUI_InitMeshDlg::SelectionIntoArgument()
{
- myEditCurrentArgument->setText("") ;
QString aString = "";
+
int nbSel = mySMESHGUI->GetNameOfSelectedIObjects(mySelection, aString) ;
+
if ( myEditCurrentArgument == LineEditC1A1 ) {
+ // geom shape
if ( nbSel != 1 ) {
- myOkHypothesis = false;
- myOkAlgorithm = false;
myGeomShape = GEOM::GEOM_Shape::_nil();
- return ;
- } else {
+ aString = "";
+ }
+ else {
Standard_Boolean testResult ;
Handle(SALOME_InteractiveObject) IO = mySelection->firstIObject() ;
myGeomShape = mySMESHGUI->ConvertIOinGEOMShape(IO, testResult) ;
if( !testResult ) {
- myOkHypothesis = false;
- myOkAlgorithm = false;
- return ;
+ myGeomShape = GEOM::GEOM_Shape::_nil();
+ aString = "";
}
}
}
else if ( myEditCurrentArgument == LineEditC1A1Hyp ) {
+ // hypotheses
+ HypoList.clear();
if ( nbSel >= 1 ) {
- HypoList.Clear();
SALOME_ListIteratorOfListIO Itinit( mySelection->StoredIObjects() );
- for (; Itinit.More(); Itinit.Next()) {
- HypoList.Append(Itinit.Value());
+ for ( ; Itinit.More(); Itinit.Next() ) {
+ HypoList.append( Itinit.Value()->getEntry() );
}
- myOkHypothesis = true ;
- if (nbSel > 1)
- aString = tr("%1 Hypothesis").arg(nbSel) ;
- LineEditC1A1Hyp->setText(aString) ;
+ if ( nbSel > 1 )
+ aString = tr( "%1 Hypothesis" ).arg( nbSel ) ;
}
else {
- myOkHypothesis = false ;
- return ;
+ aString = "";
}
- } else if ( myEditCurrentArgument == LineEditC1A1Algo ) {
+ }
+ else if ( myEditCurrentArgument == LineEditC1A1Algo ) {
+ // algorithms
+ AlgoList.clear();
if ( nbSel >= 1 ) {
- AlgoList.Clear();
SALOME_ListIteratorOfListIO Itinit( mySelection->StoredIObjects() );
- for (; Itinit.More(); Itinit.Next()) {
- AlgoList.Append(Itinit.Value());
+ for ( ; Itinit.More(); Itinit.Next() ) {
+ AlgoList.append( Itinit.Value()->getEntry() );
}
- myOkAlgorithm = true ;
- if (nbSel > 1)
- aString = tr("%1 Algorithms").arg(nbSel) ;
- LineEditC1A1Algo->setText(aString) ;
+ if ( nbSel > 1 )
+ aString = tr( "%1 Algorithms" ).arg( nbSel ) ;
}
else {
- myOkAlgorithm = false ;
- return ;
+ aString = "";
}
}
myEditCurrentArgument->setText(aString) ;
+
+ UpdateControlState();
}
void SMESHGUI_InitMeshDlg::SetEditCurrentArgument()
{
QPushButton* send = (QPushButton*)sender();
- switch (myConstructorId)
- {
- case 0: /* default constructor */
- {
- if(send == SelectButtonC1A1) {
- LineEditC1A1->setFocus() ;
- myEditCurrentArgument = LineEditC1A1;
- mySelection->ClearFilters() ;
- mySelection->AddFilter(myGeomFilter) ;
- } else if( send == SelectButtonC1A1Hyp ) {
- LineEditC1A1Hyp->setFocus() ;
- myEditCurrentArgument = LineEditC1A1Hyp ;
- mySelection->ClearFilters() ;
- mySelection->AddFilter(myHypothesisFilter) ;
- } else if( send == SelectButtonC1A1Algo ) {
- LineEditC1A1Algo->setFocus() ;
- myEditCurrentArgument = LineEditC1A1Algo ;
- mySelection->ClearFilters() ;
- mySelection->AddFilter(myAlgorithmFilter) ;
- }
- SelectionIntoArgument() ;
- break;
- }
- }
- return ;
+ if(send == SelectButtonC1A1) {
+ LineEditC1A1->setFocus() ;
+ myEditCurrentArgument = LineEditC1A1;
+ mySelection->ClearFilters() ;
+ mySelection->AddFilter(myGeomFilter) ;
+ } else if( send == SelectButtonC1A1Hyp ) {
+ LineEditC1A1Hyp->setFocus() ;
+ myEditCurrentArgument = LineEditC1A1Hyp ;
+ mySelection->ClearFilters() ;
+ mySelection->AddFilter(myHypothesisFilter) ;
+ } else if( send == SelectButtonC1A1Algo ) {
+ LineEditC1A1Algo->setFocus() ;
+ myEditCurrentArgument = LineEditC1A1Algo ;
+ mySelection->ClearFilters() ;
+ mySelection->AddFilter(myAlgorithmFilter) ;
+ }
+ SelectionIntoArgument() ;
}
//=================================================================================
//=================================================================================
void SMESHGUI_InitMeshDlg::DeactivateActiveDialog()
{
- if ( GroupConstructors->isEnabled() ) {
+ if ( GroupC1->isEnabled() ) {
disconnect( mySelection, 0, this, 0 );
- GroupConstructors->setEnabled(false) ;
GroupC1->setEnabled(false) ;
GroupButtons->setEnabled(false) ;
}
void SMESHGUI_InitMeshDlg::ActivateThisDialog()
{
mySMESHGUI->EmitSignalDeactivateDialog() ;
- GroupConstructors->setEnabled(true) ;
GroupC1->setEnabled(true) ;
GroupButtons->setEnabled(true) ;
connect ( mySelection, SIGNAL( currentSelectionChanged() ), this, SLOT( SelectionIntoArgument() ) );
- return ;
}
//=================================================================================
void SMESHGUI_InitMeshDlg::enterEvent(QEvent* e)
{
- if ( GroupConstructors->isEnabled() )
- return ;
- ActivateThisDialog() ;
- return ;
+ if ( !GroupC1->isEnabled() )
+ ActivateThisDialog() ;
}
//=================================================================================
void SMESHGUI_InitMeshDlg::closeEvent( QCloseEvent* e )
{
- this->ClickOnCancel() ;
- return ;
+ disconnect( mySelection, 0, this, 0 );
+ mySMESHGUI->ResetState() ;
+ mySelection->ClearFilters() ;
+ QDialog::closeEvent( e );
}
//=================================================================================
-// function : TextChangedInLineEdit()
+// function : UpdateControlState()
// purpose :
//=================================================================================
-void SMESHGUI_InitMeshDlg::TextChangedInLineEdit(const QString& newText)
-{
- QLineEdit* send = (QLineEdit*)sender();
- QString newT = strdup(newText) ;
-
- if (send == LineEdit_NameMesh) {
- myNameMesh = newText;
- }
- return ;
+void SMESHGUI_InitMeshDlg::UpdateControlState()
+{
+ bool isEnabled = ( !myGeomShape->_is_nil() && HypoList.count() && AlgoList.count() );
+
+ buttonOk ->setEnabled( isEnabled );
+ buttonApply->setEnabled( isEnabled );
}
+
+
+
+
+
#include "SMESH_TypeFilter.hxx"
// QT Includes
-#include <qvariant.h>
#include <qdialog.h>
+#include <qstringlist.h>
// IDL Headers
#include <SALOMEconfig.h>
#include CORBA_SERVER_HEADER(GEOM_Shape)
#include CORBA_SERVER_HEADER(SMESH_Gen)
-class QVBoxLayout;
-class QHBoxLayout;
-class QGridLayout;
-class QButtonGroup;
class QGroupBox;
class QLabel;
class QLineEdit;
class QPushButton;
-class QRadioButton;
class SMESHGUI;
-
//=================================================================================
// class : SMESHGUI_InitMeshDlg
// purpose :
SMESHGUI_InitMeshDlg( QWidget* parent = 0, const char* name = 0, SALOME_Selection* Sel = 0, bool modal = FALSE, WFlags fl = 0 );
~SMESHGUI_InitMeshDlg();
-private:
-
- void Init( SALOME_Selection* Sel ) ;
+protected:
void closeEvent( QCloseEvent* e ) ;
void enterEvent ( QEvent * ) ;
+private:
+ void Init( SALOME_Selection* Sel ) ;
+
+ void UpdateControlState();
+
+private:
SMESHGUI* mySMESHGUI ;
SALOME_Selection* mySelection ;
- GEOM::GEOM_Shape_var myGeomShape ;
- int myConstructorId ;
+ GEOM::GEOM_Shape_var myGeomShape ;
QLineEdit* myEditCurrentArgument;
- QString myNameMesh ;
-
Handle(SALOME_TypeFilter) myGeomFilter;
Handle(SMESH_TypeFilter) myHypothesisFilter;
Handle(SMESH_TypeFilter) myAlgorithmFilter;
- SALOME_ListIO HypoList;
- SALOME_ListIO AlgoList;
-
- bool myOkHypothesis;
- bool myOkAlgorithm;
-
- SMESH::SMESH_Hypothesis_var myHypothesis;
- SMESH::SMESH_Hypothesis_var myAlgorithm;
-
- SMESH::SMESH_Mesh_var myMesh;
+ QStringList HypoList;
+ QStringList AlgoList;
- QButtonGroup* GroupConstructors;
- QRadioButton* Constructor1;
QGroupBox* GroupButtons;
QPushButton* buttonOk;
QPushButton* buttonCancel;
QPushButton* buttonApply;
+
QGroupBox* GroupC1;
QLabel* TextLabel_NameMesh ;
QLineEdit* LineEdit_NameMesh ;
QLineEdit* LineEditC1A1Algo;
private slots:
-
- void ConstructorsClicked(int constructorId);
void ClickOnOk();
+ bool ClickOnApply();
void ClickOnCancel();
- void ClickOnApply();
void SetEditCurrentArgument() ;
void SelectionIntoArgument() ;
void DeactivateActiveDialog() ;
void ActivateThisDialog() ;
- void TextChangedInLineEdit(const QString& newText) ;
-
-protected:
- QGridLayout* SMESHGUI_InitMeshDlgLayout;
- QGridLayout* GroupConstructorsLayout;
- QGridLayout* GroupButtonsLayout;
- QGridLayout* GroupC1Layout;
};
#endif // DIALOGBOX_INIT_MESH_H
#include "SMESHGUI.h"
#include "QAD_Application.h"
#include "QAD_Desktop.h"
+#include "QAD_WaitCursor.h"
#include "utilities.h"
// QT Includes
#include <qgroupbox.h>
#include <qlabel.h>
+#include <qframe.h>
+#include <qwidgetstack.h>
#include <qlayout.h>
-#include <qvariant.h>
-#include <qtooltip.h>
-#include <qwhatsthis.h>
#include <qmap.h>
+#include <qpushbutton.h>
-/*
- * Constructs a SMESHGUI_MeshInfosDlg which is a child of 'parent', with the
- * name 'name' and widget flags set to 'f'
- *
- * The dialog will by default be modeless, unless you set 'modal' to
- * TRUE to construct a modal dialog.
- */
-SMESHGUI_MeshInfosDlg::SMESHGUI_MeshInfosDlg( QWidget* parent, const char* name, SALOME_Selection* Sel, bool modal, WFlags fl )
- : QDialog( parent, name, modal, WStyle_Customize | WStyle_NormalBorder | WStyle_Title | WStyle_SysMenu )
-{
- if ( !name )
- setName( "SMESHGUI_MeshInfosDlg" );
- setCaption( tr( "SMESH_MESHINFO_TITLE" ) );
- setSizeGripEnabled( TRUE );
-
- SMESHGUI_MeshInfosDlgLayout = new QVBoxLayout( this );
- SMESHGUI_MeshInfosDlgLayout->setSpacing( 6 );
- SMESHGUI_MeshInfosDlgLayout->setMargin( 11 );
-
- /****************************************************************/
- GroupBox1 = new QGroupBox( this, "GroupBox1" );
- GroupBox1->setTitle( tr( "SMESH_MESHINFO_NB1D" ) );
- GroupBox1->setColumnLayout(0, Qt::Vertical );
- GroupBox1->layout()->setSpacing( 0 );
- GroupBox1->layout()->setMargin( 0 );
- QGridLayout* GroupBox1Layout = new QGridLayout( GroupBox1->layout() );
- GroupBox1Layout->setAlignment( Qt::AlignTop );
- GroupBox1Layout->setSpacing( 6 );
- GroupBox1Layout->setMargin( 11 );
-
- TextLabel11 = new QLabel( GroupBox1, "TextLabel11" );
- TextLabel11->setMinimumWidth( 100 );
- TextLabel11->setText( tr( "SMESH_MESHINFO_NODES" ) );
- GroupBox1Layout->addWidget( TextLabel11, 0, 0 );
-
- TextLabel12 = new QLabel( GroupBox1, "TextLabel12" );
- TextLabel12->setMinimumWidth( 100 );
- TextLabel12->setText( tr( "SMESH_MESHINFO_EDGES" ) );
- GroupBox1Layout->addWidget( TextLabel12, 1, 0 );
-
- TextLabel13 = new QLabel( GroupBox1, "TextLabel13" );
- TextLabel13->setMinimumWidth( 100 );
- GroupBox1Layout->addWidget( TextLabel13, 0, 1 );
-
- TextLabel14 = new QLabel( GroupBox1, "TextLabel14" );
- TextLabel14->setMinimumWidth( 100 );
- GroupBox1Layout->addWidget( TextLabel14, 1, 1 );
- SMESHGUI_MeshInfosDlgLayout->addWidget( GroupBox1 );
-
- /****************************************************************/
- GroupBox2 = new QGroupBox( this, "GroupBox2" );
- GroupBox2->setTitle( tr( "SMESH_MESHINFO_NB2D" ) );
- GroupBox2->setColumnLayout(0, Qt::Vertical );
- GroupBox2->layout()->setSpacing( 0 );
- GroupBox2->layout()->setMargin( 0 );
- QGridLayout* GroupBox2Layout = new QGridLayout( GroupBox2->layout() );
- GroupBox2Layout->setAlignment( Qt::AlignTop );
- GroupBox2Layout->setSpacing( 6 );
- GroupBox2Layout->setMargin( 11 );
-
- TextLabel21 = new QLabel( GroupBox2, "TextLabel21" );
- TextLabel21->setMinimumWidth( 100 );
- TextLabel21->setText( tr( "SMESH_MESHINFO_TRIANGLES" ) );
- GroupBox2Layout->addWidget( TextLabel21, 0, 0 );
-
- TextLabel22 = new QLabel( GroupBox2, "TextLabel22" );
- TextLabel22->setMinimumWidth( 100 );
- TextLabel22->setText( tr( "SMESH_MESHINFO_QUADRANGLES" ) );
- GroupBox2Layout->addWidget( TextLabel22, 1, 0 );
-
- TextLabel23 = new QLabel( GroupBox2, "TextLabel23" );
- TextLabel23->setMinimumWidth( 100 );
- GroupBox2Layout->addWidget( TextLabel23, 0, 1 );
-
- TextLabel24 = new QLabel( GroupBox2, "TextLabel24" );
- TextLabel24->setMinimumWidth( 100 );
- GroupBox2Layout->addWidget( TextLabel24, 1, 1 );
- SMESHGUI_MeshInfosDlgLayout->addWidget( GroupBox2 );
-
- /****************************************************************/
- GroupBox3 = new QGroupBox( this, "GroupBox3" );
- GroupBox3->setTitle( tr( "SMESH_MESHINFO_NB3D" ) );
- GroupBox3->setColumnLayout(0, Qt::Vertical );
- GroupBox3->layout()->setSpacing( 0 );
- GroupBox3->layout()->setMargin( 0 );
- QGridLayout* GroupBox3Layout = new QGridLayout( GroupBox3->layout() );
- GroupBox3Layout->setAlignment( Qt::AlignTop );
- GroupBox3Layout->setSpacing( 6 );
- GroupBox3Layout->setMargin( 11 );
-
- TextLabel31 = new QLabel( GroupBox3, "TextLabel31" );
- TextLabel31->setMinimumWidth( 100 );
- TextLabel31->setText( tr( "SMESH_MESHINFO_TETRAS" ) );
- GroupBox3Layout->addWidget( TextLabel31, 0, 0 );
-
- TextLabel32 = new QLabel( GroupBox3, "TextLabel32" );
- TextLabel32->setMinimumWidth( 100 );
- TextLabel32->setText( tr( "SMESH_MESHINFO_HEXAS" ) );
- GroupBox3Layout->addWidget( TextLabel32, 1, 0 );
-
- TextLabel33 = new QLabel( GroupBox3, "TextLabel33" );
- TextLabel33->setMinimumWidth( 100 );
- GroupBox3Layout->addWidget( TextLabel33, 0, 1 );
-
- TextLabel34 = new QLabel( GroupBox3, "TextLabel34" );
- TextLabel34->setMinimumWidth( 100 );
- GroupBox3Layout->addWidget( TextLabel34, 1, 1 );
- SMESHGUI_MeshInfosDlgLayout->addWidget( GroupBox3 );
-
- /****************************************************************/
- QGroupBox* GroupButtons = new QGroupBox( this, "GroupButtons" );
- GroupButtons->setColumnLayout(0, Qt::Vertical );
- GroupButtons->layout()->setSpacing( 0 );
- GroupButtons->layout()->setMargin( 0 );
- QGridLayout* GroupButtonsLayout = new QGridLayout( GroupButtons->layout() );
- GroupButtonsLayout->setAlignment( Qt::AlignTop );
- GroupButtonsLayout->setSpacing( 6 );
- GroupButtonsLayout->setMargin( 11 );
-
- GroupButtonsLayout->addItem( new QSpacerItem( 20, 20, QSizePolicy::Expanding, QSizePolicy::Minimum ), 0, 0 );
- buttonOk = new QPushButton( GroupButtons, "buttonOk" );
- buttonOk->setText( tr( "SMESH_BUT_OK" ) );
- buttonOk->setAutoDefault( TRUE );
- buttonOk->setDefault( TRUE );
- GroupButtonsLayout->addWidget( buttonOk, 0, 1 );
- GroupButtonsLayout->addItem( new QSpacerItem( 20, 20, QSizePolicy::Expanding, QSizePolicy::Minimum ), 0, 2 );
- SMESHGUI_MeshInfosDlgLayout->addWidget( GroupButtons );
- /****************************************************************/
-
- Init( Sel ) ;
-}
-
-/*
- * Destroys the object and frees any allocated resources
- */
-SMESHGUI_MeshInfosDlg::~SMESHGUI_MeshInfosDlg()
-{
- // no need to delete child widgets, Qt does it all for us
-}
+#define COLONIZE( str ) ( QString( str ).contains( ":" ) > 0 ? QString( str ) : QString( str ) + " :" )
//=================================================================================
-// function : Init()
-// purpose :
+/*!
+ * SMESHGUI_MeshInfosDlg::SMESHGUI_MeshInfosDlg
+ *
+ * Constructor
+ */
//=================================================================================
-void SMESHGUI_MeshInfosDlg::Init( SALOME_Selection* Sel )
-{
- mySelection = Sel ;
-
- mySMESHGUI = SMESHGUI::GetSMESHGUI() ;
- myStudy = mySMESHGUI->GetActiveStudy()->getStudyDocument();
-
- Engines::Component_var comp = QAD_Application::getDesktop()->getEngine("FactoryServer", "SMESH");
- myCompMesh = SMESH::SMESH_Gen::_narrow(comp);
-
- int nbSel = mySelection->IObjectCount();
-
- TextLabel13->setText( "0" );
- TextLabel14->setText( "0" );
- TextLabel23->setText( "0" );
- TextLabel24->setText( "0" );
- TextLabel33->setText( "0" );
- TextLabel34->setText( "0" );
-
- //gets the selected mesh
- if ( nbSel == 1 ) {
- Handle(SALOME_InteractiveObject) IObject = mySelection->firstIObject();
- Standard_Boolean res;
- myMesh = mySMESHGUI->ConvertIOinMesh( IObject, res );
- if ( res )
- DumpMeshInfos();
- }
-
- mySMESHGUI->SetActiveDialogBox( (QDialog*)this ) ;
-
- /* signals and slots connections */
- connect( buttonOk, SIGNAL( clicked() ), this, SLOT( ClickOnOk() ) );
- connect( mySMESHGUI, SIGNAL( SignalDeactivateActiveDialog() ), this, SLOT( DeactivateActiveDialog() ) ) ;
- connect( mySelection, SIGNAL( currentSelectionChanged() ), this, SLOT( SelectionIntoArgument() ) );
- /* to close dialog if study change */
- connect( mySMESHGUI, SIGNAL ( SignalCloseAllDialogs() ), this, SLOT( ClickOnOk() ) ) ;
-
- /* Move widget on the botton right corner of main widget */
- int x, y ;
- mySMESHGUI->DefineDlgPosition( this, x, y ) ;
- this->move( x, y ) ;
- this->show() ; /* Displays Dialog */
-
- return ;
+SMESHGUI_MeshInfosDlg::SMESHGUI_MeshInfosDlg( QWidget* parent, const char* name, bool modal, WFlags fl )
+ : QDialog( parent, name, modal, WStyle_Customize | WStyle_NormalBorder | WStyle_Title | WStyle_SysMenu | WDestructiveClose )
+{
+ if ( !name )
+ setName( "SMESHGUI_MeshInfosDlg" );
+ setCaption( tr( "SMESH_MESHINFO_TITLE" ) );
+ setSizeGripEnabled( TRUE );
+
+ myStartSelection = true;
+ myIsActiveWindow = true;
+
+ QVBoxLayout* aTopLayout = new QVBoxLayout( this );
+ aTopLayout->setSpacing( 6 ); aTopLayout->setMargin( 11 );
+
+ // select button & label
+ QPixmap image0( QAD_Desktop::getResourceManager()->loadPixmap( "SMESH",tr( "ICON_SELECT" ) ) );
+ mySelectBtn = new QPushButton( this, "mySelectBtn" );
+ mySelectBtn->setPixmap( image0 );
+ mySelectBtn->setSizePolicy( QSizePolicy( QSizePolicy::Fixed, QSizePolicy::Fixed ) );
+
+ mySelectLab = new QLabel( this, "mySelectLab" );
+ mySelectLab->setAlignment( AlignCenter );
+ QFont fnt = mySelectLab->font(); fnt.setBold( true );
+ mySelectLab->setFont( fnt );
+
+ QHBoxLayout* aSelectLayout = new QHBoxLayout;
+ aSelectLayout->setMargin( 0 ); aSelectLayout->setSpacing( 0 );
+ aSelectLayout->addWidget( mySelectBtn );
+ aSelectLayout->addWidget( mySelectLab );
+
+ // top widget stack
+ myWGStack = new QWidgetStack( this );
+
+ // no valid selection
+ QWidget* myBadWidget = new QWidget( myWGStack );
+ QVBoxLayout* aBadLayout = new QVBoxLayout( myBadWidget );
+ QLabel* myBadLab = new QLabel( tr( "SMESH_BAD_SELECTION" ), myBadWidget, "myBadLab" );
+ myBadLab->setAlignment( Qt::AlignCenter );
+ myBadLab->setSizePolicy( QSizePolicy( QSizePolicy::Expanding, QSizePolicy::Expanding ) );
+ aBadLayout->addWidget( myBadLab );
+ myWGStack->addWidget( myBadWidget, 0 );
+
+ // mesh
+ myMeshWidget = new QWidget( myWGStack );
+ QGridLayout* aMeshLayout = new QGridLayout( myMeshWidget );
+ aMeshLayout->setSpacing( 6 ); aMeshLayout->setMargin( 0 );
+ myWGStack->addWidget( myMeshWidget );
+
+ // --> name
+ QLabel* myMeshNameLab = new QLabel( COLONIZE( tr( "SMESH_MESHINFO_NAME" ) ), myMeshWidget, "myMeshNameLab" );
+ myMeshName = new QLabel( myMeshWidget, "myMeshName" );
+ myMeshName->setMinimumWidth( 100 );
+ QFrame* line1 = new QFrame( myMeshWidget );
+ line1->setFrameStyle( QFrame::HLine | QFrame::Sunken );
+
+ // --> nodes
+ QLabel* myMeshNbNodesLab = new QLabel( COLONIZE( tr( "SMESH_MESHINFO_NODES" ) ), myMeshWidget, "myMeshNbNodesLab" );
+ myMeshNbNodes = new QLabel( myMeshWidget, "myMeshNbNodes" );
+ myMeshNbNodes->setMinimumWidth( 100 );
+
+ // --> edges
+ QLabel* myMeshNbEdgesLab = new QLabel( COLONIZE( tr( "SMESH_MESHINFO_EDGES" ) ), myMeshWidget, "myMeshNbEdgesLab" );
+ myMeshNbEdges = new QLabel( myMeshWidget, "myMeshNbEdges" );
+ myMeshNbEdges->setMinimumWidth( 100 );
+
+ // --> faces
+ myMeshFacesGroup = new QGroupBox( tr( "SMESH_MESHINFO_FACES" ), myMeshWidget, "myMeshFacesGroup" );
+ myMeshFacesGroup->setColumnLayout(0, Qt::Vertical );
+ myMeshFacesGroup->layout()->setSpacing( 0 ); myMeshFacesGroup->layout()->setMargin( 0 );
+ QGridLayout* myMeshFacesGroupLayout = new QGridLayout( myMeshFacesGroup->layout() );
+ myMeshFacesGroupLayout->setAlignment( Qt::AlignTop );
+ myMeshFacesGroupLayout->setSpacing( 6 ); myMeshFacesGroupLayout->setMargin( 11 );
+
+ // --> faces --> total
+ QLabel* myMeshNbFacesLab = new QLabel( COLONIZE( tr( "SMESH_MESHINFO_TOTAL" ) ), myMeshFacesGroup, "myMeshNbFacesLab" );
+ myMeshNbFacesLab->setFont( fnt );
+ myMeshNbFaces = new QLabel( myMeshFacesGroup, "myMeshNbFaces" );
+ myMeshNbFaces->setMinimumWidth( 100 );
+ myMeshNbFaces->setFont( fnt );
+
+ // --> faces --> triangles
+ QLabel* myMeshNbTrianglesLab = new QLabel( COLONIZE( tr( "SMESH_MESHINFO_TRIANGLES" ) ), myMeshFacesGroup, "myMeshNbTrianglesLab" );
+ myMeshNbTriangles = new QLabel( myMeshFacesGroup, "myMeshNbTriangles" );
+ myMeshNbTriangles->setMinimumWidth( 100 );
+
+ // --> faces --> quadrangles
+ QLabel* myMeshNbQuadranglesLab = new QLabel( COLONIZE( tr( "SMESH_MESHINFO_QUADRANGLES" ) ), myMeshFacesGroup, "myMeshNbQuadranglesLab" );
+ myMeshNbQuadrangles = new QLabel( myMeshFacesGroup, "myMeshNbQuadrangles" );
+ myMeshNbQuadrangles->setMinimumWidth( 100 );
+
+ myMeshFacesGroupLayout->addWidget( myMeshNbFacesLab, 0, 0 );
+ myMeshFacesGroupLayout->addWidget( myMeshNbFaces, 0, 1 );
+ myMeshFacesGroupLayout->addWidget( myMeshNbTrianglesLab, 1, 0 );
+ myMeshFacesGroupLayout->addWidget( myMeshNbTriangles, 1, 1 );
+ myMeshFacesGroupLayout->addWidget( myMeshNbQuadranglesLab, 2, 0 );
+ myMeshFacesGroupLayout->addWidget( myMeshNbQuadrangles, 2, 1 );
+
+ // --> volumes
+ myMeshVolumesGroup = new QGroupBox( tr( "SMESH_MESHINFO_VOLUMES" ), myMeshWidget, "myMeshVolumesGroup" );
+ myMeshVolumesGroup->setColumnLayout(0, Qt::Vertical );
+ myMeshVolumesGroup->layout()->setSpacing( 0 ); myMeshVolumesGroup->layout()->setMargin( 0 );
+ QGridLayout* myMeshVolumesGroupLayout = new QGridLayout( myMeshVolumesGroup->layout() );
+ myMeshVolumesGroupLayout->setAlignment( Qt::AlignTop );
+ myMeshVolumesGroupLayout->setSpacing( 6 ); myMeshVolumesGroupLayout->setMargin( 11 );
+
+ // --> volumes --> total
+ QLabel* myMeshNbVolumesLab = new QLabel( COLONIZE( tr( "SMESH_MESHINFO_TOTAL" ) ), myMeshVolumesGroup, "myMeshNbVolumesLab" );
+ myMeshNbVolumesLab->setFont( fnt );
+ myMeshNbVolumes = new QLabel( myMeshVolumesGroup, "myMeshNbVolumes" );
+ myMeshNbVolumes->setMinimumWidth( 100 );
+ myMeshNbVolumes->setFont( fnt );
+
+ // --> volumes --> tetrahedrons
+ QLabel* myMeshNbTetraLab = new QLabel( COLONIZE( tr( "SMESH_MESHINFO_TETRAS" ) ), myMeshVolumesGroup, "myMeshNbTetraLab" );
+ myMeshNbTetra = new QLabel( myMeshVolumesGroup, "myMeshNbTetra" );
+ myMeshNbTetra->setMinimumWidth( 100 );
+
+ // --> volumes --> hexahedrons
+ QLabel* myMeshNbHexaLab = new QLabel( COLONIZE( tr( "SMESH_MESHINFO_HEXAS" ) ), myMeshVolumesGroup, "myMeshNbHexaLab" );
+ myMeshNbHexa = new QLabel( myMeshVolumesGroup, "myMeshNbHexa" );
+ myMeshNbHexaLab->setMinimumWidth( 100 );
+
+ // --> volumes --> prisms
+ QLabel* myMeshNbPrismLab = new QLabel( COLONIZE( tr( "SMESH_MESHINFO_PRISMS" ) ), myMeshVolumesGroup, "myMeshNbPrismLab" );
+ myMeshNbPrism = new QLabel( myMeshVolumesGroup, "myMeshNbPrism" );
+ myMeshNbPrism->setMinimumWidth( 100 );
+
+ // --> volumes --> pyramids
+ QLabel* myMeshNbPyraLab = new QLabel( COLONIZE( tr( "SMESH_MESHINFO_PYRAS" ) ), myMeshVolumesGroup, "myMeshNbPyraLab" );
+ myMeshNbPyra = new QLabel( myMeshVolumesGroup, "myMeshNbPyra" );
+ myMeshNbPyra->setMinimumWidth( 100 );
+
+ myMeshVolumesGroupLayout->addWidget( myMeshNbVolumesLab, 0, 0 );
+ myMeshVolumesGroupLayout->addWidget( myMeshNbVolumes, 0, 1 );
+ myMeshVolumesGroupLayout->addWidget( myMeshNbTetraLab, 1, 0 );
+ myMeshVolumesGroupLayout->addWidget( myMeshNbTetra, 1, 1 );
+ myMeshVolumesGroupLayout->addWidget( myMeshNbHexaLab, 2, 0 );
+ myMeshVolumesGroupLayout->addWidget( myMeshNbHexa, 2, 1 );
+ myMeshVolumesGroupLayout->addWidget( myMeshNbPrismLab, 3, 0 );
+ myMeshVolumesGroupLayout->addWidget( myMeshNbPrism, 3, 1 );
+ myMeshVolumesGroupLayout->addWidget( myMeshNbPyraLab, 4, 0 );
+ myMeshVolumesGroupLayout->addWidget( myMeshNbPyra, 4, 1 );
+
+ aMeshLayout->addWidget( myMeshNameLab, 0, 0 );
+ aMeshLayout->addWidget( myMeshName, 0, 1 );
+ aMeshLayout->addMultiCellWidget( line1, 1, 1, 0, 1 );
+ aMeshLayout->addWidget( myMeshNbNodesLab, 2, 0 );
+ aMeshLayout->addWidget( myMeshNbNodes, 2, 1 );
+ aMeshLayout->addWidget( myMeshNbEdgesLab, 3, 0 );
+ aMeshLayout->addWidget( myMeshNbEdges, 3, 1 );
+ aMeshLayout->addMultiCellWidget( myMeshFacesGroup, 4, 4, 0, 1 );
+ aMeshLayout->addMultiCellWidget( myMeshVolumesGroup, 5, 5, 0, 1 );
+ aMeshLayout->addItem( new QSpacerItem( 5, 5, QSizePolicy::Minimum, QSizePolicy::Expanding ), 6, 0 );
+
+ // submesh
+ mySubMeshWidget = new QWidget( myWGStack );
+ QGridLayout* aSubMeshLayout = new QGridLayout( mySubMeshWidget );
+ aSubMeshLayout->setSpacing( 6 ); aSubMeshLayout->setMargin( 0 );
+ myWGStack->addWidget( mySubMeshWidget );
+
+ // --> name
+ QLabel* mySubMeshNameLab = new QLabel( COLONIZE( tr( "SMESH_MESHINFO_NAME" ) ), mySubMeshWidget, "mySubMeshNameLab" );
+ mySubMeshName = new QLabel( mySubMeshWidget, "mySubMeshName" );
+ mySubMeshName->setMinimumWidth( 100 );
+ QFrame* line2 = new QFrame( mySubMeshWidget );
+ line2->setFrameStyle( QFrame::HLine | QFrame::Sunken );
+
+ // --> nodes
+ QLabel* mySubMeshNbNodesLab = new QLabel( COLONIZE( tr( "SMESH_MESHINFO_NODES" ) ), mySubMeshWidget, "mySubMeshNbNodesLab" );
+ mySubMeshNbNodes = new QLabel( mySubMeshWidget, "mySubMeshNbNodes" );
+ mySubMeshNbNodes->setMinimumWidth( 100 );
+
+ // --> elements
+ mySubMeshElementsGroup = new QGroupBox( tr( "SMESH_MESHINFO_ELEMENTS" ), mySubMeshWidget, "mySubMeshElementsGroup" );
+ mySubMeshElementsGroup->setColumnLayout(0, Qt::Vertical );
+ mySubMeshElementsGroup->layout()->setSpacing( 0 ); mySubMeshElementsGroup->layout()->setMargin( 0 );
+ QGridLayout* mySubMeshElementsGroupLayout = new QGridLayout( mySubMeshElementsGroup->layout() );
+ mySubMeshElementsGroupLayout->setAlignment( Qt::AlignTop );
+ mySubMeshElementsGroupLayout->setSpacing( 6 ); mySubMeshElementsGroupLayout->setMargin( 11 );
+
+ // --> elements --> total
+ QLabel* mySubMeshNbElementsLab = new QLabel( COLONIZE( tr( "SMESH_MESHINFO_TOTAL" ) ), mySubMeshElementsGroup, "mySubMeshNbElementsLab" );
+ mySubMeshNbElementsLab->setFont( fnt );
+ mySubMeshNbElements = new QLabel( mySubMeshElementsGroup, "mySubMeshNbElements" );
+ mySubMeshNbElements->setMinimumWidth( 100 );
+ mySubMeshNbElements->setFont( fnt );
+
+ // --> elements --> edges
+ QLabel* mySubMeshNbEdgesLab = new QLabel( COLONIZE( tr( "SMESH_MESHINFO_EDGES" ) ), mySubMeshElementsGroup, "mySubMeshNbEdgesLab" );
+ mySubMeshNbEdges = new QLabel( mySubMeshElementsGroup, "mySubMeshNbEdges" );
+ mySubMeshNbEdges->setMinimumWidth( 100 );
+
+ // --> elements --> faces
+ QLabel* mySubMeshNbFacesLab = new QLabel( COLONIZE( tr( "SMESH_MESHINFO_FACES" ) ), mySubMeshElementsGroup, "mySubMeshNbFacesLab" );
+ mySubMeshNbFaces = new QLabel( mySubMeshElementsGroup, "mySubMeshNbFaces" );
+ mySubMeshNbFaces->setMinimumWidth( 100 );
+
+ // --> elements --> volumes
+ QLabel* mySubMeshNbVolumesLab = new QLabel( COLONIZE( tr( "SMESH_MESHINFO_VOLUMES" ) ), mySubMeshElementsGroup, "mySubMeshNbVolumesLab" );
+ mySubMeshNbVolumes = new QLabel( mySubMeshElementsGroup, "mySubMeshNbVolumes" );
+ mySubMeshNbVolumes->setMinimumWidth( 100 );
+
+ mySubMeshElementsGroupLayout->addWidget( mySubMeshNbElementsLab, 0, 0 );
+ mySubMeshElementsGroupLayout->addWidget( mySubMeshNbElements, 0, 1 );
+ mySubMeshElementsGroupLayout->addWidget( mySubMeshNbEdgesLab, 1, 0 );
+ mySubMeshElementsGroupLayout->addWidget( mySubMeshNbEdges, 1, 1 );
+ mySubMeshElementsGroupLayout->addWidget( mySubMeshNbFacesLab, 2, 0 );
+ mySubMeshElementsGroupLayout->addWidget( mySubMeshNbFaces, 2, 1 );
+ mySubMeshElementsGroupLayout->addWidget( mySubMeshNbVolumesLab, 3, 0 );
+ mySubMeshElementsGroupLayout->addWidget( mySubMeshNbVolumes, 3, 1 );
+
+ aSubMeshLayout->addWidget( mySubMeshNameLab, 0, 0 );
+ aSubMeshLayout->addWidget( mySubMeshName, 0, 1 );
+ aSubMeshLayout->addMultiCellWidget( line2, 1, 1, 0, 1 );
+ aSubMeshLayout->addWidget( mySubMeshNbNodesLab, 2, 0 );
+ aSubMeshLayout->addWidget( mySubMeshNbNodes, 2, 1 );
+ aSubMeshLayout->addMultiCellWidget( mySubMeshElementsGroup, 3, 3, 0, 1 );
+ aSubMeshLayout->addItem( new QSpacerItem( 5, 5, QSizePolicy::Minimum, QSizePolicy::Expanding ), 4, 0 );
+
+ // group
+ myGroupWidget = new QWidget( myWGStack );
+ QGridLayout* myGroupWidgetLayout = new QGridLayout( myGroupWidget );
+ myGroupWidgetLayout->setSpacing( 6 ); myGroupWidgetLayout->setMargin( 0 );
+ myWGStack->addWidget( myGroupWidget );
+
+ // --> name
+ QLabel* myGroupNameLab = new QLabel( COLONIZE( tr( "SMESH_MESHINFO_NAME" ) ), myGroupWidget, "myGroupNameLab" );
+ myGroupName = new QLabel( myGroupWidget, "myGroupName" );
+ myGroupName->setMinimumWidth( 100 );
+ QFrame* line3 = new QFrame( myGroupWidget );
+ line3->setFrameStyle( QFrame::HLine | QFrame::Sunken );
+
+ // --> type
+ QLabel* myGroupTypeLab = new QLabel( COLONIZE( tr( "SMESH_MESHINFO_TYPE" ) ), myGroupWidget, "myGroupTypeLab" );
+ myGroupType = new QLabel( myGroupWidget, "myGroupType" );
+ myGroupType->setMinimumWidth( 100 );
+
+ // --> number of entities
+ QLabel* myGroupNbLab = new QLabel( COLONIZE( tr( "SMESH_MESHINFO_ENTITIES" ) ), myGroupWidget, "myGroupNbLab" );
+ myGroupNb = new QLabel( myGroupWidget, "myGroupNb" );
+ myGroupNb->setMinimumWidth( 100 );
+
+ myGroupWidgetLayout->addWidget( myGroupNameLab, 0, 0 );
+ myGroupWidgetLayout->addWidget( myGroupName, 0, 1 );
+ myGroupWidgetLayout->addMultiCellWidget( line3, 1, 1, 0, 1 );
+ myGroupWidgetLayout->addWidget( myGroupTypeLab, 2, 0 );
+ myGroupWidgetLayout->addWidget( myGroupType, 2, 1 );
+ myGroupWidgetLayout->addWidget( myGroupNbLab, 3, 0 );
+ myGroupWidgetLayout->addWidget( myGroupNb, 3, 1 );
+ myGroupWidgetLayout->addItem( new QSpacerItem( 5, 5, QSizePolicy::Minimum, QSizePolicy::Expanding ), 4, 0 );
+
+ // buttons
+ myButtonsGroup = new QGroupBox( this, "myButtonsGroup" );
+ myButtonsGroup->setColumnLayout(0, Qt::Vertical );
+ myButtonsGroup->layout()->setSpacing( 0 ); myButtonsGroup->layout()->setMargin( 0 );
+ QHBoxLayout* myButtonsGroupLayout = new QHBoxLayout( myButtonsGroup->layout() );
+ myButtonsGroupLayout->setAlignment( Qt::AlignTop );
+ myButtonsGroupLayout->setSpacing( 6 ); myButtonsGroupLayout->setMargin( 11 );
+
+ // buttons --> OK button
+ myOkBtn = new QPushButton( tr( "SMESH_BUT_OK" ), myButtonsGroup, "myOkBtn" );
+ myOkBtn->setAutoDefault( TRUE ); myOkBtn->setDefault( TRUE );
+ myButtonsGroupLayout->addStretch();
+ myButtonsGroupLayout->addWidget( myOkBtn );
+ myButtonsGroupLayout->addStretch();
+
+ aTopLayout->addLayout( aSelectLayout );
+ aTopLayout->addWidget( myWGStack );
+ aTopLayout->addWidget( myButtonsGroup );
+
+ mySelection = SALOME_Selection::Selection( SMESHGUI::GetSMESHGUI()->GetActiveStudy()->getSelection() );
+ SMESHGUI::GetSMESHGUI()->SetActiveDialogBox( this ) ;
+
+ // connect signals
+ connect( myOkBtn, SIGNAL( clicked() ), this, SLOT( close() ) );
+ connect( mySelectBtn, SIGNAL( clicked() ), this, SLOT( onStartSelection() ) );
+ connect( SMESHGUI::GetSMESHGUI(), SIGNAL( SignalCloseAllDialogs() ), this, SLOT( close() ) ) ;
+ connect( SMESHGUI::GetSMESHGUI(), SIGNAL( SignalDeactivateActiveDialog() ), this, SLOT( DeactivateActiveDialog() ) ) ;
+ connect( mySelection, SIGNAL( currentSelectionChanged() ), this, SLOT( onSelectionChanged() ) );
+
+ // resize and move dialog, then show
+ int x, y;
+ SMESHGUI::GetSMESHGUI()->DefineDlgPosition( this, x, y );
+ this->move( x, y );
+ this->show();
+
+ // init dialog with current selection
+ onSelectionChanged();
}
//=================================================================================
-// function : genEdgeKey
-// purpose : edge counting helper;
-// packs two long integers into one 8-byte value (treated as double by the caller);
-// the order of arguments is insignificant
+/*!
+ * SMESHGUI_MeshInfosDlg::~SMESHGUI_MeshInfosDlg
+ *
+ * Destructor
+ */
//=================================================================================
-void genEdgeKey(long a, long b, void* key)
+SMESHGUI_MeshInfosDlg::~SMESHGUI_MeshInfosDlg()
{
- long* lKey = (long*)key;
- *lKey = (a < b) ? a : b;
- *(++lKey) = (a < b) ? b : a;
}
//=================================================================================
-// function : DumpMeshInfos()
-// purpose :
+/*!
+ * SMESHGUI_MeshInfosDlg::DumpMeshInfos
+ */
//=================================================================================
void SMESHGUI_MeshInfosDlg::DumpMeshInfos()
{
- int nbOfNodes = myMesh->NbNodes();
- int nbOfEdges = myMesh->NbEdges();
- int nbOfTriangles = myMesh->NbTriangles();
- int nbOfQuadrangles = myMesh->NbQuadrangles();
- int nbOfTetras = myMesh->NbTetras();
- int nbOfHexas = myMesh->NbHexas();
-
- /*
- int nbOfNodes = 0 ;
- int nbOfEdges = 0 ;
- int nbOfTriangles = 0 ;
- int nbOfQuadrangles = 0 ;
- int nbOfTetras = 0 ;
- int nbOfHexas = 0 ;
- int nbCells = 0 ;
- int CellType = 0 ;
- QMap<double, char> aMapOfEdges;
-
- Standard_Boolean result;
- SMESH_Actor* MeshActor = mySMESHGUI->FindActor(myMesh, result, true);
-
- if ( result ) {
- vtkUnstructuredGrid* ugrid = vtkUnstructuredGrid::SafeDownCast( MeshActor->DataSource );
- vtkPoints *Pts = ugrid->GetPoints();
- nbOfNodes = Pts->GetNumberOfPoints();
- int nbCells = ugrid->GetNumberOfCells();
-
- for ( int i = 0; i < nbCells; i++ ) {
- vtkCell* cellPtr = ugrid->GetCell(i);
- CellType = cellPtr->GetCellType();
- switch (CellType)
- {
- case 3: //Edges
- {
- nbOfEdges++;
- break;
- }
- case 5: //Triangles
- {
- nbOfTriangles++;
-
- for (int edgeNum = 0; edgeNum < 3; edgeNum++) {
- vtkCell* edgePtr = cellPtr->GetEdge(edgeNum);
- double anEdgeKey;
- genEdgeKey(edgePtr->GetPointId(0), edgePtr->GetPointId(1), &anEdgeKey);
- if (!aMapOfEdges.contains(anEdgeKey)) {
- nbOfEdges++;
- aMapOfEdges.insert(anEdgeKey, 0);
- }
- }
- break;
- }
- case 9: //Quadrangles
- {
- nbOfQuadrangles++;
-
- for (int edgeNum = 0; edgeNum < 4; edgeNum++) {
- vtkCell* edgePtr = cellPtr->GetEdge(edgeNum);
- double anEdgeKey;
- genEdgeKey(edgePtr->GetPointId(0), edgePtr->GetPointId(1), &anEdgeKey);
- if (!aMapOfEdges.contains(anEdgeKey)) {
- nbOfEdges++;
- aMapOfEdges.insert(anEdgeKey, 0);
- }
- }
- break;
- }
- case 10: //Tetraedras
- {
- nbOfTetras++;
-
- for (int edgeNum = 0; edgeNum < 6; edgeNum++) {
- vtkCell* edgePtr = cellPtr->GetEdge(edgeNum);
- double anEdgeKey;
- genEdgeKey(edgePtr->GetPointId(0), edgePtr->GetPointId(1), &anEdgeKey);
- if (!aMapOfEdges.contains(anEdgeKey)) {
- nbOfEdges++;
- aMapOfEdges.insert(anEdgeKey, 0);
- }
- }
- break;
- }
- case 12: //Hexahedras
- {
- nbOfHexas++;
-
- for (int edgeNum = 0; edgeNum < 12; edgeNum++) {
- vtkCell* edgePtr = cellPtr->GetEdge(edgeNum);
- double anEdgeKey;
- genEdgeKey(edgePtr->GetPointId(0), edgePtr->GetPointId(1), &anEdgeKey);
- if (!aMapOfEdges.contains(anEdgeKey)) {
- nbOfEdges++;
- aMapOfEdges.insert(anEdgeKey, 0);
- }
- }
- break;
+ QAD_WaitCursor wc;
+ int nbSel = mySelection->IObjectCount();
+ if ( nbSel == 1 ) {
+ myStartSelection = false;
+ mySelectLab->setText( "" );
+ Handle(SALOME_InteractiveObject) IObject = mySelection->firstIObject();
+ SALOMEDS::SObject_var aSO = SMESHGUI::GetSMESHGUI()->GetStudy()->FindObjectID( IObject->getEntry() );
+ if ( !aSO->_is_nil() ) {
+ CORBA::Object_var anObject = aSO->GetObject();
+ if ( !CORBA::is_nil( anObject ) ) {
+ SMESH::SMESH_Mesh_var aMesh = SMESH::SMESH_Mesh::_narrow( anObject );
+ if ( !aMesh->_is_nil() ) {
+ myWGStack->raiseWidget( myMeshWidget );
+ setCaption( tr( "SMESH_MESHINFO_TITLE" ) + " [" + tr("SMESH_OBJECT_MESH") +"]" );
+ myMeshName->setText( aSO->GetName() );
+ myMeshNbNodes->setNum( (int)aMesh->NbNodes() );
+ myMeshNbEdges->setNum( (int)aMesh->NbEdges() );
+ myMeshNbFaces->setNum( (int)aMesh->NbFaces() );
+ myMeshNbTriangles->setNum( (int)aMesh->NbTriangles() );
+ myMeshNbQuadrangles->setNum( (int)aMesh->NbQuadrangles() );
+ myMeshNbVolumes->setNum( (int)aMesh->NbVolumes() );
+ myMeshNbTetra->setNum( (int)aMesh->NbTetras() );
+ myMeshNbHexa->setNum( (int)aMesh->NbHexas() );
+ myMeshNbPrism->setNum( (int)aMesh->NbPrisms() );
+ myMeshNbPyra->setNum( (int)aMesh->NbPyramids() );
+ return;
+ }
+ SMESH::SMESH_subMesh_var aSubMesh = SMESH::SMESH_subMesh::_narrow( anObject );
+ if ( !aSubMesh->_is_nil() ) {
+ myWGStack->raiseWidget( mySubMeshWidget );
+ setCaption( tr( "SMESH_MESHINFO_TITLE" ) + " [" + tr("SMESH_SUBMESH") +"]" );
+ mySubMeshName->setText( aSO->GetName() );
+ mySubMeshNbNodes->setNum( (int)aSubMesh->GetNumberOfNodes() );
+ mySubMeshNbElements->setNum( (int)aSubMesh->GetNumberOfElements() );
+ mySubMeshNbEdges->setNum( (int)( aSubMesh->GetElementsByType( SMESH::EDGE )->length() ) );
+ mySubMeshNbFaces->setNum( (int)( aSubMesh->GetElementsByType( SMESH::FACE )->length() ) );
+ mySubMeshNbVolumes->setNum( (int)( aSubMesh->GetElementsByType( SMESH::VOLUME )->length() ) );
+ return;
+ }
+ SMESH::SMESH_Group_var aGroup = SMESH::SMESH_Group::_narrow( anObject );
+ if ( !aGroup->_is_nil() ) {
+ myWGStack->raiseWidget( myGroupWidget );
+ setCaption( tr( "SMESH_MESHINFO_TITLE" ) + " [" + tr("SMESH_GROUP") +"]" );
+ myGroupName->setText( aSO->GetName() );
+ int aType = aGroup->GetType();
+ QString strType;
+ switch ( aType ) {
+ case SMESH::NODE:
+ strType = "SMESH_MESHINFO_NODES"; break;
+ case SMESH::EDGE:
+ strType = "SMESH_MESHINFO_EDGES"; break;
+ case SMESH::FACE:
+ strType = "SMESH_MESHINFO_FACES"; break;
+ case SMESH::VOLUME:
+ strType = "SMESH_MESHINFO_VOLUMES"; break;
+ default:
+ strType = "SMESH_MESHINFO_ALL_TYPES"; break;
}
+
+ myGroupType->setText( tr( strType ) );
+ myGroupNb->setNum( (int)aGroup->Size() );
+ return;
}
+ }
}
}
- */
- TextLabel13->setText( tr( "%1" ).arg(nbOfNodes) );
- TextLabel14->setText( tr( "%1" ).arg(nbOfEdges) );
- TextLabel23->setText( tr( "%1" ).arg(nbOfTriangles) );
- TextLabel24->setText( tr( "%1" ).arg(nbOfQuadrangles) );
- TextLabel33->setText( tr( "%1" ).arg(nbOfTetras) );
- TextLabel34->setText( tr( "%1" ).arg(nbOfHexas) );
-}
-
-//=================================================================================
-// function : ClickOnOk()
-// purpose :
-//=================================================================================
-void SMESHGUI_MeshInfosDlg::ClickOnOk()
-{
- disconnect( mySelection, 0, this, 0 );
- mySMESHGUI->ResetState() ;
- reject() ;
- return ;
+ myWGStack->raiseWidget( 0 );
+ setCaption( tr( "SMESH_MESHINFO_TITLE" ) );
}
//=================================================================================
// function : SelectionIntoArgument()
// purpose : Called when selection has changed
//=================================================================================
-void SMESHGUI_MeshInfosDlg::SelectionIntoArgument()
+void SMESHGUI_MeshInfosDlg::onSelectionChanged()
{
- TextLabel13->setText( "0" );
- TextLabel14->setText( "0" );
- TextLabel23->setText( "0" );
- TextLabel24->setText( "0" );
- TextLabel33->setText( "0" );
- TextLabel34->setText( "0" );
-
- int nbSel = mySelection->IObjectCount();
- if ( nbSel == 1 ) {
- Handle(SALOME_InteractiveObject) IObject = mySelection->firstIObject();
- Standard_Boolean res;
- myMesh = mySMESHGUI->ConvertIOinMesh( IObject, res );
- if ( res )
- DumpMeshInfos();
- }
- return ;
+ if ( myStartSelection )
+ DumpMeshInfos();
}
//=================================================================================
void SMESHGUI_MeshInfosDlg::closeEvent( QCloseEvent* e )
{
- disconnect( mySelection, 0, this, 0 );
- mySMESHGUI->ResetState() ;
- reject() ;
- return ;
+ SMESHGUI::GetSMESHGUI()->ResetState();
+ QDialog::closeEvent( e );
}
//=================================================================================
-// function : enterEvent()
-// purpose : when mouse enter onto the QWidget
+// function : windowActivationChange()
+// purpose : called when window is activated/deactivated
//=================================================================================
-void SMESHGUI_MeshInfosDlg::enterEvent( QEvent * )
+void SMESHGUI_MeshInfosDlg::windowActivationChange( bool oldActive )
{
- ActivateThisDialog() ;
+ QDialog::windowActivationChange( oldActive );
+ if ( isActiveWindow() && myIsActiveWindow != isActiveWindow() )
+ ActivateThisDialog() ;
+ myIsActiveWindow = isActiveWindow();
}
void SMESHGUI_MeshInfosDlg::DeactivateActiveDialog()
{
disconnect( mySelection, 0, this, 0 );
-
- return ;
}
void SMESHGUI_MeshInfosDlg::ActivateThisDialog()
{
/* Emit a signal to deactivate any active dialog */
- mySMESHGUI->EmitSignalDeactivateDialog() ;
-
- return ;
+ SMESHGUI::GetSMESHGUI()->EmitSignalDeactivateDialog() ;
+ connect( mySelection, SIGNAL( currentSelectionChanged() ), this, SLOT( onSelectionChanged() ) );
}
+//=================================================================================
+// function : onStartSelection()
+// purpose : starts selection
+//=================================================================================
+void SMESHGUI_MeshInfosDlg::onStartSelection()
+{
+ myStartSelection = true;
+ onSelectionChanged();
+ myStartSelection = true;
+ mySelectLab->setText( tr( "INF_SELECT_OBJECT" ) );
+}
#ifndef SMESHGUI_MESHINFOSDLG_H
#define SMESHGUI_MESHINFOSDLG_H
-#include "SALOME_Selection.h"
-#include "QAD_Study.h"
-
// IDL Headers
#include <SALOMEconfig.h>
#include CORBA_SERVER_HEADER(SMESH_Gen)
#include CORBA_SERVER_HEADER(SMESH_Mesh)
// QT Includes
-#include <qvariant.h>
#include <qdialog.h>
-class QVBoxLayout;
-class QHBoxLayout;
-class QGridLayout;
+
class QGroupBox;
class QLabel;
class QPushButton;
-class SMESHGUI;
+class SALOME_Selection;
+class QWidgetStack;
class SMESHGUI_MeshInfosDlg : public QDialog
{
Q_OBJECT
public:
- SMESHGUI_MeshInfosDlg( QWidget* parent = 0, const char* name = 0, SALOME_Selection* Sel = 0, bool modal = FALSE, WFlags fl = 0 );
+ SMESHGUI_MeshInfosDlg( QWidget* parent = 0, const char* name = 0, bool modal = FALSE, WFlags fl = 0 );
~SMESHGUI_MeshInfosDlg();
-private:
-
- void Init( SALOME_Selection* Sel ) ;
- void closeEvent( QCloseEvent* e ) ;
- void enterEvent ( QEvent * ) ; /* mouse enter the QWidget */
+protected:
+ void closeEvent( QCloseEvent* e );
+ void windowActivationChange( bool oldActive );
void DumpMeshInfos();
- SMESH::SMESH_Gen_var myCompMesh ;
- SMESHGUI* mySMESHGUI ;
- SMESH::SMESH_Mesh_var myMesh ;
- SALOME_Selection* mySelection ;
- SALOMEDS::Study_var myStudy;
+private slots:
+ void onSelectionChanged();
+ void DeactivateActiveDialog() ;
+ void ActivateThisDialog();
+ void onStartSelection();
- QGroupBox* GroupBox1;
- QLabel* TextLabel12;
- QLabel* TextLabel11;
- QLabel* TextLabel13;
- QLabel* TextLabel14;
- QGroupBox* GroupBox2;
- QLabel* TextLabel21;
- QLabel* TextLabel22;
- QLabel* TextLabel23;
- QLabel* TextLabel24;
- QGroupBox* GroupBox3;
- QLabel* TextLabel31;
- QLabel* TextLabel32;
- QLabel* TextLabel33;
- QLabel* TextLabel34;
- QPushButton* buttonOk;
+private:
+ SALOME_Selection* mySelection;
+ bool myStartSelection;
+ bool myIsActiveWindow;
+
+ QPushButton* mySelectBtn;
+ QLabel* mySelectLab;
-private slots:
+ QWidgetStack* myWGStack;
- void ClickOnOk();
- void SelectionIntoArgument() ;
- void DeactivateActiveDialog() ;
- void ActivateThisDialog() ;
+ QWidget* myMeshWidget;
+ QLabel* myMeshName;
+ QLabel* myMeshNbNodes;
+ QLabel* myMeshNbEdges;
+ QGroupBox* myMeshFacesGroup;
+ QLabel* myMeshNbFaces;
+ QLabel* myMeshNbTriangles;
+ QLabel* myMeshNbQuadrangles;
+ QGroupBox* myMeshVolumesGroup;
+ QLabel* myMeshNbVolumes;
+ QLabel* myMeshNbTetra;
+ QLabel* myMeshNbHexa;
+ QLabel* myMeshNbPyra;
+ QLabel* myMeshNbPrism;
+
+ QWidget* mySubMeshWidget;
+ QLabel* mySubMeshName;
+ QLabel* mySubMeshNbNodes;
+ QGroupBox* mySubMeshElementsGroup;
+ QLabel* mySubMeshNbElements;
+ QLabel* mySubMeshNbEdges;
+ QLabel* mySubMeshNbFaces;
+ QLabel* mySubMeshNbVolumes;
-protected:
- QVBoxLayout* SMESHGUI_MeshInfosDlgLayout;
- QHBoxLayout* Layout1;
+ QWidget* myGroupWidget;
+ QLabel* myGroupName;
+ QLabel* myGroupType;
+ QLabel* myGroupNb;
+ QGroupBox* myButtonsGroup;
+ QPushButton* myOkBtn;
};
#endif // SMESHGUI_MESHINFOSDLG_H
// Module : SMESH
// $Header$
-using namespace std;
#include "SMESHGUI_MoveNodesDlg.h"
-#include "SMESHGUI.h"
#include "SMESHGUI_SpinBox.h"
+#include "SMESH_Actor.h"
+#include "SMESHGUI.h"
#include "QAD_Application.h"
#include "QAD_Desktop.h"
// Open CASCADE Include
#include <TColStd_MapIteratorOfMapOfInteger.hxx>
-// VTK Include
-#include <vtkActor.h>
+using namespace std;
//=================================================================================
// class : SMESHGUI_MoveNodesDlg()
//=================================================================================
void SMESHGUI_MoveNodesDlg::ClickOnCancel()
{
- QAD_Application::getDesktop()->SetSelectionMode( 4 );
+ QAD_Application::getDesktop()->SetSelectionMode( ActorSelection );
disconnect( mySelection, 0, this, 0 );
mySMESHGUI->ResetState() ;
mySMESHGUI->EraseSimulationActors();
return ;
}
- if ( mySelection->SelectionMode() != 1 ){
+ if ( mySelection->SelectionMode() != NodeSelection ){
QAD_MessageBox::warn1 ( QAD_Application::getDesktop(), tr ("SMESH_WRN_WARNING"),
- tr ("SMESH_WRN_SELECTIONMODE_NODES"), tr ("SMESH_BUT_YES") );
+ tr ("SMESH_WRN_SELECTIONMODE_NODES"), tr ("SMESH_BUT_OK") );
return;
}
//=======================================================================
void SMESHGUI_NodesDlg::ClickOnCancel()
{
- QAD_Application::getDesktop()->SetSelectionMode( 4 );
+ QAD_Application::getDesktop()->SetSelectionMode( ActorSelection );
disconnect( mySelection, 0, this, 0 );
myMeshGUI->ResetState() ;
myMeshGUI->EraseSimulationActors() ;
return ;
}
- if ( mySelection->SelectionMode() != 1 ) {
+ if ( mySelection->SelectionMode() != NodeSelection ) {
SpinBox_X->SetValue(0.0) ;
SpinBox_Y->SetValue(0.0) ;
SpinBox_Z->SetValue(0.0) ;
QAD_MessageBox::warn1 ( QAD_Application::getDesktop(), tr ("SMESH_WRN_WARNING"),
- tr ("SMESH_WRN_SELECTIONMODE_NODES"), tr ("SMESH_BUT_YES") );
+ tr ("SMESH_WRN_SELECTIONMODE_NODES"), tr ("SMESH_BUT_OK") );
return;
}
Standard_Boolean result;
SMESH_Actor* ac = myMeshGUI->FindActor( myMesh, result, true );
- vtkUnstructuredGrid* ugrid = vtkUnstructuredGrid::SafeDownCast( ac->DataSource );
+ vtkUnstructuredGrid* ugrid = vtkUnstructuredGrid::SafeDownCast( ac->GetUnstructuredGrid() );
float *p0 = ugrid->GetPoint(idNodes[0]);
SpinBox_X->SetValue( p0[0] ) ;
//=================================================================================
void SMESHGUI_OrientationElementsDlg::ClickOnCancel()
{
- QAD_Application::getDesktop()->SetSelectionMode( 4 );
+ QAD_Application::getDesktop()->SetSelectionMode( ActorSelection );
disconnect( mySelection, 0, this, 0 );
mySMESHGUI->ResetState() ;
reject() ;
if(nbElements < 1)
return ;
- if ( mySelection->SelectionMode() != 3 ) {
+ if ( mySelection->SelectionMode() != FaceSelection ) {
QAD_MessageBox::warn1 ( QAD_Application::getDesktop(), tr ("SMESH_WRN_WARNING"),
- tr ("SMESH_WRN_SELECTIONMODE_ELEMENTS"), tr ("SMESH_BUT_YES") );
+ tr ("SMESH_WRN_SELECTIONMODE_ELEMENTS"), tr ("SMESH_BUT_OK") );
return;
}
using namespace std;
#include "SMESHGUI_Preferences_ScalarBarDlg.h"
+#include "SMESHGUI.h"
#include <qbuttongroup.h>
#include <qcheckbox.h>
#include <qlabel.h>
#include <qlineedit.h>
#include <qpushbutton.h>
+#include <qtoolbutton.h>
#include <qradiobutton.h>
#include <qspinbox.h>
#include <qlayout.h>
-#include <qvariant.h>
-#include <qtooltip.h>
-#include <qwhatsthis.h>
+#include <qvalidator.h>
+#include <qcolordialog.h>
-/*
- * Constructs a SMESHGUI_Preferences_ScalarBarDlg which is a child of 'parent', with the
- * name 'name' and widget flags set to 'f'
+#include <vtkTextProperty.h>
+#include <vtkScalarBarActor.h>
+
+#include "QAD_SpinBoxDbl.h"
+#include "QAD_Config.h"
+#include "SALOME_Selection.h"
+#include "SMESHGUI.h"
+#include "SMESH_Actor.h"
+
+#define MINIMUM_WIDTH 70
+#define MARGIN_SIZE 11
+#define SPACING_SIZE 6
+
+#define DEF_VER_X 0.01
+#define DEF_VER_Y 0.10
+#define DEF_VER_H 0.80
+#define DEF_VER_W 0.10
+#define DEF_HOR_X 0.20
+#define DEF_HOR_Y 0.01
+#define DEF_HOR_H 0.12
+#define DEF_HOR_W 0.60
+
+// Only one instance is allowed
+SMESHGUI_Preferences_ScalarBarDlg* SMESHGUI_Preferences_ScalarBarDlg::myDlg = 0;
+
+//=================================================================================================
+/*!
+ * SMESHGUI_Preferences_ScalarBarDlg::ScalarBarProperties
+ *
+ * Gets the only instance of "Scalar Bar Properties" dialog box
+ */
+//=================================================================================================
+void SMESHGUI_Preferences_ScalarBarDlg::ScalarBarProperties(QWidget* parent,
+ SALOME_Selection* Sel)
+{
+ if ( !myDlg ) {
+ myDlg = new SMESHGUI_Preferences_ScalarBarDlg( parent, Sel, false );
+ myDlg->show();
+ }
+ else {
+ myDlg->show();
+ myDlg->setActiveWindow();
+ myDlg->raise();
+ myDlg->setFocus();
+ }
+}
+
+//=================================================================================================
+/*!
+ * SMESHGUI_Preferences_ScalarBarDlg::ScalarBarPreferences
+ *
+ * Opens "Scalar Bar Preferences" dialog box
+ */
+//=================================================================================================
+void SMESHGUI_Preferences_ScalarBarDlg::ScalarBarPreferences( QWidget* parent )
+{
+ SMESHGUI_Preferences_ScalarBarDlg* aDlg = new SMESHGUI_Preferences_ScalarBarDlg( parent, 0, true );
+ aDlg->exec();
+}
+
+//=================================================================================================
+/*!
+ * SMESHGUI_Preferences_ScalarBarDlg::SMESHGUI_Preferences_ScalarBarDlg
*
- * The dialog will by default be modeless, unless you set 'modal' to
- * TRUE to construct a modal dialog.
+ * Constructor
*/
-SMESHGUI_Preferences_ScalarBarDlg::SMESHGUI_Preferences_ScalarBarDlg( QWidget* parent, const char* name, bool modal, WFlags fl )
- : QDialog( parent, name, modal, WStyle_Customize | WStyle_NormalBorder | WStyle_Title | WStyle_SysMenu )
+//=================================================================================================
+SMESHGUI_Preferences_ScalarBarDlg::SMESHGUI_Preferences_ScalarBarDlg(QWidget* parent,
+ SALOME_Selection* Sel,
+ bool modal)
+ : QDialog( parent, 0, modal, WStyle_Customize | WStyle_NormalBorder | WStyle_Title | WStyle_SysMenu | WDestructiveClose )
{
- if ( !name )
- setName( "SMESHGUI_Preferences_ScalarBarDlg" );
- setCaption( tr( "SMESH_PREFERENCES_SCALARBAR" ) );
- setSizeGripEnabled( TRUE );
-
- grid = new QGridLayout( this );
- grid->setSpacing( 6 );
- grid->setMargin( 11 );
-
- /******************************************************************************/
- Properties = new QGroupBox( this, "Properties" );
- Properties->setTitle( tr( "SMESH_PROPERTIES" ) );
- Properties->setColumnLayout(0, Qt::Vertical );
- Properties->layout()->setSpacing( 0 );
- Properties->layout()->setMargin( 0 );
- grid_4 = new QGridLayout( Properties->layout() );
- grid_4->setAlignment( Qt::AlignTop );
- grid_4->setSpacing( 6 );
- grid_4->setMargin( 11 );
-
- /* Font */
- grid_5 = new QGridLayout;
- grid_5->setSpacing( 6 );
- grid_5->setMargin( 0 );
- TextLabel2 = new QLabel( Properties, "TextLabel2" );
- TextLabel2->setText( tr( "SMESH_FONT" ) );
- grid_5->addWidget( TextLabel2, 0, 0 );
- ComboBox1 = new QComboBox( FALSE, Properties, "ComboBox1" );
- ComboBox1->setSizePolicy( QSizePolicy( QSizePolicy::Expanding, QSizePolicy::Fixed ) );
- ComboBox1->insertItem( tr( "SMESH_FONT_ARIAL" ) );
- ComboBox1->insertItem( tr( "SMESH_FONT_COURIER" ) );
- ComboBox1->insertItem( tr( "SMESH_FONT_TIMES" ) );
- grid_5->addWidget( ComboBox1, 0, 1 );
- grid_4->addLayout( grid_5, 0, 0 );
+ setName( "SMESHGUI_Preferences_ScalarBarDlg" );
+ setCaption( Sel ? tr( "SMESH_PROPERTIES_SCALARBAR" ) : tr( "SMESH_PREFERENCES_SCALARBAR" ) );
+ setSizeGripEnabled( TRUE );
+
+ mySelection = Sel;
+ myActor = 0;
+
+ /******************************************************************************/
+ // Top layout
+ QGridLayout* aTopLayout = new QGridLayout( this );
+ aTopLayout->setSpacing( SPACING_SIZE ); aTopLayout->setMargin( MARGIN_SIZE );
+ int aRow = 0;
+
+ /******************************************************************************/
+ // Scalar range
+ if ( mySelection ) {
+ myRangeGrp = new QGroupBox ( tr( "SMESH_RANGE_SCALARBAR" ), this, "myRangeGrp" );
+ myRangeGrp->setColumnLayout( 0, Qt::Vertical );
+ myRangeGrp->layout()->setSpacing( 0 ); myRangeGrp->layout()->setMargin( 0 );
+ QGridLayout* myRangeGrpLayout = new QGridLayout( myRangeGrp->layout() );
+ myRangeGrpLayout->setAlignment( Qt::AlignTop );
+ myRangeGrpLayout->setSpacing( SPACING_SIZE ); myRangeGrpLayout->setMargin( MARGIN_SIZE );
+
+ myMinEdit = new QLineEdit( myRangeGrp, "myMinEdit" );
+ myMinEdit->setMinimumWidth( MINIMUM_WIDTH );
+ myMinEdit->setValidator( new QDoubleValidator( this ) );
+
+ myMaxEdit = new QLineEdit( myRangeGrp, "myMaxEdit" );
+ myMaxEdit->setMinimumWidth( MINIMUM_WIDTH );
+ myMaxEdit->setValidator( new QDoubleValidator( this ) );
+
+ myRangeGrpLayout->addWidget( new QLabel( tr( "SMESH_RANGE_MIN" ), myRangeGrp, "myMinLab" ), 0, 0 );
+ myRangeGrpLayout->addWidget( myMinEdit, 0, 1 );
+ myRangeGrpLayout->addWidget( new QLabel( tr( "SMESH_RANGE_MAX" ), myRangeGrp, "myMaxLab" ), 0, 2 );
+ myRangeGrpLayout->addWidget( myMaxEdit, 0, 3 );
+
+ aTopLayout->addWidget( myRangeGrp, aRow, 0 );
+ aRow++;
+ }
+
+ /******************************************************************************/
+ // Text properties
+ myFontGrp = new QGroupBox ( tr( "SMESH_FONT_SCALARBAR" ), this, "myFontGrp" );
+ myFontGrp->setColumnLayout( 0, Qt::Vertical );
+ myFontGrp->layout()->setSpacing( 0 ); myFontGrp->layout()->setMargin( 0 );
+ QGridLayout* myFontGrpLayout = new QGridLayout( myFontGrp->layout() );
+ myFontGrpLayout->setAlignment( Qt::AlignTop );
+ myFontGrpLayout->setSpacing( SPACING_SIZE ); myFontGrpLayout->setMargin( MARGIN_SIZE );
+
+ myTitleColorBtn = new QToolButton( myFontGrp, "myTitleColorBtn" );
+
+ myTitleFontCombo = new QComboBox( false, myFontGrp, "myTitleFontCombo" );
+ myTitleFontCombo->setMinimumWidth( MINIMUM_WIDTH );
+ myTitleFontCombo->setSizePolicy( QSizePolicy( QSizePolicy::Expanding, QSizePolicy::Fixed ) );
+ myTitleFontCombo->insertItem( tr( "SMESH_FONT_ARIAL" ) );
+ myTitleFontCombo->insertItem( tr( "SMESH_FONT_COURIER" ) );
+ myTitleFontCombo->insertItem( tr( "SMESH_FONT_TIMES" ) );
+
+ myTitleBoldCheck = new QCheckBox( tr( "SMESH_FONT_BOLD" ), myFontGrp, "myTitleBoldCheck" );
+ myTitleItalicCheck = new QCheckBox( tr( "SMESH_FONT_ITALIC" ), myFontGrp, "myTitleItalicCheck" );
+ myTitleShadowCheck = new QCheckBox( tr( "SMESH_FONT_SHADOW" ), myFontGrp, "myTitleShadowCheck" );
+
+ myLabelsColorBtn = new QToolButton( myFontGrp, "myLabelsColorBtn" );
+
+ myLabelsFontCombo = new QComboBox( false, myFontGrp, "myLabelsFontCombo" );
+ myLabelsFontCombo->setMinimumWidth( MINIMUM_WIDTH );
+ myLabelsFontCombo->setSizePolicy( QSizePolicy( QSizePolicy::Expanding, QSizePolicy::Fixed ) );
+ myLabelsFontCombo->insertItem( tr( "SMESH_FONT_ARIAL" ) );
+ myLabelsFontCombo->insertItem( tr( "SMESH_FONT_COURIER" ) );
+ myLabelsFontCombo->insertItem( tr( "SMESH_FONT_TIMES" ) );
+
+ myLabelsBoldCheck = new QCheckBox( tr( "SMESH_FONT_BOLD" ), myFontGrp, "myLabelsBoldCheck" );
+ myLabelsItalicCheck = new QCheckBox( tr( "SMESH_FONT_ITALIC" ), myFontGrp, "myLabelsItalicCheck" );
+ myLabelsShadowCheck = new QCheckBox( tr( "SMESH_FONT_SHADOW" ), myFontGrp, "myLabelsShadowCheck" );
+
+ myFontGrpLayout->addWidget( new QLabel( tr( "SMESH_TITLE" ), myFontGrp, "myFontTitleLab" ), 0, 0 );
+ myFontGrpLayout->addWidget( myTitleColorBtn, 0, 1 );
+ myFontGrpLayout->addWidget( myTitleFontCombo, 0, 2 );
+ myFontGrpLayout->addWidget( myTitleBoldCheck, 0, 3 );
+ myFontGrpLayout->addWidget( myTitleItalicCheck, 0, 4 );
+ myFontGrpLayout->addWidget( myTitleShadowCheck, 0, 5 );
+
+ myFontGrpLayout->addWidget( new QLabel( tr( "SMESH_LABELS" ), myFontGrp, "myFontLabelsLab" ), 1, 0 );
+ myFontGrpLayout->addWidget( myLabelsColorBtn, 1, 1 );
+ myFontGrpLayout->addWidget( myLabelsFontCombo, 1, 2 );
+ myFontGrpLayout->addWidget( myLabelsBoldCheck, 1, 3 );
+ myFontGrpLayout->addWidget( myLabelsItalicCheck, 1, 4 );
+ myFontGrpLayout->addWidget( myLabelsShadowCheck, 1, 5 );
+
+ aTopLayout->addWidget( myFontGrp, aRow, 0 );
+ aRow++;
+
+ /******************************************************************************/
+ // Labels & Colors
+ myLabColorGrp = new QGroupBox ( tr( "SMESH_LABELS_COLORS_SCALARBAR" ), this, "myLabColorGrp" );
+ myLabColorGrp->setColumnLayout( 0, Qt::Vertical );
+ myLabColorGrp->layout()->setSpacing( 0 ); myLabColorGrp->layout()->setMargin( 0 );
+ QGridLayout* myLabColorGrpLayout = new QGridLayout( myLabColorGrp->layout() );
+ myLabColorGrpLayout->setAlignment( Qt::AlignTop );
+ myLabColorGrpLayout->setSpacing( SPACING_SIZE ); myLabColorGrpLayout->setMargin( MARGIN_SIZE );
+
+ myColorsSpin = new QSpinBox( 2, 256, 1, myLabColorGrp, "myColorsSpin" );
+ myColorsSpin->setMinimumWidth( MINIMUM_WIDTH );
+ myColorsSpin->setSizePolicy( QSizePolicy( QSizePolicy::Expanding, QSizePolicy::Fixed ) );
+
+ myLabelsSpin = new QSpinBox( 2, 65, 1, myLabColorGrp, "myLabelsSpin" );
+ myLabelsSpin->setMinimumWidth( MINIMUM_WIDTH );
+ myLabelsSpin->setSizePolicy( QSizePolicy( QSizePolicy::Expanding, QSizePolicy::Fixed ) );
+
+ myLabColorGrpLayout->addWidget( new QLabel( tr( "SMESH_NUMBEROFCOLORS" ), myLabColorGrp, "myNbColorLab" ), 0, 0 );
+ myLabColorGrpLayout->addWidget( myColorsSpin, 0, 1 );
+ myLabColorGrpLayout->addWidget( new QLabel( tr( "SMESH_NUMBEROFLABELS" ), myLabColorGrp, "myNbLabsLab" ), 0, 2 );
+ myLabColorGrpLayout->addWidget( myLabelsSpin, 0, 3 );
+
+ aTopLayout->addWidget( myLabColorGrp, aRow, 0 );
+ aRow++;
+
+ /******************************************************************************/
+ // Orientation
+ myOrientationGrp = new QButtonGroup ( tr( "SMESH_ORIENTATION" ), this, "myOrientationGrp" );
+ myOrientationGrp->setColumnLayout( 0, Qt::Vertical );
+ myOrientationGrp->layout()->setSpacing( 0 ); myOrientationGrp->layout()->setMargin( 0 );
+ QGridLayout* myOrientationGrpLayout = new QGridLayout( myOrientationGrp->layout() );
+ myOrientationGrpLayout->setAlignment( Qt::AlignTop );
+ myOrientationGrpLayout->setSpacing( SPACING_SIZE ); myOrientationGrpLayout->setMargin( MARGIN_SIZE );
+
+ myVertRadioBtn = new QRadioButton( tr( "SMESH_VERTICAL" ), myOrientationGrp, "myVertRadioBtn" );
+ myHorizRadioBtn = new QRadioButton( tr( "SMESH_HORIZONTAL" ), myOrientationGrp, "myHorizRadioBtn" );
+ myVertRadioBtn->setChecked( true );
+
+ myOrientationGrpLayout->addWidget( myVertRadioBtn, 0, 0 );
+ myOrientationGrpLayout->addWidget( myHorizRadioBtn, 0, 1 );
+
+ aTopLayout->addWidget( myOrientationGrp, aRow, 0 );
+ aRow++;
+
+ /******************************************************************************/
+ // Position & Size
+ myOriginDimGrp = new QGroupBox ( tr( "SMESH_POSITION_SIZE_SCALARBAR" ), this, "myOriginDimGrp" );
+ myOriginDimGrp->setColumnLayout( 0, Qt::Vertical );
+ myOriginDimGrp->layout()->setSpacing( 0 ); myOriginDimGrp->layout()->setMargin( 0 );
+ QGridLayout* myOriginDimGrpLayout = new QGridLayout( myOriginDimGrp->layout() );
+ myOriginDimGrpLayout->setAlignment( Qt::AlignTop );
+ myOriginDimGrpLayout->setSpacing( SPACING_SIZE ); myOriginDimGrpLayout->setMargin( MARGIN_SIZE );
- /* Font attributes */
- grid_6 = new QGridLayout;
- grid_6->setSpacing( 6 );
- grid_6->setMargin( 0 );
- Bold = new QCheckBox( Properties, "Bold" );
- Bold->setText( tr( "SMESH_FONT_BOLD" ) );
- grid_6->addWidget( Bold, 0, 0 );
- Italic = new QCheckBox( Properties, "Italic" );
- Italic->setText( tr( "SMESH_FONT_ITALIC" ) );
- grid_6->addWidget( Italic, 0, 1 );
- Shadow = new QCheckBox( Properties, "Shadow" );
- Shadow->setText( tr( "SMESH_FONT_SHADOW" ) );
- grid_6->addWidget( Shadow, 0, 2 );
- grid_4->addLayout( grid_6, 1, 0 );
-
- grid_7 = new QGridLayout;
- grid_7->setSpacing( 6 );
- grid_7->setMargin( 0 );
- NumberColors = new QLabel( Properties, "NumberColors" );
- NumberColors->setText( tr( "SMESH_NUMBEROFCOLORS" ) );
- grid_7->addWidget( NumberColors, 0, 0 );
- SpinBoxColors = new QSpinBox( Properties, "SpinBoxColors" );
- SpinBoxColors->setSizePolicy( QSizePolicy( QSizePolicy::Expanding, QSizePolicy::Fixed ) );
- SpinBoxColors->setMinValue( 1 );
- grid_7->addWidget( SpinBoxColors, 0, 1 );
- NumberLabels = new QLabel( Properties, "NumberLabels" );
- NumberLabels->setText( tr( "SMESH_NUMBEROFLABELS" ) );
- grid_7->addWidget( NumberLabels, 1, 0 );
- SpinBoxLabels = new QSpinBox( Properties, "SpinBoxLabels" );
- SpinBoxLabels->setSizePolicy( QSizePolicy( QSizePolicy::Expanding, QSizePolicy::Fixed ) );
- SpinBoxLabels->setMinValue( 1 );
- grid_7->addWidget( SpinBoxLabels, 1, 1 );
- grid_4->addLayout( grid_7, 2, 0 );
-
- grid->addWidget( Properties, 0, 0 );
-
- /******************************************************************************/
- ButtonGroup_Orientation = new QButtonGroup( this, "ButtonGroup_Orientation" );
- ButtonGroup_Orientation->setTitle( tr( "SMESH_ORIENTATION" ) );
- ButtonGroup_Orientation->setColumnLayout(0, Qt::Vertical );
- ButtonGroup_Orientation->layout()->setSpacing( 0 );
- ButtonGroup_Orientation->layout()->setMargin( 0 );
- grid_2 = new QGridLayout( ButtonGroup_Orientation->layout() );
- grid_2->setAlignment( Qt::AlignTop );
- grid_2->setSpacing( 6 );
- grid_2->setMargin( 11 );
- RadioVert = new QRadioButton( ButtonGroup_Orientation, "RadioVert" );
- RadioVert->setText( tr( "SMESH_VERTICAL" ) );
- RadioHoriz = new QRadioButton( ButtonGroup_Orientation, "RadioHoriz" );
- RadioHoriz->setText( tr( "SMESH_HORIZONTAL" ) );
- grid_2->addWidget( RadioVert, 0, 0 );
- grid_2->addWidget( RadioHoriz, 0, 1 );
-
- grid->addWidget( ButtonGroup_Orientation, 1, 0 );
-
- /******************************************************************************/
- GroupBox5 = new QGroupBox( this, "GroupBox5" );
- GroupBox5->setTitle( tr( "SMESH_DIMENSIONS" ) );
- GroupBox5->setColumnLayout(0, Qt::Vertical );
- GroupBox5->layout()->setSpacing( 0 );
- GroupBox5->layout()->setMargin( 0 );
- grid_11 = new QGridLayout( GroupBox5->layout() );
- grid_11->setAlignment( Qt::AlignTop );
- grid_11->setSpacing( 6 );
- grid_11->setMargin( 11 );
-
- LineEditWidth = new QLineEdit( GroupBox5, "LineEditWidth" );
- grid_11->addWidget( LineEditWidth, 0, 0 );
- Width = new QLabel( GroupBox5, "Width" );
- Width->setText( tr( "SMESH_WIDTH" ) );
- grid_11->addWidget( Width, 0, 1 );
- LineEditHeight = new QLineEdit( GroupBox5, "LineEditHeight" );
- grid_11->addWidget( LineEditHeight, 1, 0 );
- Height = new QLabel( GroupBox5, "Height" );
- Height->setText( tr( "SMESH_HEIGHT" ) );
- grid_11->addWidget( Height, 1, 1 );
-
- grid->addWidget( GroupBox5, 2, 0 );
-
- /***************************************************************/
- QGroupBox* GroupButtons = new QGroupBox( this, "GroupButtons" );
- GroupButtons->setGeometry( QRect( 10, 10, 281, 48 ) );
- GroupButtons->setTitle( tr( "" ) );
- GroupButtons->setColumnLayout(0, Qt::Vertical );
- GroupButtons->layout()->setSpacing( 0 );
- GroupButtons->layout()->setMargin( 0 );
- grid_15 = new QGridLayout( GroupButtons->layout() );
- grid_15->setAlignment( Qt::AlignTop );
- grid_15->setSpacing( 6 );
- grid_15->setMargin( 11 );
- buttonOk = new QPushButton( GroupButtons, "buttonOk" );
- buttonOk->setText( tr( "SMESH_BUT_OK" ) );
- buttonOk->setAutoDefault( TRUE );
- buttonOk->setDefault( TRUE );
- grid_15->addWidget( buttonOk, 0, 0 );
- grid_15->addItem( new QSpacerItem( 20, 20, QSizePolicy::Expanding, QSizePolicy::Minimum ), 0, 1 );
- buttonCancel = new QPushButton( GroupButtons, "buttonCancel" );
- buttonCancel->setText( tr( "SMESH_BUT_CANCEL" ) );
- buttonCancel->setAutoDefault( TRUE );
- grid_15->addWidget( buttonCancel, 0, 2 );
-
- grid->addWidget( GroupButtons, 3, 0 );
-
- // signals and slots connections
- connect( buttonOk, SIGNAL( clicked() ), this, SLOT( accept() ) );
- connect( buttonCancel, SIGNAL( clicked() ), this, SLOT( reject() ) );
+ myXSpin = new QAD_SpinBoxDbl( myOriginDimGrp, 0.0, 1.0, 0.1 );
+ myXSpin->setMinimumWidth( MINIMUM_WIDTH );
+ myXSpin->setSizePolicy( QSizePolicy( QSizePolicy::Expanding, QSizePolicy::Fixed ) );
+
+ myYSpin = new QAD_SpinBoxDbl( myOriginDimGrp, 0.0, 1.0, 0.1 );
+ myYSpin->setMinimumWidth( MINIMUM_WIDTH );
+ myYSpin->setSizePolicy( QSizePolicy( QSizePolicy::Expanding, QSizePolicy::Fixed ) );
+
+ myWidthSpin = new QAD_SpinBoxDbl( myOriginDimGrp, 0.0, 1.0, 0.1 );
+ myWidthSpin->setMinimumWidth( MINIMUM_WIDTH );
+ myWidthSpin->setSizePolicy( QSizePolicy( QSizePolicy::Expanding, QSizePolicy::Fixed ) );
+
+ myHeightSpin = new QAD_SpinBoxDbl( myOriginDimGrp, 0.0, 1.0, 0.1 );
+ myHeightSpin->setMinimumWidth( MINIMUM_WIDTH );
+ myHeightSpin->setSizePolicy( QSizePolicy( QSizePolicy::Expanding, QSizePolicy::Fixed ) );
+
+ myOriginDimGrpLayout->addWidget( new QLabel( tr( "SMESH_X_SCALARBAR" ), myOriginDimGrp, "myXLab" ), 0, 0 );
+ myOriginDimGrpLayout->addWidget( myXSpin, 0, 1 );
+ myOriginDimGrpLayout->addWidget( new QLabel( tr( "SMESH_Y_SCALARBAR" ), myOriginDimGrp, "myYLab" ), 0, 2 );
+ myOriginDimGrpLayout->addWidget( myYSpin, 0, 3 );
+ myOriginDimGrpLayout->addWidget( new QLabel( tr( "SMESH_WIDTH" ), myOriginDimGrp, "myWidthLab" ), 1, 0 );
+ myOriginDimGrpLayout->addWidget( myWidthSpin, 1, 1 );
+ myOriginDimGrpLayout->addWidget( new QLabel( tr( "SMESH_HEIGHT" ), myOriginDimGrp, "myHeightLab" ), 1, 2 );
+ myOriginDimGrpLayout->addWidget( myHeightSpin, 1, 3 );
+
+ aTopLayout->addWidget( myOriginDimGrp, aRow, 0 );
+ aRow++;
+
+ /***************************************************************/
+ // Common buttons
+ myButtonGrp = new QGroupBox( this, "myButtonGrp" );
+ myButtonGrp->setColumnLayout(0, Qt::Vertical );
+ myButtonGrp->layout()->setSpacing( 0 ); myButtonGrp->layout()->setMargin( 0 );
+ QHBoxLayout* myButtonGrpLayout = new QHBoxLayout( myButtonGrp->layout() );
+ myButtonGrpLayout->setAlignment( Qt::AlignTop );
+ myButtonGrpLayout->setSpacing( SPACING_SIZE ); myButtonGrpLayout->setMargin( MARGIN_SIZE );
+
+ myOkBtn = new QPushButton( tr( "SMESH_BUT_OK" ), myButtonGrp, "myOkBtn" );
+ myOkBtn->setAutoDefault( TRUE ); myOkBtn->setDefault( TRUE );
+ myButtonGrpLayout->addWidget( myOkBtn );
+ if ( mySelection ) {
+ myApplyBtn = new QPushButton( tr( "SMESH_BUT_APPLY" ), myButtonGrp, "myApplyBtn" );
+ myApplyBtn->setAutoDefault( TRUE );
+ myButtonGrpLayout->addWidget( myApplyBtn );
+ }
+ myButtonGrpLayout->addStretch();
+ myCancelBtn = new QPushButton( tr( "SMESH_BUT_CANCEL" ), myButtonGrp, "myCancelBtn" );
+ if ( mySelection )
+ myCancelBtn->setText( tr( "SMESH_BUT_CLOSE" ) );
+ myCancelBtn->setAutoDefault( TRUE );
+ myButtonGrpLayout->addWidget( myCancelBtn );
+
+ aTopLayout->addWidget( myButtonGrp, aRow, 0 );
+
+ /***************************************************************/
+ // Init
+ // --> first init from preferences
+ QColor titleColor( 255, 255, 255 );
+ if ( QAD_CONFIG->hasSetting( "SMESH:ScalarBarTitleColor" ) ) {
+ QStringList aTColor = QStringList::split( ":", QAD_CONFIG->getSetting( "SMESH:ScalarBarTitleColor" ), false );
+ titleColor = QColor( ( aTColor.count() > 0 ? aTColor[0].toInt() : 255 ),
+ ( aTColor.count() > 1 ? aTColor[1].toInt() : 255 ),
+ ( aTColor.count() > 2 ? aTColor[2].toInt() : 255 ) );
+ }
+ myTitleColorBtn->setPaletteBackgroundColor( titleColor );
+ myTitleFontCombo->setCurrentItem( 0 );
+ if ( QAD_CONFIG->hasSetting( "SMESH:ScalarBarTitleFont" ) ) {
+ if ( QAD_CONFIG->getSetting( "SMESH:ScalarBarTitleFont" ) == "Arial" )
+ myTitleFontCombo->setCurrentItem( 0 );
+ if ( QAD_CONFIG->getSetting( "SMESH:ScalarBarTitleFont" ) == "Courier" )
+ myTitleFontCombo->setCurrentItem( 1 );
+ if ( QAD_CONFIG->getSetting( "SMESH:ScalarBarTitleFont" ) == "Times" )
+ myTitleFontCombo->setCurrentItem( 2 );
+ }
+ myTitleBoldCheck->setChecked( QAD_CONFIG->getSetting( "SMESH:ScalarBarTitleBold" ) == "true" );
+ myTitleItalicCheck->setChecked( QAD_CONFIG->getSetting( "SMESH:ScalarBarTitleItalic" ) == "true" );
+ myTitleShadowCheck->setChecked( QAD_CONFIG->getSetting( "SMESH:ScalarBarTitleShadow" ) == "true" );
+
+ QColor labelColor( 255, 255, 255 );
+ if ( QAD_CONFIG->hasSetting( "SMESH:ScalarBarLabelColor" ) ) {
+ QStringList aLColor = QStringList::split( ":", QAD_CONFIG->getSetting( "SMESH:ScalarBarLabelColor" ), false );
+ labelColor = QColor( ( aLColor.count() > 0 ? aLColor[0].toInt() : 255 ),
+ ( aLColor.count() > 1 ? aLColor[1].toInt() : 255 ),
+ ( aLColor.count() > 2 ? aLColor[2].toInt() : 255 ) );
+ }
+ myLabelsColorBtn->setPaletteBackgroundColor( labelColor );
+ myLabelsFontCombo->setCurrentItem( 0 );
+ if ( QAD_CONFIG->hasSetting( "SMESH:ScalarBarLabelFont" ) ) {
+ if ( QAD_CONFIG->getSetting( "SMESH:ScalarBarLabelFont" ) == "Arial" )
+ myLabelsFontCombo->setCurrentItem( 0 );
+ if ( QAD_CONFIG->getSetting( "SMESH:ScalarBarLabelFont" ) == "Courier" )
+ myLabelsFontCombo->setCurrentItem( 1 );
+ if ( QAD_CONFIG->getSetting( "SMESH:ScalarBarLabelFont" ) == "Times" )
+ myLabelsFontCombo->setCurrentItem( 2 );
+ }
+ myLabelsBoldCheck->setChecked( QAD_CONFIG->getSetting( "SMESH:ScalarBarLabelBold" ) == "true" );
+ myLabelsItalicCheck->setChecked( QAD_CONFIG->getSetting( "SMESH:ScalarBarLabelItalic" ) == "true" );
+ myLabelsShadowCheck->setChecked( QAD_CONFIG->getSetting( "SMESH:ScalarBarLabelShadow" ) == "true" );
+
+ int aNbColors = 64;
+ if ( QAD_CONFIG->hasSetting( "SMESH:ScalarBarNbOfColors" ) )
+ aNbColors = QAD_CONFIG->getSetting( "SMESH:ScalarBarNbOfColors" ).toInt();
+ myColorsSpin->setValue( aNbColors );
+ int aNbLabels = 5;
+ if ( QAD_CONFIG->hasSetting( "SMESH:ScalarBarNbOfLabels" ) )
+ aNbLabels = QAD_CONFIG->getSetting( "SMESH:ScalarBarNbOfLabels" ).toInt();
+ myLabelsSpin->setValue( aNbLabels );
+
+ QString aOrientation = QAD_CONFIG->getSetting( "SMESH:ScalarBarOrientation" );
+ if ( aOrientation == "Horizontal" )
+ myHorizRadioBtn->setChecked( true );
+ else
+ myVertRadioBtn->setChecked( true );
+ myIniOrientation = myVertRadioBtn->isChecked();
+
+ if ( QAD_CONFIG->hasSetting( "SMESH:ScalarBarXPosition" ) )
+ myIniX = QAD_CONFIG->getSetting( "SMESH:ScalarBarXPosition" ).toDouble();
+ else
+ myIniX = myHorizRadioBtn->isChecked() ? DEF_HOR_X : DEF_VER_X;
+ if ( QAD_CONFIG->hasSetting( "SMESH:ScalarBarYPosition" ) )
+ myIniY = QAD_CONFIG->getSetting( "SMESH:ScalarBarYPosition" ).toDouble();
+ else
+ myIniY = myHorizRadioBtn->isChecked() ? DEF_HOR_Y : DEF_VER_Y;
+ if ( QAD_CONFIG->hasSetting( "SMESH:ScalarBarWidth" ) )
+ myIniW = QAD_CONFIG->getSetting( "SMESH:ScalarBarWidth" ).toDouble();
+ else
+ myIniW = myHorizRadioBtn->isChecked() ? DEF_HOR_W : DEF_VER_W;
+ if ( QAD_CONFIG->hasSetting( "SMESH:ScalarBarHeight" ) )
+ myIniH = QAD_CONFIG->getSetting( "SMESH:ScalarBarHeight" ).toDouble();
+ else
+ myIniH = myHorizRadioBtn->isChecked() ? DEF_HOR_H : DEF_VER_H;
+ setOriginAndSize( myIniX, myIniY, myIniW, myIniH );
+
+ if ( mySelection ) {
+ // --> then init from selection if necessary
+ onSelectionChanged();
+ }
+
+ /***************************************************************/
+ // Connect section
+ connect( myTitleColorBtn, SIGNAL( clicked() ), this, SLOT( onTitleColor() ) );
+ connect( myLabelsColorBtn, SIGNAL( clicked() ), this, SLOT( onLabelsColor() ) );
+ connect( myOkBtn, SIGNAL( clicked() ), this, SLOT( onOk() ) );
+ connect( myCancelBtn, SIGNAL( clicked() ), this, SLOT( onCancel() ) );
+ connect( myXSpin, SIGNAL( valueChanged( double ) ), this, SLOT( onXYChanged() ) );
+ connect( myYSpin, SIGNAL( valueChanged( double ) ), this, SLOT( onXYChanged() ) );
+ connect( myOrientationGrp, SIGNAL( clicked( int ) ), this, SLOT( onOrientationChanged() ) );
+ if ( mySelection ) {
+ connect( myApplyBtn, SIGNAL( clicked() ), this, SLOT( onApply() ) );
+ connect( mySelection, SIGNAL( currentSelectionChanged() ), this, SLOT( onSelectionChanged() ) );
+ }
+ connect( SMESHGUI::GetSMESHGUI(), SIGNAL( SignalCloseAllDialogs() ), this, SLOT( onCancel() ) ) ;
}
-/*
- * Destroys the object and frees any allocated resources
+//=================================================================================================
+/*!
+ * SMESHGUI_Preferences_ScalarBarDlg::~SMESHGUI_Preferences_ScalarBarDlg
+ *
+ * Destructor
*/
+//=================================================================================================
SMESHGUI_Preferences_ScalarBarDlg::~SMESHGUI_Preferences_ScalarBarDlg()
{
- // no need to delete child widgets, Qt does it all for us
}
+//=================================================================================================
+/*!
+ * SMESHGUI_Preferences_ScalarBarDlg::onOk
+ *
+ * OK button slot
+ */
+//=================================================================================================
+void SMESHGUI_Preferences_ScalarBarDlg::onOk()
+{
+ if ( onApply() )
+ onCancel();
+}
+
+//=================================================================================================
+/*!
+ * SMESHGUI_Preferences_ScalarBarDlg::onApply
+ *
+ * Apply button slot
+ */
+//=================================================================================================
+bool SMESHGUI_Preferences_ScalarBarDlg::onApply()
+{
+ if ( mySelection ) {
+ // Scalar Bar properties
+ if ( !myActor )
+ return false;
+ vtkScalarBarActor* myScalarBarActor = myActor->GetScalarBarActor();
+
+ vtkTextProperty* aTitleTextPrp = myScalarBarActor->GetTitleTextProperty();
+ QColor aTColor = myTitleColorBtn->paletteBackgroundColor();
+ aTitleTextPrp->SetColor( aTColor.red()/255., aTColor.green()/255., aTColor.blue()/255. );
+ if ( myTitleFontCombo->currentItem() == 0 )
+ aTitleTextPrp->SetFontFamilyToArial();
+ else if ( myTitleFontCombo->currentItem() == 1 )
+ aTitleTextPrp->SetFontFamilyToCourier();
+ else
+ aTitleTextPrp->SetFontFamilyToTimes();
+ aTitleTextPrp->SetBold( myTitleBoldCheck->isChecked() );
+ aTitleTextPrp->SetItalic( myTitleItalicCheck->isChecked() );
+ aTitleTextPrp->SetShadow( myTitleShadowCheck->isChecked() );
+ myScalarBarActor->SetTitleTextProperty( aTitleTextPrp );
+
+ vtkTextProperty* aLabelsTextPrp = myScalarBarActor->GetLabelTextProperty();
+ QColor aLColor = myLabelsColorBtn->paletteBackgroundColor();
+ aLabelsTextPrp->SetColor( aLColor.red()/255., aLColor.green()/255., aLColor.blue()/255. );
+ if ( myLabelsFontCombo->currentItem() == 0 )
+ aLabelsTextPrp->SetFontFamilyToArial();
+ else if ( myLabelsFontCombo->currentItem() == 1 )
+ aLabelsTextPrp->SetFontFamilyToCourier();
+ else
+ aLabelsTextPrp->SetFontFamilyToTimes();
+ aLabelsTextPrp->SetBold( myLabelsBoldCheck->isChecked() );
+ aLabelsTextPrp->SetItalic( myLabelsItalicCheck->isChecked() );
+ aLabelsTextPrp->SetShadow( myLabelsShadowCheck->isChecked() );
+ myScalarBarActor->SetLabelTextProperty( aLabelsTextPrp );
+
+ myScalarBarActor->SetNumberOfLabels( myLabelsSpin->value() );
+ myScalarBarActor->SetMaximumNumberOfColors( myColorsSpin->value() );
+
+ if ( myHorizRadioBtn->isChecked() )
+ myScalarBarActor->SetOrientationToHorizontal();
+ else
+ myScalarBarActor->SetOrientationToVertical();
+
+ myScalarBarActor->SetPosition( myXSpin->value(), myYSpin->value() );
+ myScalarBarActor->SetWidth( myWidthSpin->value() );
+ myScalarBarActor->SetHeight( myHeightSpin->value() );
+
+ double aMin = myMinEdit->text().toDouble();
+ double aMax = myMaxEdit->text().toDouble();
+ myScalarBarActor->GetLookupTable()->SetRange( aMin, aMax );
+ SMESHGUI::GetSMESHGUI()->UpdateView();
+ }
+ else {
+ // Scalar Bar preferences
+ QColor titleColor = myTitleColorBtn->paletteBackgroundColor();
+ QAD_CONFIG->addSetting( "SMESH:ScalarBarTitleColor", QString().sprintf( "%d:%d:%d", titleColor.red(), titleColor.green(), titleColor.blue() ) );
+ if ( myTitleFontCombo->currentItem() == 0 )
+ QAD_CONFIG->addSetting( "SMESH:ScalarBarTitleFont", "Arial" );
+ else if ( myTitleFontCombo->currentItem() == 1 )
+ QAD_CONFIG->addSetting( "SMESH:ScalarBarTitleFont", "Courier" );
+ else
+ QAD_CONFIG->addSetting( "SMESH:ScalarBarTitleFont", "Times" );
+ QAD_CONFIG->addSetting( "SMESH:ScalarBarTitleBold", myTitleBoldCheck->isChecked() ? "true" : "false" );
+ QAD_CONFIG->addSetting( "SMESH:ScalarBarTitleItalic", myTitleItalicCheck->isChecked() ? "true" : "false" );
+ QAD_CONFIG->addSetting( "SMESH:ScalarBarTitleShadow", myTitleShadowCheck->isChecked() ? "true" : "false" );
+
+ QColor labelColor = myLabelsColorBtn->paletteBackgroundColor();
+ QAD_CONFIG->addSetting( "SMESH:ScalarBarLabelColor", QString().sprintf( "%d:%d:%d", labelColor.red(), labelColor.green(),labelColor. blue() ) );
+ if ( myLabelsFontCombo->currentItem() == 0 )
+ QAD_CONFIG->addSetting( "SMESH:ScalarBarLabelFont", "Arial" );
+ else if ( myLabelsFontCombo->currentItem() == 1 )
+ QAD_CONFIG->addSetting( "SMESH:ScalarBarLabelFont", "Courier" );
+ else
+ QAD_CONFIG->addSetting( "SMESH:ScalarBarLabelFont", "Times" );
+ QAD_CONFIG->addSetting( "SMESH:ScalarBarLabelBold", myLabelsBoldCheck->isChecked() ? "true" : "false" );
+ QAD_CONFIG->addSetting( "SMESH:ScalarBarLabelItalic", myLabelsItalicCheck->isChecked() ? "true" : "false" );
+ QAD_CONFIG->addSetting( "SMESH:ScalarBarLabelShadow", myLabelsShadowCheck->isChecked() ? "true" : "false" );
+
+ QAD_CONFIG->addSetting( "SMESH:ScalarBarNbOfColors", myColorsSpin->value() );
+ QAD_CONFIG->addSetting( "SMESH:ScalarBarNbOfLabels", myLabelsSpin->value() );
+
+ QAD_CONFIG->addSetting( "SMESH:ScalarBarOrientation", myHorizRadioBtn->isChecked() ? "Horizontal" : "Vertical" );
+
+ QAD_CONFIG->addSetting( "SMESH:ScalarBarXPosition", myXSpin->value() );
+ QAD_CONFIG->addSetting( "SMESH:ScalarBarYPosition", myYSpin->value() );
+ QAD_CONFIG->addSetting( "SMESH:ScalarBarWidth", myWidthSpin->value() );
+ QAD_CONFIG->addSetting( "SMESH:ScalarBarHeight", myHeightSpin->value() );
+ }
+ return true;
+}
+
+//=================================================================================================
+/*!
+ * SMESHGUI_Preferences_ScalarBarDlg::onCancel
+ *
+ * Cancel button slot
+ */
+//=================================================================================================
+void SMESHGUI_Preferences_ScalarBarDlg::onCancel()
+{
+ close();
+}
+
+//=================================================================================================
+/*!
+ * SMESHGUI_Preferences_ScalarBarDlg::onTitleColor
+ *
+ * Change Title color button slot
+ */
+//=================================================================================================
+void SMESHGUI_Preferences_ScalarBarDlg::onTitleColor()
+{
+ QColor aColor = myTitleColorBtn->paletteBackgroundColor();
+ aColor = QColorDialog::getColor( aColor, this );
+ if ( aColor.isValid() )
+ myTitleColorBtn->setPaletteBackgroundColor( aColor );
+}
+
+//=================================================================================================
+/*!
+ * SMESHGUI_Preferences_ScalarBarDlg::onLabelsColor
+ *
+ * Change Labels color button slot
+ */
+//=================================================================================================
+void SMESHGUI_Preferences_ScalarBarDlg::onLabelsColor()
+{
+ QColor aColor = myLabelsColorBtn->paletteBackgroundColor();
+ aColor = QColorDialog::getColor( aColor, this );
+ if ( aColor.isValid() )
+ myLabelsColorBtn->setPaletteBackgroundColor( aColor );
+}
+
+//=================================================================================================
+/*!
+ * SMESHGUI_Preferences_ScalarBarDlg::onSelectionChanged
+ *
+ * Called when selection changed
+ */
+//=================================================================================================
+void SMESHGUI_Preferences_ScalarBarDlg::onSelectionChanged()
+{
+ if( mySelection ) {
+ if ( mySelection->IObjectCount() == 1 ) {
+ Handle(SALOME_InteractiveObject) anIO = mySelection->firstIObject();
+ if( anIO->hasEntry() ) {
+ Standard_Boolean isOk;
+ SMESH_Actor* anActor = SMESHGUI::GetSMESHGUI()->FindActorByEntry( anIO->getEntry(), isOk, true );
+ if ( isOk && anActor->GetScalarBarActor() && anActor->GetControlMode() != SMESH_Actor::eNone ) {
+ myActor = anActor;
+ vtkScalarBarActor* myScalarBarActor = myActor->GetScalarBarActor();
+
+ double aMin = 0.0, aMax = 0.0;
+ if ( myScalarBarActor->GetLookupTable() ) {
+ float *range = myScalarBarActor->GetLookupTable()->GetRange();
+ myMinEdit->setText( QString::number( range[0] ) );
+ myMaxEdit->setText( QString::number( range[1] ) );
+ }
+
+ vtkTextProperty* aTitleTextPrp = myScalarBarActor->GetTitleTextProperty();
+ float aTColor[3];
+ aTitleTextPrp->GetColor( aTColor );
+ myTitleColorBtn->setPaletteBackgroundColor( QColor( (int)( aTColor[0]*255 ), (int)( aTColor[1]*255 ), (int)( aTColor[2]*255 ) ) );
+ myTitleFontCombo->setCurrentItem( aTitleTextPrp->GetFontFamily() );
+ myTitleBoldCheck->setChecked( aTitleTextPrp->GetBold() );
+ myTitleItalicCheck->setChecked( aTitleTextPrp->GetItalic() );
+ myTitleShadowCheck->setChecked( aTitleTextPrp->GetShadow() );
+
+ vtkTextProperty* aLabelsTextPrp = myScalarBarActor->GetLabelTextProperty();
+ float aLColor[3];
+ aLabelsTextPrp->GetColor( aLColor );
+ myLabelsColorBtn->setPaletteBackgroundColor( QColor( (int)( aLColor[0]*255 ), (int)( aLColor[1]*255 ), (int)( aLColor[2]*255 ) ) );
+ myLabelsFontCombo->setCurrentItem( aLabelsTextPrp->GetFontFamily() );
+ myLabelsBoldCheck->setChecked( aLabelsTextPrp->GetBold() );
+ myLabelsItalicCheck->setChecked( aLabelsTextPrp->GetItalic() );
+ myLabelsShadowCheck->setChecked( aLabelsTextPrp->GetShadow() );
+
+ myLabelsSpin->setValue( myScalarBarActor->GetNumberOfLabels() );
+ myColorsSpin->setValue( myScalarBarActor->GetMaximumNumberOfColors() );
+
+ if ( myScalarBarActor->GetOrientation() == VTK_ORIENT_VERTICAL )
+ myVertRadioBtn->setChecked( true );
+ else
+ myHorizRadioBtn->setChecked( true );
+ myIniOrientation = myVertRadioBtn->isChecked();
+
+ myIniX = myScalarBarActor->GetPosition()[0];
+ myIniY = myScalarBarActor->GetPosition()[1];
+ myIniW = myScalarBarActor->GetWidth();
+ myIniH = myScalarBarActor->GetHeight();
+ setOriginAndSize( myIniX, myIniY, myIniW, myIniH );
+
+ myRangeGrp->setEnabled( true );
+ myFontGrp->setEnabled( true );
+ myLabColorGrp->setEnabled( true );
+ myOrientationGrp->setEnabled( true );
+ myOriginDimGrp->setEnabled( true );
+ myOkBtn->setEnabled( true );
+ myApplyBtn->setEnabled( true );
+ return;
+ }
+ }
+ }
+ myActor = 0;
+ myRangeGrp->setEnabled( false );
+ myFontGrp->setEnabled( false );
+ myLabColorGrp->setEnabled( false );
+ myOrientationGrp->setEnabled( false );
+ myOriginDimGrp->setEnabled( false );
+ myOkBtn->setEnabled( false );
+ myApplyBtn->setEnabled( false );
+ }
+}
+
+//=================================================================================================
+/*!
+ * SMESHGUI_Preferences_ScalarBarDlg::closeEvent
+ *
+ * Close event handler
+ */
+//=================================================================================================
+void SMESHGUI_Preferences_ScalarBarDlg::closeEvent( QCloseEvent* e )
+{
+ if ( mySelection ) // "Properties" dialog box
+ myDlg = 0;
+ QDialog::closeEvent( e );
+}
+
+//=================================================================================================
+/*!
+ * SMESHGUI_Preferences_ScalarBarDlg::onXYChanged
+ *
+ * Called when X, Y values are changed
+ */
+//=================================================================================================
+void SMESHGUI_Preferences_ScalarBarDlg::onXYChanged()
+{
+ myWidthSpin->setMaxValue( 1.0 - myXSpin->value() );
+ myHeightSpin->setMaxValue( 1.0 - myYSpin->value() );
+}
+
+//=================================================================================================
+/*!
+ * SMESHGUI_Preferences_ScalarBarDlg::setOriginAndSize
+ *
+ * Called when X, Y values are changed
+ */
+//=================================================================================================
+void SMESHGUI_Preferences_ScalarBarDlg::setOriginAndSize( const double x,
+ const double y,
+ const double w,
+ const double h )
+{
+ blockSignals( true );
+ myXSpin->setValue( x );
+ myYSpin->setValue( y );
+ myWidthSpin->setMaxValue( 1.0 );
+ myWidthSpin->setValue( w );
+ myHeightSpin->setMaxValue( 1.0 );
+ myHeightSpin->setValue( h );
+ blockSignals( false );
+ onXYChanged();
+}
+
+//=================================================================================================
+/*!
+ * SMESHGUI_Preferences_ScalarBarDlg::onOrientationChanged
+ *
+ * Called when orientation is changed
+ */
+//=================================================================================================
+void SMESHGUI_Preferences_ScalarBarDlg::onOrientationChanged()
+{
+ int aOrientation = myVertRadioBtn->isChecked();
+ if ( aOrientation == myIniOrientation )
+ setOriginAndSize( myIniX, myIniY, myIniW, myIniH );
+ else
+ setOriginAndSize( aOrientation ? DEF_VER_X : DEF_HOR_X,
+ aOrientation ? DEF_VER_Y : DEF_HOR_Y,
+ aOrientation ? DEF_VER_W : DEF_HOR_W,
+ aOrientation ? DEF_VER_H : DEF_HOR_H );
+}
#ifndef SMESHGUI_PREFERENCES_SCALARBARDLG_H
#define SMESHGUI_PREFERENCES_SCALARBARDLG_H
-#include <qvariant.h>
#include <qdialog.h>
-class QVBoxLayout;
-class QHBoxLayout;
-class QGridLayout;
+
class QButtonGroup;
class QCheckBox;
class QComboBox;
class QLabel;
class QLineEdit;
class QPushButton;
+class QToolButton;
class QRadioButton;
class QSpinBox;
+class QAD_SpinBoxDbl;
+class SALOME_Selection;
+class SMESH_Actor;
class SMESHGUI_Preferences_ScalarBarDlg : public QDialog
{
- Q_OBJECT
+ Q_OBJECT
public:
- SMESHGUI_Preferences_ScalarBarDlg( QWidget* parent = 0, const char* name = 0, bool modal = FALSE, WFlags fl = 0 );
- ~SMESHGUI_Preferences_ScalarBarDlg();
-
- QButtonGroup* ButtonGroup_Orientation;
- QRadioButton* RadioHoriz;
- QRadioButton* RadioVert;
- QGroupBox* Properties;
- QLabel* NumberLabels;
- QLabel* NumberColors;
- QSpinBox* SpinBoxLabels;
- QSpinBox* SpinBoxColors;
- QLabel* TextLabel2;
- QComboBox* ComboBox1;
- QCheckBox* Shadow;
- QCheckBox* Italic;
- QCheckBox* Bold;
- QGroupBox* GroupBox5;
- QLineEdit* LineEditWidth;
- QLineEdit* LineEditHeight;
- QLabel* Height;
- QLabel* Width;
- QPushButton* buttonCancel;
- QPushButton* buttonOk;
+ ~SMESHGUI_Preferences_ScalarBarDlg();
+ static void ScalarBarPreferences( QWidget* parent );
+ static void ScalarBarProperties ( QWidget* parent, SALOME_Selection* Sel );
protected:
- QGridLayout* grid;
- QGridLayout* grid_2;
- QGridLayout* grid_3;
- QGridLayout* grid_4;
- QGridLayout* grid_5;
- QGridLayout* grid_6;
- QGridLayout* grid_7;
- QGridLayout* grid_8;
- QGridLayout* grid_9;
- QGridLayout* grid_10;
- QGridLayout* grid_11;
- QGridLayout* grid_12;
- QGridLayout* grid_13;
- QGridLayout* grid_14;
- QGridLayout* grid_15;
+ SMESHGUI_Preferences_ScalarBarDlg( QWidget* parent = 0, SALOME_Selection* Sel = 0, bool modal = FALSE );
+ static SMESHGUI_Preferences_ScalarBarDlg* myDlg;
+ void closeEvent( QCloseEvent* e );
+ void setOriginAndSize( const double x, const double y, const double w, const double h );
+
+protected slots:
+ void onOk();
+ bool onApply();
+ void onCancel();
+ void onTitleColor();
+ void onLabelsColor();
+ void onSelectionChanged();
+ void onXYChanged();
+ void onOrientationChanged();
+
+private:
+ SALOME_Selection* mySelection;
+ SMESH_Actor* myActor;
+ double myIniX, myIniY, myIniW, myIniH;
+ int myIniOrientation;
+
+ QGroupBox* myRangeGrp;
+ QLineEdit* myMinEdit;
+ QLineEdit* myMaxEdit;
+
+ QGroupBox* myFontGrp;
+ QToolButton* myTitleColorBtn;
+ QComboBox* myTitleFontCombo;
+ QCheckBox* myTitleBoldCheck;
+ QCheckBox* myTitleItalicCheck;
+ QCheckBox* myTitleShadowCheck;
+ QToolButton* myLabelsColorBtn;
+ QComboBox* myLabelsFontCombo;
+ QCheckBox* myLabelsBoldCheck;
+ QCheckBox* myLabelsItalicCheck;
+ QCheckBox* myLabelsShadowCheck;
+
+ QGroupBox* myLabColorGrp;
+ QSpinBox* myColorsSpin;
+ QSpinBox* myLabelsSpin;
+
+ QButtonGroup* myOrientationGrp;
+ QRadioButton* myVertRadioBtn;
+ QRadioButton* myHorizRadioBtn;
+
+ QGroupBox* myOriginDimGrp;
+ QAD_SpinBoxDbl* myXSpin;
+ QAD_SpinBoxDbl* myYSpin;
+ QAD_SpinBoxDbl* myWidthSpin;
+ QAD_SpinBoxDbl* myHeightSpin;
+
+ QGroupBox* myButtonGrp;
+ QPushButton* myOkBtn;
+ QPushButton* myApplyBtn;
+ QPushButton* myCancelBtn;
};
#endif // SMESHGUI_PREFERENCES_SCALARBARDLG_H
--- /dev/null
+// SMESH SMESHGUI : GUI for SMESH component
+//
+// Copyright (C) 2003 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
+// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
+//
+// This library 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.
+//
+// This library 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 this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+//
+// See http://www.salome-platform.org or email : webmaster.salome@opencascade.org
+//
+//
+//
+// File : SMESHGUI_Preferences_SelectionDlg.cxx
+// Author : Natalia KOPNOVA
+// Module : SMESH
+// $Header$
+
+using namespace std;
+#include "SMESHGUI_Preferences_SelectionDlg.h"
+#include "SMESHGUI.h"
+
+#include <qgroupbox.h>
+#include <qlayout.h>
+#include <qlabel.h>
+#include <qlineedit.h>
+#include <qvalidator.h>
+#include <qspinbox.h>
+#include <qpushbutton.h>
+#include <qpalette.h>
+#include <qcolordialog.h>
+
+//=================================================================================
+// class : SMESHGUI_LineEdit
+// purpose :
+//=================================================================================
+SMESHGUI_LineEdit::SMESHGUI_LineEdit(QWidget* parent, const char *name)
+ : QLineEdit(parent, name)
+{
+}
+
+SMESHGUI_LineEdit::SMESHGUI_LineEdit(const QString& text, QWidget* parent, const char *name)
+ : QLineEdit(text, parent, name)
+{
+}
+
+void SMESHGUI_LineEdit::focusOutEvent(QFocusEvent* e)
+{
+ const QValidator* aVal = validator();
+ QString aText = text();
+ int aCurPos = cursorPosition();
+ if (aVal && aVal->validate(aText, aCurPos) != QValidator::Acceptable) {
+ QString aValid = aText;
+ aVal->fixup(aValid);
+ if (aText != aValid) {
+ setText(aValid);
+ update();
+ return;
+ }
+ }
+ QLineEdit::focusOutEvent(e);
+}
+
+
+//=================================================================================
+// class : SMESHGUI_DoubleValidator
+// purpose :
+//=================================================================================
+SMESHGUI_DoubleValidator::SMESHGUI_DoubleValidator(QObject * parent, const char *name)
+ : QDoubleValidator(parent, name)
+{
+}
+
+SMESHGUI_DoubleValidator::SMESHGUI_DoubleValidator(double bottom, double top, int decimals,
+ QObject * parent, const char *name)
+ : QDoubleValidator(bottom, top, decimals, parent, name)
+{
+}
+
+void SMESHGUI_DoubleValidator::fixup(QString& theText) const
+{
+ bool ok;
+ double aValue = theText.toDouble(&ok);
+ if (ok) {
+ if (aValue < bottom())
+ theText = QString::number(bottom(), 'g', decimals());
+ if (aValue > top())
+ theText = QString::number(top(), 'g', decimals());
+ }
+}
+
+
+//=================================================================================
+// class : SMESHGUI_Preferences_SelectionDlg()
+// purpose :
+//=================================================================================
+SMESHGUI_Preferences_SelectionDlg::SMESHGUI_Preferences_SelectionDlg( QWidget* parent, const char* name )
+ : QDialog( parent, name, true, WStyle_Customize | WStyle_NormalBorder | WStyle_Title | WStyle_SysMenu )
+{
+ if ( !name ) setName( "SMESHGUI_Preferences_SelectionDlg" );
+ setCaption( tr( "SMESH_PREF_SELECTION" ) );
+
+ QVBoxLayout* aMainLayout = new QVBoxLayout(this, 11, 6);
+ QLabel* aLabel;
+
+ /***************************************************************/
+ QGroupBox* aSelectBox = new QGroupBox(4, Qt::Horizontal, this, "selection");
+ aSelectBox->setTitle(tr("SMESH_SELECTION"));
+
+ aLabel = new QLabel(aSelectBox, "selection color label");
+ aLabel->setText(tr("SMESH_OUTLINE_COLOR"));
+ myColor[2] = new QPushButton(aSelectBox, "outline color");
+ myColor[2]->setFixedSize(QSize(25, 25));
+
+ aSelectBox->addSpace(0);
+ aSelectBox->addSpace(0);
+
+ aLabel = new QLabel(aSelectBox, "selection color label");
+ aLabel->setText(tr("SMESH_ELEMENTS_COLOR"));
+ myColor[1] = new QPushButton(aSelectBox, "elements color");
+ myColor[1]->setFixedSize(QSize(25, 25));
+
+ aLabel = new QLabel(aSelectBox, "selection width label");
+ aLabel->setText(tr("SMESH_WIDTH"));
+ myWidth[1] = new QSpinBox(0, 5, 1, aSelectBox, "selection width");
+ myWidth[1]->setSizePolicy(QSizePolicy(QSizePolicy::Expanding, QSizePolicy::Fixed));
+ myWidth[1]->setButtonSymbols(QSpinBox::PlusMinus);
+ myWidth[1]->setMinimumWidth(50);
+
+ /***************************************************************/
+ QGroupBox* aPreSelectBox = new QGroupBox(1, Qt::Vertical, this, "preselection");
+ aPreSelectBox->setTitle(tr("SMESH_PRESELECTION"));
+
+ aLabel = new QLabel(aPreSelectBox, "preselection color label");
+ aLabel->setText(tr("SMESH_HILIGHT_COLOR"));
+ myColor[0] = new QPushButton(aPreSelectBox, "preselection color");
+ myColor[0]->setFixedSize(QSize(25, 25));
+
+ aLabel = new QLabel(aPreSelectBox, "preselection width label");
+ aLabel->setText(tr("SMESH_WIDTH"));
+ myWidth[0] = new QSpinBox(0, 5, 1, aPreSelectBox, "preselection width");
+ myWidth[0]->setSizePolicy(QSizePolicy(QSizePolicy::Expanding, QSizePolicy::Fixed));
+ myWidth[0]->setButtonSymbols(QSpinBox::PlusMinus);
+ myWidth[0]->setMinimumWidth(50);
+
+ /***************************************************************/
+ QGroupBox* aPrecisionBox = new QGroupBox(1, Qt::Vertical, this, "preselection");
+ aPrecisionBox->setTitle(tr("SMESH_PRECISION"));
+ QDoubleValidator* aValidator = new SMESHGUI_DoubleValidator(aPrecisionBox);
+ aValidator->setBottom(0.001);
+ aValidator->setDecimals(6);
+
+ aLabel = new QLabel(aPrecisionBox, "node tol label");
+ aLabel->setText(tr("SMESH_NODES"));
+ myPrecision[0] = new SMESHGUI_LineEdit(aPrecisionBox, "node precision");
+ myPrecision[0]->setValidator(aValidator);
+
+ aLabel = new QLabel(aPrecisionBox, "item tol label");
+ aLabel->setText(tr("SMESH_ELEMENTS"));
+ myPrecision[1] = new SMESHGUI_LineEdit(aPrecisionBox, "item precision");
+ myPrecision[1]->setValidator(aValidator);
+
+ /***************************************************************/
+ QFrame* aButtons = new QFrame(this, "button box");
+ aButtons->setFrameStyle(QFrame::Box | QFrame::Sunken);
+ QHBoxLayout* aBtnLayout = new QHBoxLayout(aButtons, 11, 6);
+ aBtnLayout->setAutoAdd(false);
+
+ QPushButton* aOKBtn = new QPushButton(aButtons, "ok");
+ aOKBtn->setText(tr("SMESH_BUT_OK"));
+ aOKBtn->setAutoDefault(true);
+ aOKBtn->setDefault(true);
+ QPushButton* aCloseBtn = new QPushButton(aButtons, "close");
+ aCloseBtn->setText(tr("SMESH_BUT_CLOSE"));
+ aCloseBtn->setAutoDefault(true);
+
+ aBtnLayout->addWidget(aOKBtn);
+ aBtnLayout->addStretch();
+ aBtnLayout->addWidget(aCloseBtn);
+
+ /***************************************************************/
+ aMainLayout->addWidget(aSelectBox);
+ aMainLayout->addWidget(aPreSelectBox);
+ aMainLayout->addWidget(aPrecisionBox);
+ aMainLayout->addWidget(aButtons);
+
+ for (int i = 0; i < 3; i++)
+ connect(myColor[i], SIGNAL(clicked()), this, SLOT(onSelectColor()));
+
+ connect(aOKBtn, SIGNAL(clicked()), this, SLOT(accept()));
+ connect(aCloseBtn, SIGNAL(clicked()), this, SLOT(reject()));
+
+ /* Move widget on the botton right corner of main widget */
+ int x, y ;
+ SMESHGUI::GetSMESHGUI()->DefineDlgPosition(this, x, y);
+ this->move(x, y);
+}
+
+//=================================================================================
+// function : ~SMESHGUI_Preferences_SelectionDlg()
+// purpose : Destroys the object and frees any allocated resources
+//=================================================================================
+SMESHGUI_Preferences_SelectionDlg::~SMESHGUI_Preferences_SelectionDlg()
+{
+ // no need to delete child widgets, Qt does it all for us
+}
+
+//=================================================================================
+// function : closeEvent()
+// purpose :
+//=================================================================================
+void SMESHGUI_Preferences_SelectionDlg::closeEvent( QCloseEvent* e )
+{
+ reject();
+}
+
+//=================================================================================
+// function : onSelectColor()
+// purpose :
+//=================================================================================
+void SMESHGUI_Preferences_SelectionDlg::onSelectColor()
+{
+ QPushButton* aSender = (QPushButton*)sender();
+ QColor aColor = aSender->palette().active().button();
+ aColor = QColorDialog::getColor(aColor, this);
+ if (aColor.isValid()) {
+ QPalette aPal = aSender->palette();
+ aPal.setColor(QColorGroup::Button, aColor);
+ aSender->setPalette(aPal);
+ }
+}
+
+//=================================================================================
+// function : SetColor()
+// purpose :
+//=================================================================================
+void SMESHGUI_Preferences_SelectionDlg::SetColor(int type, QColor color)
+{
+ if (type > 0 && type <= 3) {
+ QPalette aPal = myColor[type-1]->palette();
+ aPal.setColor(QColorGroup::Button, color);
+ myColor[type-1]->setPalette(aPal);
+ }
+}
+
+//=================================================================================
+// function : GetColor()
+// purpose :
+//=================================================================================
+QColor SMESHGUI_Preferences_SelectionDlg::GetColor(int type)
+{
+ QColor aColor;
+ if (type > 0 && type <= 3)
+ aColor = myColor[type-1]->palette().active().button();
+ return aColor;
+}
+
+//=================================================================================
+// function : SetWidth()
+// purpose :
+//=================================================================================
+void SMESHGUI_Preferences_SelectionDlg::SetWidth(int type, int value)
+{
+ if (type > 0 && type <= 2)
+ myWidth[type-1]->setValue(value);
+}
+
+//=================================================================================
+// function : GetWidth()
+// purpose :
+//=================================================================================
+int SMESHGUI_Preferences_SelectionDlg::GetWidth(int type)
+{
+ if (type > 0 && type <= 2)
+ return myWidth[type-1]->value();
+ return 0;
+}
+
+//=================================================================================
+// function : SetPrecision()
+// purpose :
+//=================================================================================
+void SMESHGUI_Preferences_SelectionDlg::SetPrecision(int type, double value)
+{
+ if (type > 0 && type <= 2)
+ myPrecision[type-1]->setText(QString::number(value));
+}
+
+//=================================================================================
+// function : GetPrecision()
+// purpose :
+//=================================================================================
+double SMESHGUI_Preferences_SelectionDlg::GetPrecision(int type)
+{
+ if (type > 0 && type <= 2)
+ return myPrecision[type-1]->text().toDouble();
+}
--- /dev/null
+// SMESH SMESHGUI : GUI for SMESH component
+//
+// Copyright (C) 2003 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
+// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
+//
+// This library 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.
+//
+// This library 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 this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+//
+// See http://www.salome-platorm.org or email : webmaster.salome@opencascade.org
+//
+//
+//
+// File : SMESHGUI_Preferences_SelectionDlg.h
+// Author : Natalia KOPNOVA
+// Module : SMESH
+// $Header$
+
+#ifndef SMESHGUI_PREFERENCES_SELECTIONDLG_H
+#define SMESHGUI_PREFERENCES_SELECTIONDLG_H
+
+
+// QT Includes
+#include <qdialog.h>
+#include <qlineedit.h>
+#include <qvalidator.h>
+
+class QPushButton;
+class QSpinBox;
+class QColor;
+
+class SMESHGUI_LineEdit : public QLineEdit
+{
+ Q_OBJECT
+
+ public:
+ SMESHGUI_LineEdit(QWidget* parent, const char* name = 0);
+ SMESHGUI_LineEdit(const QString& text, QWidget* parent, const char* name = 0);
+
+ ~SMESHGUI_LineEdit() {};
+
+ protected:
+ void focusOutEvent(QFocusEvent* e);
+};
+
+class SMESHGUI_DoubleValidator : public QDoubleValidator
+{
+ Q_OBJECT
+
+ public:
+ SMESHGUI_DoubleValidator(QObject* parent, const char* name = 0);
+ SMESHGUI_DoubleValidator(double bottom, double top, int decimals,
+ QObject* parent, const char* name = 0);
+
+ ~SMESHGUI_DoubleValidator() {};
+
+ void fixup(QString& text) const;
+};
+
+class SMESHGUI_Preferences_SelectionDlg : public QDialog
+{
+ Q_OBJECT
+
+public:
+ SMESHGUI_Preferences_SelectionDlg( QWidget* parent = 0, const char* name = 0 );
+ ~SMESHGUI_Preferences_SelectionDlg();
+
+ void SetColor(int type, QColor color);
+ QColor GetColor(int type);
+ void SetWidth(int type, int value);
+ int GetWidth(int type);
+ void SetPrecision(int type, double value);
+ double GetPrecision(int type);
+
+private:
+ void closeEvent( QCloseEvent* e ) ;
+
+private slots:
+ void onSelectColor();
+
+private:
+ QPushButton* myColor[3];
+ QSpinBox* myWidth[2];
+ QLineEdit* myPrecision[2];
+};
+
+#endif // SMESHGUI_PREFERENCES_SELECTIONDLG_H
//=================================================================================
void SMESHGUI_RemoveElementsDlg::ClickOnCancel()
{
- QAD_Application::getDesktop()->SetSelectionMode( 4 );
+ QAD_Application::getDesktop()->SetSelectionMode( ActorSelection );
disconnect( mySelection, 0, this, 0 );
mySMESHGUI->ResetState() ;
reject() ;
if(nbElements < 1)
return ;
- if ( mySelection->SelectionMode() != 3 ) {
+ if ( mySelection->SelectionMode() != CellSelection ) {
QAD_MessageBox::warn1 ( QAD_Application::getDesktop(), tr ("SMESH_WRN_WARNING"),
- tr ("SMESH_WRN_SELECTIONMODE_ELEMENTS"), tr ("SMESH_BUT_YES") );
+ tr ("SMESH_WRN_SELECTIONMODE_ELEMENTS"), tr ("SMESH_BUT_OK") );
return;
}
//=================================================================================
void SMESHGUI_RemoveNodesDlg::ClickOnCancel()
{
- QAD_Application::getDesktop()->SetSelectionMode( 4 );
+ QAD_Application::getDesktop()->SetSelectionMode( ActorSelection );
disconnect( mySelection, 0, this, 0 );
mySMESHGUI->ResetState() ;
mySMESHGUI->EraseSimulationActors();
if(nbNodes < 1)
return ;
- if ( mySelection->SelectionMode() != 1 ){
+ if ( mySelection->SelectionMode() != NodeSelection ){
QAD_MessageBox::warn1 ( QAD_Application::getDesktop(), tr ("SMESH_WRN_WARNING"),
- tr ("SMESH_WRN_SELECTIONMODE_NODES"), tr ("SMESH_BUT_YES") );
+ tr ("SMESH_WRN_SELECTIONMODE_NODES"), tr ("SMESH_BUT_OK") );
return;
}
SMESHGUI_StudyAPI::SMESHGUI_StudyAPI ( SALOMEDS::Study_ptr aStudy,
SMESH::SMESH_Gen_ptr CompMesh)
{
- myStudy = aStudy;
- myStudyBuilder = aStudy->NewBuilder();
-
setOrb();
-
- // NRI : Temporary added
- if ( myStudy->GetProperties()->IsLocked() ) {
-// QAD_MessageBox::warn1 ( (QWidget*)QAD_Application::getDesktop(),
-// QObject::tr("WARNING"),
-// QObject::tr("WRN_STUDY_LOCKED"),
-// QObject::tr("BUT_OK") );
-
- return;
- }
- // NRI
-
- SALOMEDS::SComponent_var father = aStudy->FindComponent("MESH");
- /*SALOMEDS::GenericAttribute_var anAttr;
- SALOMEDS::AttributeName_var aName;
- SALOMEDS::AttributePixMap_var aPixmap;
-
- if (father->_is_nil()) {
- father = myStudyBuilder->NewComponent("MESH");
- }
- anAttr = myStudyBuilder->FindOrCreateAttribute(father, "AttributeName");
- aName = SALOMEDS::AttributeName::_narrow(anAttr);
- //NRI aName->SetValue(QObject::tr("SMESH_MEN_COMPONENT"));
- aName->SetValue( QAD_Application::getDesktop()->getComponentUserName( "SMESH" ) );
- anAttr = myStudyBuilder->FindOrCreateAttribute(father, "AttributePixMap");
- aPixmap = SALOMEDS::AttributePixMap::_narrow(anAttr);
- aPixmap->SetPixMap( "ICON_OBJBROWSER_SMESH" );
-
- myStudyBuilder->DefineComponentInstance(father, CompMesh );
- mySComponentMesh = SALOMEDS::SComponent::_narrow( father );*/
+ Update( aStudy );
}
//=======================================================================
// function :
// purpose : Update
//=======================================================================
-void SMESHGUI_StudyAPI::Update(SMESH::SMESH_Gen_ptr CompMesh)
-{
- // NRI : Temporary added
- if ( myStudy->GetProperties()->IsLocked() ) {
- return;
- }
- // NRI
-
- SALOMEDS::SComponent_var father = myStudy->FindComponent("MESH");
- SALOMEDS::GenericAttribute_var anAttr;
- SALOMEDS::AttributeName_var aName;
- SALOMEDS::AttributePixMap_var aPixmap;
-
- if (father->_is_nil()) {
- father = myStudyBuilder->NewComponent("MESH");
- anAttr = myStudyBuilder->FindOrCreateAttribute(father, "AttributeName");
- aName = SALOMEDS::AttributeName::_narrow(anAttr);
- //NRI aName->SetValue(QObject::tr("SMESH_MEN_COMPONENT"));
- aName->SetValue( QAD_Application::getDesktop()->getComponentUserName( "SMESH" ) );
- anAttr = myStudyBuilder->FindOrCreateAttribute(father, "AttributePixMap");
- aPixmap = SALOMEDS::AttributePixMap::_narrow(anAttr);
- aPixmap->SetPixMap( "ICON_OBJBROWSER_SMESH" );
- }
- myStudyBuilder->DefineComponentInstance(father, CompMesh );
- mySComponentMesh = SALOMEDS::SComponent::_narrow( father );
-}
-
-//=======================================================================
-// function : AddNewMesh
-// purpose :
-//=======================================================================
-
-SALOMEDS::SObject_ptr SMESHGUI_StudyAPI::AddNewMesh (SMESH::SMESH_Mesh_ptr M)
+void SMESHGUI_StudyAPI::Update(SALOMEDS::Study_ptr aStudy)
{
- // NRI : Temporary added
- if ( myStudy->GetProperties()->IsLocked() ) {
- return SALOMEDS::SObject::_nil();
- }
- // NRI
-
- //Find or Create Hypothesis root
- SALOMEDS::SObject_var HypothesisRoot;
- SALOMEDS::GenericAttribute_var anAttr;
- SALOMEDS::AttributeName_var aName;
- SALOMEDS::AttributeIOR_var anIOR;
- SALOMEDS::AttributeSelectable_var aSelAttr;
- SALOMEDS::AttributePixMap_var aPixmap;
-
- if (!mySComponentMesh->FindSubObject (Tag_HypothesisRoot, HypothesisRoot)) {
- HypothesisRoot = myStudyBuilder->NewObjectToTag (mySComponentMesh, Tag_HypothesisRoot);
- anAttr = myStudyBuilder->FindOrCreateAttribute(HypothesisRoot, "AttributeName");
- aName = SALOMEDS::AttributeName::_narrow(anAttr);
- aName->SetValue(QObject::tr("SMESH_MEN_HYPOTHESIS"));
- anAttr = myStudyBuilder->FindOrCreateAttribute(HypothesisRoot, "AttributePixMap");
- aPixmap = SALOMEDS::AttributePixMap::_narrow(anAttr);
- aPixmap->SetPixMap( "ICON_SMESH_TREE_HYPO" );
- anAttr = myStudyBuilder->FindOrCreateAttribute(HypothesisRoot, "AttributeSelectable");
- aSelAttr = SALOMEDS::AttributeSelectable::_narrow(anAttr);
- aSelAttr->SetSelectable(false);
- }
-
- SALOMEDS::SObject_var AlgorithmsRoot;
- if (!mySComponentMesh->FindSubObject (Tag_AlgorithmsRoot, AlgorithmsRoot)) {
- AlgorithmsRoot = myStudyBuilder->NewObjectToTag (mySComponentMesh, Tag_AlgorithmsRoot);
- anAttr = myStudyBuilder->FindOrCreateAttribute(AlgorithmsRoot, "AttributeName");
- aName = SALOMEDS::AttributeName::_narrow(anAttr);
- aName->SetValue(QObject::tr("SMESH_MEN_ALGORITHMS"));
- anAttr = myStudyBuilder->FindOrCreateAttribute(AlgorithmsRoot, "AttributePixMap");
- aPixmap = SALOMEDS::AttributePixMap::_narrow(anAttr);
- aPixmap->SetPixMap( "ICON_SMESH_TREE_ALGO" );
- anAttr = myStudyBuilder->FindOrCreateAttribute(AlgorithmsRoot, "AttributeSelectable");
- aSelAttr = SALOMEDS::AttributeSelectable::_narrow(anAttr);
- aSelAttr->SetSelectable(false);
- }
-
- // Add New Mesh
- SALOMEDS::SObject_var newMesh = myStudyBuilder->NewObject(mySComponentMesh);
- anAttr = myStudyBuilder->FindOrCreateAttribute(newMesh, "AttributePixMap");
- aPixmap = SALOMEDS::AttributePixMap::_narrow(anAttr);
- aPixmap->SetPixMap( "ICON_SMESH_TREE_MESH" );
- anAttr = myStudyBuilder->FindOrCreateAttribute(newMesh, "AttributeIOR");
- anIOR = SALOMEDS::AttributeIOR::_narrow(anAttr);
- anIOR->SetValue(IORToString(M));
- return SALOMEDS::SObject::_narrow( newMesh );
+ myStudy = SALOMEDS::Study::_duplicate( aStudy );
+ myStudyBuilder = aStudy->NewBuilder();
}
-
//=======================================================================
// function : SetShape
// purpose :
}
// NRI
+ if ( SO_Mesh_Or_SubMesh->_is_nil() )
+ return GEOM::GEOM_Shape::_nil();
+
GEOM::GEOM_Shape_var Shape;
SALOMEDS::SObject_var aSO, aGeom;
SALOMEDS::GenericAttribute_var anAttr;
return GEOM::GEOM_Shape::_nil();
}
-//=======================================================================
-// function : AddNewHypothesis
-// purpose :
-//=======================================================================
-SALOMEDS::SObject_ptr SMESHGUI_StudyAPI::AddNewHypothesis (SMESH::SMESH_Hypothesis_ptr H)
-{
- // NRI : Temporary added
- if ( myStudy->GetProperties()->IsLocked() ) {
- return SALOMEDS::SObject::_nil();
- }
- // NRI
-
- //Find or Create Hypothesis root
- SALOMEDS::SObject_var HypothesisRoot;
- SALOMEDS::GenericAttribute_var anAttr;
- SALOMEDS::AttributeName_var aName;
- SALOMEDS::AttributeIOR_var anIOR;
- SALOMEDS::AttributeSelectable_var aSelAttr;
- SALOMEDS::AttributePixMap_var aPixmap;
-
- if (!mySComponentMesh->FindSubObject (Tag_HypothesisRoot, HypothesisRoot)) {
- HypothesisRoot = myStudyBuilder->NewObjectToTag (mySComponentMesh, Tag_HypothesisRoot);
- anAttr = myStudyBuilder->FindOrCreateAttribute(HypothesisRoot, "AttributeName");
- aName = SALOMEDS::AttributeName::_narrow(anAttr);
- aName->SetValue(QObject::tr("SMESH_MEN_HYPOTHESIS"));
- anAttr = myStudyBuilder->FindOrCreateAttribute(HypothesisRoot, "AttributeSelectable");
- aSelAttr = SALOMEDS::AttributeSelectable::_narrow(anAttr);
- aSelAttr->SetSelectable(false);
- anAttr = myStudyBuilder->FindOrCreateAttribute(HypothesisRoot, "AttributePixMap");
- aPixmap = SALOMEDS::AttributePixMap::_narrow(anAttr);
- aPixmap->SetPixMap( "ICON_SMESH_TREE_HYPO" );
- }
- // Add New Hypothesis
- SALOMEDS::SObject_var newHypo = myStudyBuilder->NewObject(HypothesisRoot);
- anAttr = myStudyBuilder->FindOrCreateAttribute(newHypo, "AttributePixMap");
- aPixmap = SALOMEDS::AttributePixMap::_narrow(anAttr);
- QString aType = H->GetName();
- MESSAGE ( " aType " << aType )
- aPixmap->SetPixMap( "ICON_SMESH_TREE_HYPO_" + aType );
- // if ( aType.compare("LocalLength") == 0 )
- // aPixmap->SetPixMap( "ICON_SMESH_TREE_HYPO_LENGTH" );
- // else if ( aType.compare("NumberOfSegments") == 0 )
- // aPixmap->SetPixMap( "ICON_SMESH_TREE_HYPO_SEGMENT" );
- // else if ( aType.compare("MaxElementArea") == 0 )
- // aPixmap->SetPixMap( "ICON_SMESH_TREE_HYPO_AREA" );
- // else if ( aType.compare("MaxElementVolume") == 0 )
- // aPixmap->SetPixMap( "ICON_SMESH_TREE_HYPO_VOLUME" );
- anAttr = myStudyBuilder->FindOrCreateAttribute(newHypo, "AttributeIOR");
- anIOR = SALOMEDS::AttributeIOR::_narrow(anAttr);
- anIOR->SetValue(IORToString(H));
- return SALOMEDS::SObject::_narrow(newHypo);
-}
-
-//=======================================================================
-// function : AddNewAlgorithms
-// purpose :
-//=======================================================================
-SALOMEDS::SObject_ptr SMESHGUI_StudyAPI::AddNewAlgorithms (SMESH::SMESH_Hypothesis_ptr H)
-{
- // NRI : Temporary added
- if ( myStudy->GetProperties()->IsLocked() ) {
- return SALOMEDS::SObject::_nil();
- }
- // NRI
-
- //Find or Create Algorithms root
- SALOMEDS::SObject_var AlgorithmsRoot;
- SALOMEDS::GenericAttribute_var anAttr;
- SALOMEDS::AttributeName_var aName;
- SALOMEDS::AttributeIOR_var anIOR;
- SALOMEDS::AttributeSelectable_var aSelAttr;
- SALOMEDS::AttributePixMap_var aPixmap;
-
- if (!mySComponentMesh->FindSubObject (Tag_AlgorithmsRoot, AlgorithmsRoot)) {
- AlgorithmsRoot = myStudyBuilder->NewObjectToTag (mySComponentMesh, Tag_AlgorithmsRoot);
- anAttr = myStudyBuilder->FindOrCreateAttribute(AlgorithmsRoot, "AttributeName");
- aName = SALOMEDS::AttributeName::_narrow(anAttr);
- aName->SetValue(QObject::tr("SMESH_MEN_ALGORITHMS"));
- anAttr = myStudyBuilder->FindOrCreateAttribute(AlgorithmsRoot, "AttributeSelectable");
- aSelAttr = SALOMEDS::AttributeSelectable::_narrow(anAttr);
- aSelAttr->SetSelectable(false);
- anAttr = myStudyBuilder->FindOrCreateAttribute(AlgorithmsRoot, "AttributePixMap");
- aPixmap = SALOMEDS::AttributePixMap::_narrow(anAttr);
- aPixmap->SetPixMap( "ICON_SMESH_TREE_ALGO" );
- }
- // Add New Algorithms
- SALOMEDS::SObject_var newHypo = myStudyBuilder->NewObject(AlgorithmsRoot);
- anAttr = myStudyBuilder->FindOrCreateAttribute(newHypo, "AttributePixMap");
- aPixmap = SALOMEDS::AttributePixMap::_narrow(anAttr);
- QString aType = H->GetName();
- // if ( aType.compare("Regular_1D") == 0 )
- aPixmap->SetPixMap( "ICON_SMESH_TREE_ALGO_" + aType );
- // aPixmap->SetPixMap( "ICON_SMESH_TREE_ALGO_REGULAR" );
- // else if ( aType.compare("MEFISTO_2D") == 0 )
- // aPixmap->SetPixMap( "ICON_SMESH_TREE_ALGO_MEFISTO" );
- // else if ( aType.compare("Quadrangle_2D") == 0 )
- // aPixmap->SetPixMap( "ICON_SMESH_TREE_ALGO_QUAD" );
- // else if ( aType.compare("Hexa_3D") == 0 )
- // aPixmap->SetPixMap( "ICON_SMESH_TREE_ALGO_HEXA" );
- anAttr = myStudyBuilder->FindOrCreateAttribute(newHypo, "AttributeIOR");
- anIOR = SALOMEDS::AttributeIOR::_narrow(anAttr);
- anIOR->SetValue(IORToString(H));
- return SALOMEDS::SObject::_narrow(newHypo);
-}
-
-
//=======================================================================
// function : AddSubMeshOnShape
// purpose :
// function :
// purpose :
//=======================================================================
-SALOMEDS::SObject_ptr SMESHGUI_StudyAPI::FindMesh (SMESH::SMESH_Mesh_ptr M)
+SALOMEDS::SObject_ptr SMESHGUI_StudyAPI::FindObject( CORBA::Object_ptr theObject )
{
// NRI : Temporary added
if ( myStudy->GetProperties()->IsLocked() ) {
return SALOMEDS::SObject::_nil();
}
// NRI
- return SALOMEDS::SObject::_narrow( myStudy->FindObjectIOR (IORToString(M)) );
-}
-
-//=======================================================================
-// function :
-// purpose :
-//=======================================================================
-SALOMEDS::SObject_ptr SMESHGUI_StudyAPI::FindHypothesisOrAlgorithms (SMESH::SMESH_Hypothesis_ptr H)
-{
- // NRI : Temporary added
- if ( myStudy->GetProperties()->IsLocked() ) {
- return SALOMEDS::SObject::_nil();
+ if ( !CORBA::is_nil ( theObject ) ) {
+ string anIOR = IORToString( theObject );
+ if ( anIOR != "" )
+ return myStudy->FindObjectIOR( anIOR.c_str() );
}
- // NRI
- return SALOMEDS::SObject::_narrow( myStudy->FindObjectIOR (IORToString(H)) );
-}
-
+ return SALOMEDS::SObject::_nil();
+}
//=======================================================================
// function :
// purpose :
//=======================================================================
-SALOMEDS::SObject_ptr SMESHGUI_StudyAPI::FindSubMesh (SMESH::SMESH_subMesh_ptr SM)
-{
- // NRI : Temporary added
- if ( myStudy->GetProperties()->IsLocked() ) {
- return SALOMEDS::SObject::_nil();
- }
- // NRI
- return SALOMEDS::SObject::_narrow( myStudy->FindObjectIOR (IORToString(SM)) );
-}
-
-
void SMESHGUI_StudyAPI::setOrb()
{
try {
ASSERT(! CORBA::is_nil(_orb));
}
-//=======================================================================
-// function :
-// purpose :
-//=======================================================================
-void SMESHGUI_StudyAPI::SetTagHypothesisRoot()
-{
- // NRI : Temporary added
- if ( myStudy->GetProperties()->IsLocked() ) {
- return;
- }
- // NRI
- SALOMEDS::ChildIterator_var it = myStudy->NewChildIterator(mySComponentMesh);
- int i = 0;
- for (; it->More();it->Next()) {
- i++;
- }
- Tag_HypothesisRoot = i++;
-}
-
//=======================================================================
// function :
// purpose :
#include CORBA_SERVER_HEADER(GEOM_Shape)
#include CORBA_SERVER_HEADER(SALOMEDS)
#include CORBA_SERVER_HEADER(SALOMEDS_Attributes)
+#include CORBA_SERVER_HEADER(SALOME_GenericObj)
class SMESH_subMesh_ptr;
SALOMEDS::SObject_ptr AddSubMeshOnShape (SALOMEDS::SObject_ptr SO_Mesh, SALOMEDS::SObject_ptr SO_GeomShape, SMESH::SMESH_subMesh_ptr SM, GEOM::shape_type ST);
- void Update(SMESH::SMESH_Gen_ptr Gen);
+ void Update(SALOMEDS::Study_ptr aStudy);
void ModifiedMesh( SALOMEDS::SObject_ptr MorSM, bool right);
SALOMEDS::SObject_ptr GetMeshOrSubmesh (SALOMEDS::SObject_ptr SO);
- SALOMEDS::SObject_ptr FindMesh (SMESH::SMESH_Mesh_ptr M);
+ SALOMEDS::SObject_ptr FindObject(CORBA::Object_ptr theObject);
- SALOMEDS::SObject_ptr FindHypothesisOrAlgorithms (SMESH::SMESH_Hypothesis_ptr H);
-
- SALOMEDS::SObject_ptr FindSubMesh (SMESH::SMESH_subMesh_ptr SM);
-
- //SALOMEDS::ListOfSObject_ptr FindMesh (SALOMEDS_SObject_ptr SO_GeomShape);
- //SALOMEDS_SObject_ptr FindSubMesh (SALOMEDS_SObject_ptr SO_Mesh, SALOMEDS_SObject_ptr SO_GeomShape);
-
static void setOrb();
private:
//fields
SALOMEDS::Study_var myStudy;
SALOMEDS::StudyBuilder_var myStudyBuilder;
- SALOMEDS::SComponent_var mySComponentMesh;
-
};
#endif
Engines::Component_var comp = QAD_Application::getDesktop()->getEngine("FactoryServer", "SMESH");
SMESH::SMESH_Gen_var CompMesh = SMESH::SMESH_Gen::_narrow(comp);
+ Engines::Component_var comp1 = QAD_Application::getDesktop()->getEngine("FactoryServer", "GEOM");
+ GEOM::GEOM_Gen_var CompGeom = GEOM::GEOM_Gen::_narrow(comp1);
+
QAD_ResourceMgr* resMgr = QAD_Desktop::createResourceManager();
if ( resMgr ) {
QString msg;
CORBA::Object_var obj = QAD_Application::getDesktop()->getNameService()->Resolve("/myStudyManager");
SALOMEDS::StudyManager_var myStudyMgr = SALOMEDS::StudyManager::_narrow(obj);
myStudy = myStudyMgr->GetStudyByID(studyID);
+
+ CompMesh->SetCurrentStudy( myStudy.in() );
+
myStudyBuilder = myStudy->NewBuilder();
SALOMEDS::GenericAttribute_var anAttr;
SALOMEDS::AttributeName_var aName;
myStudyBuilder->DefineComponentInstance(father, CompMesh );
if (aLocked) myStudy->GetProperties()->SetLocked(true);
}
-
- mySComponentMesh=father;
+ mySComponentMesh = SALOMEDS::SComponent::_narrow( father );
// Tags definition
Tag_HypothesisRoot = 1;
const char* SMESH_Swig::AddNewMesh(const char* IOR)
{
MESSAGE("AddNewMesh");
+
+ // VSR: added temporarily - to be removed - objects are published automatically by engine
+ SALOMEDS::SObject_var SO = myStudy->FindObjectIOR( IOR );
+ if ( !SO->_is_nil() )
+ return SO->GetID();
+
//Find or Create Hypothesis root
SALOMEDS::GenericAttribute_var anAttr;
SALOMEDS::AttributeName_var aName;
SALOMEDS::AttributePixMap_var aPixmap;
SALOMEDS::SObject_var HypothesisRoot;
- ASSERT(!mySComponentMesh->_is_nil());
if (!mySComponentMesh->FindSubObject (Tag_HypothesisRoot, HypothesisRoot)) {
HypothesisRoot = myStudyBuilder->NewObjectToTag (mySComponentMesh, Tag_HypothesisRoot);
anAttr = myStudyBuilder->FindOrCreateAttribute(HypothesisRoot, "AttributeName");
const char* SMESH_Swig::AddNewHypothesis(const char* IOR)
{
MESSAGE("AddNewHypothesis");
+
+ // VSR: added temporarily - to be removed - objects are published automatically by engine
+ SALOMEDS::SObject_var SO = myStudy->FindObjectIOR( IOR );
+ if ( !SO->_is_nil() )
+ return SO->GetID();
+
//Find or Create Hypothesis root
SALOMEDS::SObject_var HypothesisRoot;
SALOMEDS::GenericAttribute_var anAttr;
const char* SMESH_Swig::AddNewAlgorithms(const char* IOR)
{
MESSAGE("AddNewAlgorithms");
+
+ // VSR: added temporarily - to be removed - objects are published automatically by engine
+ SALOMEDS::SObject_var SO = myStudy->FindObjectIOR( IOR );
+ if ( !SO->_is_nil() )
+ return SO->GetID();
+
//Find or Create Algorithms root
SALOMEDS::SObject_var AlgorithmsRoot;
SALOMEDS::GenericAttribute_var anAttr;
#include "SMESHGUI.h"
// QT Includes
-#include <qframe.h>
#include <qlabel.h>
#include <qpushbutton.h>
#include <qslider.h>
#include <qlayout.h>
-#include <qvariant.h>
-#include <qtooltip.h>
-#include <qwhatsthis.h>
-#include <qapplication.h>
#include <qgroupbox.h>
#include "VTKViewer_ViewFrame.h"
#include "VTKViewer_RenderWindowInteractor.h"
#include "QAD_RightFrame.h"
+#include "QAD_WaitCursor.h"
#include "SALOME_ListIteratorOfListIO.hxx"
+#include "SMESH_Actor.h"
+#include "SALOME_Selection.h"
+#include "SALOME_InteractiveObject.hxx"
+
+static SMESH_Actor* FindActorByEntry(const char* theEntry)
+{
+ QAD_Study* aStudy = SMESHGUI::GetSMESHGUI()->GetActiveStudy();
+ QAD_StudyFrame *aStudyFrame = aStudy->getActiveStudyFrame();
+ VTKViewer_ViewFrame* aViewFrame = dynamic_cast<VTKViewer_ViewFrame*>( aStudyFrame->getRightFrame()->getViewFrame() );
+
+ if(aViewFrame){
+ vtkRenderer *aRenderer = aViewFrame->getRenderer();
+ vtkActorCollection *aCollection = aRenderer->GetActors();
+ aCollection->InitTraversal();
+ while(vtkActor *anAct = aCollection->GetNextActor()){
+ if(SMESH_Actor *anActor = dynamic_cast<SMESH_Actor*>(anAct)){
+ if(anActor->hasIO()){
+ Handle(SALOME_InteractiveObject) anIO = anActor->getIO();
+ if(anIO->hasEntry() && strcmp(anIO->getEntry(),theEntry) == 0){
+ return anActor;
+ }
+ }
+ }
+ }
+ }
+ return NULL;
+}
//=================================================================================
// class : SMESHGUI_TransparencyDlg()
//=================================================================================
SMESHGUI_TransparencyDlg::SMESHGUI_TransparencyDlg( QWidget* parent,
const char* name,
- SALOME_Selection* Sel,
bool modal,
WFlags fl )
- : QDialog( parent, name, modal, WStyle_Customize | WStyle_NormalBorder | WStyle_Title | WStyle_SysMenu )
+ : QDialog( parent, name, modal, WStyle_Customize | WStyle_NormalBorder | WStyle_Title | WStyle_SysMenu | WDestructiveClose )
{
if ( !name )
setName( "SMESHGUI_TransparencyDlg" );
- resize( 152, 107 );
setCaption( tr( "SMESH_TRANSPARENCY_TITLE" ) );
setSizeGripEnabled( TRUE );
- SMESHGUI_TransparencyDlgLayout = new QGridLayout( this );
+ QGridLayout* SMESHGUI_TransparencyDlgLayout = new QGridLayout( this );
SMESHGUI_TransparencyDlgLayout->setSpacing( 6 );
SMESHGUI_TransparencyDlgLayout->setMargin( 11 );
- /*************************************************************************/
- QGroupBox* GroupButtons = new QGroupBox( this, "GroupButtons" );
- GroupButtons->setColumnLayout(0, Qt::Vertical );
- GroupButtons->layout()->setSpacing( 0 );
- GroupButtons->layout()->setMargin( 0 );
- QGridLayout* GroupButtonsLayout = new QGridLayout( GroupButtons->layout() );
- GroupButtonsLayout->setAlignment( Qt::AlignTop );
- GroupButtonsLayout->setSpacing( 6 );
- GroupButtonsLayout->setMargin( 11 );
-
- buttonOk = new QPushButton( GroupButtons, "buttonOk" );
- buttonOk->setText( tr( "GEOM_BUT_OK" ) );
- buttonOk->setAutoDefault( TRUE );
- buttonOk->setDefault( TRUE );
- GroupButtonsLayout->addItem( new QSpacerItem( 20, 20, QSizePolicy::Expanding, QSizePolicy::Minimum), 0, 0 );
- GroupButtonsLayout->addWidget( buttonOk, 0, 1 );
- GroupButtonsLayout->addItem( new QSpacerItem( 20, 20, QSizePolicy::Expanding, QSizePolicy::Minimum), 0, 2 );
-
/*************************************************************************/
QGroupBox* GroupC1 = new QGroupBox( this, "GroupC1" );
GroupC1->setColumnLayout(0, Qt::Vertical );
GroupC1Layout->setSpacing( 6 );
GroupC1Layout->setMargin( 11 );
- TextLabelOpaque = new QLabel( GroupC1, "TextLabelOpaque" );
- TextLabelOpaque->setText( tr( "SMESH_TRANSPARENCY_OPAQUE" ) );
- TextLabelOpaque->setAlignment( int( QLabel::AlignLeft ) );
- GroupC1Layout->addWidget( TextLabelOpaque, 0, 0 );
- GroupC1Layout->addItem( new QSpacerItem( 20, 20, QSizePolicy::Expanding, QSizePolicy::Minimum ), 0, 1 );
-
TextLabelTransparent = new QLabel( GroupC1, "TextLabelTransparent" );
TextLabelTransparent->setText( tr( "SMESH_TRANSPARENCY_TRANSPARENT" ) );
- TextLabelTransparent->setAlignment( int( QLabel::AlignRight ) );
- GroupC1Layout->addWidget( TextLabelTransparent, 0, 2 );
+ TextLabelTransparent->setAlignment( AlignLeft );
+ GroupC1Layout->addWidget( TextLabelTransparent, 0, 0 );
+
+ ValueLab = new QLabel( GroupC1, "ValueLab" );
+ ValueLab->setAlignment( AlignCenter );
+ ValueLab->setSizePolicy( QSizePolicy( QSizePolicy::Expanding, QSizePolicy::Fixed ) );
+ QFont fnt = ValueLab->font(); fnt.setBold( true ); ValueLab->setFont( fnt );
+ GroupC1Layout->addWidget( ValueLab, 0, 1 );
+
+ TextLabelOpaque = new QLabel( GroupC1, "TextLabelOpaque" );
+ TextLabelOpaque->setText( tr( "SMESH_TRANSPARENCY_OPAQUE" ) );
+ TextLabelOpaque->setAlignment( AlignRight );
+ GroupC1Layout->addWidget( TextLabelOpaque, 0, 2 );
Slider1 = new QSlider( 0, 10, 1, 5, Horizontal, GroupC1, "Slider1" );
+ Slider1->setFocusPolicy( QWidget::NoFocus );
Slider1->setMinimumSize( 300, 0 );
- Slider1->setTickmarks( QSlider::Left );
+ Slider1->setTickmarks( QSlider::Above );
+ Slider1->setTickInterval( 10 );
+ Slider1->setTracking( true );
+ Slider1->setMinValue( 0 ) ;
+ Slider1->setMaxValue( 100 );
+ Slider1->setLineStep( 1 );
+ Slider1->setPageStep( 10 );
GroupC1Layout->addMultiCellWidget( Slider1, 1, 1, 0, 2 );
+ /*************************************************************************/
+ QGroupBox* GroupButtons = new QGroupBox( this, "GroupButtons" );
+ GroupButtons->setColumnLayout(0, Qt::Vertical );
+ GroupButtons->layout()->setSpacing( 0 );
+ GroupButtons->layout()->setMargin( 0 );
+ QGridLayout* GroupButtonsLayout = new QGridLayout( GroupButtons->layout() );
+ GroupButtonsLayout->setAlignment( Qt::AlignTop );
+ GroupButtonsLayout->setSpacing( 6 );
+ GroupButtonsLayout->setMargin( 11 );
+
+ buttonOk = new QPushButton( GroupButtons, "buttonOk" );
+ buttonOk->setText( tr( "SMESH_BUT_CLOSE" ) );
+ buttonOk->setAutoDefault( TRUE );
+ buttonOk->setDefault( TRUE );
+ GroupButtonsLayout->addItem( new QSpacerItem( 20, 20, QSizePolicy::Expanding, QSizePolicy::Minimum), 0, 0 );
+ GroupButtonsLayout->addWidget( buttonOk, 0, 1 );
+ GroupButtonsLayout->addItem( new QSpacerItem( 20, 20, QSizePolicy::Expanding, QSizePolicy::Minimum), 0, 2 );
+
SMESHGUI_TransparencyDlgLayout->addWidget( GroupC1, 0, 0 );
SMESHGUI_TransparencyDlgLayout->addWidget( GroupButtons, 1, 0 );
- /* Initialisations */
- this->mySMESHGUI = SMESHGUI::GetSMESHGUI() ;
- this->mySel = Sel ;
-
- /* First call valueChanged() method for initialisation */
- /* The default value of transparency will change with the selection */
- this->myFirstInit = true ;
-// Slider1->setMaxValue( 10 );
-// Slider1->setValue( 5 ) ;
+ mySelection = SALOME_Selection::Selection( SMESHGUI::GetSMESHGUI()->GetActiveStudy()->getSelection());
-
- this->ValueHasChanged( Slider1->value() ) ;
+ // Initial state
+ this->onSelectionChanged() ;
// signals and slots connections : after ValueHasChanged()
connect( buttonOk, SIGNAL( clicked() ), this, SLOT( ClickOnOk() ) );
- connect( Slider1, SIGNAL( valueChanged(int) ), this, SLOT( ValueHasChanged(int) ) );
+ connect( Slider1, SIGNAL( valueChanged(int) ), this, SLOT( SetTransparency() ) );
+ connect( Slider1, SIGNAL( sliderMoved(int) ), this, SLOT( ValueHasChanged() ) );
+ connect( SMESHGUI::GetSMESHGUI(), SIGNAL ( SignalCloseAllDialogs() ), this, SLOT( ClickOnOk() ) ) ;
+ connect( mySelection, SIGNAL( currentSelectionChanged() ), this, SLOT( onSelectionChanged() ) );
/* Move widget on the botton right corner of main widget */
int x, y ;
- mySMESHGUI->DefineDlgPosition( this, x, y ) ;
+ SMESHGUI::GetSMESHGUI()->DefineDlgPosition( this, x, y ) ;
this->move( x, y ) ;
- this->show() ; /* Displays this Dialog */
+ this->show();
}
-
-
//=================================================================================
// function : ~SMESHGUI_TransparencyDlg()
// purpose :
//=================================================================================
SMESHGUI_TransparencyDlg::~SMESHGUI_TransparencyDlg()
{
- // no need to delete child widgets, Qt does it all for us
+ // no need to delete child widgets, Qt does it all for us
}
//=======================================================================
void SMESHGUI_TransparencyDlg::ClickOnOk()
{
- accept() ;
- return ;
+ close();
}
-//=======================================================================
-// function : ClickOnClose()
-// purpose :
-//=======================================================================
-void SMESHGUI_TransparencyDlg::ClickOnClose()
+//=================================================================================
+// function : SetTransparency()
+// purpose : Called when value of slider change
+// : or the first time as initilisation
+//=================================================================================
+void SMESHGUI_TransparencyDlg::SetTransparency()
{
- accept() ;
- return ;
+ if ( SMESHGUI::GetSMESHGUI()->GetActiveStudy()->getActiveStudyFrame()->getTypeView() == VIEW_VTK ) {
+ QAD_WaitCursor wc;
+ float opacity = this->Slider1->value() / 100. ;
+ SALOME_ListIteratorOfListIO It( mySelection->StoredIObjects() );
+ for( ;It.More(); It.Next() ) {
+ Handle(SALOME_InteractiveObject) IOS = It.Value();
+ SMESH_Actor* anActor = FindActorByEntry(IOS->getEntry());
+ if ( anActor )
+ anActor->SetOpacity( opacity );
+ }
+ SMESHGUI::GetSMESHGUI()->GetActiveStudy()->getActiveStudyFrame()->getRightFrame()->getViewFrame()->Repaint();
+ }
+ ValueHasChanged();
}
-
//=================================================================================
// function : ValueHasChanged()
-// purpose : Called when value of slider change
-// : or the first time as initilisation
+// purpose : Called when user moves a slider
//=================================================================================
-void SMESHGUI_TransparencyDlg::ValueHasChanged( int newValue )
+void SMESHGUI_TransparencyDlg::ValueHasChanged()
{
+ ValueLab->setText( QString::number( this->Slider1->value() ) + "%" );
+}
- if ( mySMESHGUI->GetActiveStudy()->getActiveStudyFrame()->getTypeView() == VIEW_VTK ) {
- VTKViewer_RenderWindowInteractor* myRenderInter= ((VTKViewer_ViewFrame*)mySMESHGUI->GetActiveStudy()->getActiveStudyFrame()->getRightFrame()->getViewFrame())->getRWInteractor();
- SALOME_ListIteratorOfListIO It( this->mySel->StoredIObjects() );
- Handle(SALOME_InteractiveObject) FirstIOS = mySel->firstIObject();
- if( !FirstIOS.IsNull() ) {
- /* The first time as initialisation */
- if( this->myFirstInit ) {
- this->myFirstInit = false ;
- float transp = ( myRenderInter->GetTransparency(FirstIOS))*10.0 ;
- this->Slider1->setValue( int(transp) ) ;
- return;
+//=================================================================================
+// function : onSelectionChanged()
+// purpose : Called when selection is changed
+//=================================================================================
+void SMESHGUI_TransparencyDlg::onSelectionChanged()
+{
+ if ( SMESHGUI::GetSMESHGUI()->GetActiveStudy()->getActiveStudyFrame()->getTypeView() == VIEW_VTK ) {
+ int opacity = 100;
+ if ( mySelection->IObjectCount() == 1 ) {
+ Handle(SALOME_InteractiveObject) FirstIOS = mySelection->firstIObject();
+ if( !FirstIOS.IsNull() ) {
+ SMESH_Actor* anActor = FindActorByEntry( FirstIOS->getEntry() );
+ if ( anActor )
+ opacity = int( anActor->GetOpacity() * 100. + 0.5 );
}
}
-
- QApplication::setOverrideCursor( Qt::waitCursor );
- for( ;It.More(); It.Next() ) {
- Handle(SALOME_InteractiveObject) IOS = It.Value();
- myRenderInter->SetTransparency( IOS, newValue/10.0 );
+ else if ( mySelection->IObjectCount() > 1 ) {
+ SALOME_ListIteratorOfListIO It( mySelection->StoredIObjects() );
+ int setOp = -1;
+ for ( ; It.More(); It.Next() ) {
+ Handle(SALOME_InteractiveObject) IO = It.Value();
+ if( !IO.IsNull() ) {
+ SMESH_Actor* anActor = FindActorByEntry( IO->getEntry() );
+ if ( anActor ) {
+ int op = int( anActor->GetOpacity() * 100. + 0.5 );
+ if ( setOp < 0 )
+ setOp = op;
+ else if ( setOp != op ) {
+ setOp = 100;
+ break;
+ }
+ }
+ }
+ }
+ if ( setOp >= 0 )
+ opacity = setOp;
}
- QApplication::restoreOverrideCursor();
+ Slider1->setValue( opacity ) ;
}
- QApplication::restoreOverrideCursor();
- return ;
+ ValueHasChanged();
}
#ifndef DIALOGBOX_TRANSPARENCYDLG_H
#define DIALOGBOX_TRANSPARENCYDLG_H
-#include "SALOME_Selection.h"
-#include "SALOME_InteractiveObject.hxx"
-
// QT Includes
-#include <qvariant.h>
#include <qdialog.h>
-class QVBoxLayout;
-class QHBoxLayout;
-class QGridLayout;
-class QFrame;
class QLabel;
class QPushButton;
class QSlider;
-class SMESHGUI;
+class SALOME_Selection;
//=================================================================================
// class : SMESHGUI_TransparencyDlg
public:
SMESHGUI_TransparencyDlg( QWidget* parent = 0,
- const char* name = 0,
- SALOME_Selection* Sel = 0,
- bool modal = TRUE,
- WFlags fl = 0 );
+ const char* name = 0,
+ bool modal = false,
+ WFlags fl = 0 );
~SMESHGUI_TransparencyDlg();
private :
- SMESHGUI* mySMESHGUI ; /* Current GeomGUI object */
- bool myFirstInit ; /* Inform for the first init */
- SALOME_Selection* mySel; /* User selection */
-
- QPushButton* buttonOk;
- QLabel* TextLabelOpaque;
- QLabel* TextLabelTransparent;
- QSlider* Slider1;
+ SALOME_Selection* mySelection;
+
+ QPushButton* buttonOk;
+ QLabel* TextLabelOpaque;
+ QLabel* ValueLab;
+ QLabel* TextLabelTransparent;
+ QSlider* Slider1;
public slots:
void ClickOnOk();
- void ClickOnClose();
- void ValueHasChanged( int newValue ) ;
-
-protected:
- QGridLayout* SMESHGUI_TransparencyDlgLayout;
- QHBoxLayout* Layout1;
- QHBoxLayout* Layout2;
+ void ValueHasChanged() ;
+ void SetTransparency();
+ void onSelectionChanged();
};
#endif // DIALOGBOX_TRANSPARENCYDLG_H
--- /dev/null
+// SMESH SMESHGUI : reading of xml file with list of available hypotheses and algorithms
+// Copyright (C) 2003 CEA
+//
+// This library 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.
+//
+
+// This library 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 this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+//
+// See http://www.salome-platform.org or email : webmaster.salome@opencascade.org
+//
+//
+//
+// File : SMESHGUI_XmlHandler.cxx
+// Author : Julia DOROVSKIKH
+// Module : SMESH
+// $Header$
+
+using namespace std;
+#define INCLUDE_MENUITEM_DEF
+
+#include "SMESHGUI_XmlHandler.h"
+
+// QT Include
+//#include <qaccel.h>
+#include <qfileinfo.h>
+
+/*!
+ Constructor
+*/
+SMESHGUI_XmlHandler::SMESHGUI_XmlHandler()
+{
+}
+
+/*!
+ Destructor
+*/
+SMESHGUI_XmlHandler::~SMESHGUI_XmlHandler()
+{
+}
+
+/*!
+ Starts parsing of document. Does some initialization
+
+ Reimplemented from QXmlDefaultHandler.
+*/
+bool SMESHGUI_XmlHandler::startDocument()
+{
+ myErrorProt = "";
+ return TRUE;
+}
+
+/*!
+ Does different actions depending on the name of the tag and the
+ state you are in document.
+
+ Reimplemented from QXmlDefaultHandler.
+*/
+bool SMESHGUI_XmlHandler::startElement (const QString&, const QString&,
+ const QString& qName,
+ const QXmlAttributes& atts)
+{
+ if (qName == "meshers")
+ {
+ myHypothesesMap.clear();
+ myAlgorithmsMap.clear();
+ }
+ else if (qName == "meshers-group") // group of hypotheses and algorithms
+ {
+// if (atts.value("server-lib") != "")
+ {
+ myPluginName = atts.value("name");
+ myServerLib = atts.value("server-lib");
+ myClientLib = atts.value("gui-lib");
+
+ QString aResName = atts.value("resources");
+ if (aResName != "")
+ {
+ MESSAGE("Loading Resources " << aResName);
+ QAD_ResourceMgr* resMgr = QAD_Desktop::createResourceManager();
+ QString msg;
+ if (!resMgr->loadResources(aResName, msg))
+ MESSAGE(msg);
+ }
+ }
+ }
+ else if (qName == "hypotheses") // group of hypotheses
+ {
+ }
+ else if (qName == "algorithms") // group of algorithms
+ {
+ }
+ else if (qName == "hypothesis" || qName == "algorithm") // hypothesis or algorithm
+ {
+ if (atts.value("type") != "")
+ {
+ QString aHypAlType = atts.value("type");
+ QString aLabel = atts.value("label-id");
+ QString anIcon = atts.value("icon-id");
+ HypothesisData* aHypLibNames =
+ new HypothesisData (myPluginName, myServerLib, myClientLib,
+ aLabel, anIcon);
+
+ if (qName == "algorithm")
+ {
+ myAlgorithmsMap[(char*)aHypAlType.latin1()] = aHypLibNames;
+ }
+ else
+ {
+ myHypothesesMap[(char*)aHypAlType.latin1()] = aHypLibNames;
+ }
+ }
+ }
+ else
+ {
+ // error
+ return FALSE;
+ }
+ return TRUE;
+}
+
+
+/*!
+ Reimplemented from QXmlDefaultHandler.
+*/
+bool SMESHGUI_XmlHandler::endElement (const QString&, const QString&, const QString&)
+{
+ return TRUE;
+}
+
+
+/*!
+ Reimplemented from QXmlDefaultHandler.
+*/
+bool SMESHGUI_XmlHandler::characters (const QString& ch)
+{
+ // we are not interested in whitespaces
+ QString ch_simplified = ch.simplifyWhiteSpace();
+ if ( ch_simplified.isEmpty() )
+ return TRUE;
+ return TRUE;
+}
+
+
+/*!
+ Returns the default error string.
+
+ Reimplemented from QXmlDefaultHandler.
+*/
+QString SMESHGUI_XmlHandler::errorString()
+{
+ return "the document is not in the quote file format";
+}
+
+/*!
+ Returns the error protocol if parsing failed
+
+ Reimplemented from QXmlDefaultHandler.
+*/
+QString SMESHGUI_XmlHandler::errorProtocol()
+{
+ return myErrorProt;
+}
+
+/*!
+ Returns exception
+
+ Reimplemented from QXmlDefaultHandler.
+*/
+bool SMESHGUI_XmlHandler::fatalError (const QXmlParseException& exception)
+{
+ myErrorProt += QString("fatal parsing error: %1 in line %2, column %3\n")
+ .arg(exception.message())
+ .arg(exception.lineNumber())
+ .arg(exception.columnNumber());
+
+ return QXmlDefaultHandler::fatalError( exception );
+}
--- /dev/null
+// SMESH SMESHGUI : reading of xml file with list of available hypotheses and algorithms
+//
+// Copyright (C) 2003 CEA
+//
+// This library 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.
+//
+// This library 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 this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+//
+// See http://www.salome-platform.org or email : webmaster.salome@opencascade.org
+//
+//
+//
+// File : SMESHGUI_XmlHandler.cxx
+// Author : Julia DOROVSKIKH
+// Module : SMESH
+// $Header$
+
+#include "SMESHGUI.h"
+
+#include <qxml.h>
+#include <map>
+
+class SMESHGUI_XmlHandler : public QXmlDefaultHandler
+{
+ public:
+ SMESHGUI_XmlHandler();
+ virtual ~SMESHGUI_XmlHandler();
+
+ bool startDocument();
+ bool startElement( const QString& namespaceURI, const QString& localName,
+ const QString& qName, const QXmlAttributes& atts );
+ bool endElement( const QString& namespaceURI, const QString& localName, const QString& qName );
+ bool characters( const QString& ch );
+
+ QString errorString();
+ QString errorProtocol();
+ bool fatalError (const QXmlParseException& exception);
+
+ public:
+ map<string, HypothesisData*> myHypothesesMap;
+ map<string, HypothesisData*> myAlgorithmsMap;
+
+ private:
+ QString myErrorProt;
+ QString myPluginName;
+ QString myServerLib;
+ QString myClientLib;
+};
# Hypothesis
#-----------------------------------------------------------
-#Hypo Local Length
-msgid "ICON_DLG_LOCAL_LENGTH"
-msgstr "mesh_hypo_length.png"
-
-#Hypo Nb Segments
-msgid "ICON_DLG_NB_SEGMENTS"
-msgstr "mesh_hypo_segment.png"
-
-#Hypo Max Area
-msgid "ICON_DLG_MAX_ELEMENT_AREA"
-msgstr "mesh_hypo_area.png"
-
-#Hypo Max Volume
-msgid "ICON_DLG_MAX_ELEMENT_VOLUME"
-msgstr "mesh_hypo_volume.png"
-
#Set Algo
msgid "ICON_DLG_ADD_ALGORITHM"
msgstr "mesh_set_algo.png"
#-----------------------------------------------------------
-# ObjectBrother
+# ObjectBrowser
#-----------------------------------------------------------
#mesh_tree_mesh
msgid "ICON_SMESH_TREE_MESH"
msgstr "mesh_tree_mesh.png"
+#mesh_tree_group
+msgid "ICON_SMESH_TREE_GROUP"
+msgstr "mesh_tree_group.png"
+
#mesh_tree_algo
msgid "ICON_SMESH_TREE_ALGO"
msgstr "mesh_tree_algo.png"
-#mesh_tree_algo_regular
-msgid "ICON_SMESH_TREE_ALGO_Regular_1D"
-msgstr "mesh_tree_algo_regular.png"
-
-#mesh_tree_algo_hexa
-msgid "ICON_SMESH_TREE_ALGO_Hexa_3D"
-msgstr "mesh_tree_algo_hexa.png"
-
-#mesh_tree_algo_mefisto
-msgid "ICON_SMESH_TREE_ALGO_MEFISTO_2D"
-msgstr "mesh_tree_algo_mefisto.png"
-
-#mesh_tree_algo_quad
-msgid "ICON_SMESH_TREE_ALGO_Quadrangle_2D"
-msgstr "mesh_tree_algo_quad.png"
-
#mesh_tree_hypo
msgid "ICON_SMESH_TREE_HYPO"
msgstr "mesh_tree_hypo.png"
-#mesh_tree_hypo_area
-msgid "ICON_SMESH_TREE_HYPO_MaxElementArea"
-msgstr "mesh_tree_hypo_area.png"
+#mesh_tree_mesh_warn
+msgid "ICON_SMESH_TREE_MESH_WARN"
+msgstr "mesh_tree_mesh_warn.png"
-#mesh_tree_hypo_length
-msgid "ICON_SMESH_TREE_HYPO_LocalLength"
-msgstr "mesh_tree_hypo_length.png"
+#mesh_tree_mesh
+msgid "ICON_SMESH_TREE_MESH_IMPORTED"
+msgstr "mesh_tree_importedmesh.png"
-#mesh_tree_hypo_segment
-msgid "ICON_SMESH_TREE_HYPO_NumberOfSegments"
-msgstr "mesh_tree_hypo_segment.png"
-#mesh_tree_hypo_volume
-msgid "ICON_SMESH_TREE_HYPO_MaxElementVolume"
-msgstr "mesh_tree_hypo_volume.png"
+#-----------------------------------------------------------
+# Group
+#-----------------------------------------------------------
-#mesh_tree_mesh_warn
-msgid "ICON_SMESH_TREE_MESH_WARN"
-msgstr "mesh_tree_mesh_warn.png"
+msgid "ICON_EDIT_GROUP"
+msgstr "mesh_edit_group.png"
+
+msgid "ICON_CONSTRUCT_GROUP"
+msgstr "mesh_make_group.png"
msgid "SMESH_BUT_CANCEL"
msgstr "&Cancel"
+#Add
+msgid "SMESH_BUT_ADD"
+msgstr "A&dd"
+
+#Remove
+msgid "SMESH_BUT_REMOVE"
+msgstr "&Remove"
+
+#Set Filters
+msgid "SMESH_BUT_FILTER"
+msgstr "Set &Filters"
+
+#Sort
+msgid "SMESH_BUT_SORT"
+msgstr "&Sort List"
+
+#Create
+msgid "SMESH_BUT_CREATE"
+msgstr "Create"
#-------------------------------------------------------------------------
# WARNING
#-------------------------------------------------------------------------
+#Error
+msgid "SMESH_ERROR"
+msgstr "Error"
+
#Warning
msgid "SMESH_WRN_WARNING"
msgstr "Warning"
msgid "SMESH_WRN_SELECTIONMODE_DIAGONAL"
msgstr "Activate Link Selection Mode"
+#Empty name
+msgid "SMESH_WRN_EMPTY_NAME"
+msgstr "Empty name is not valid"
#-------------------------------------------------------------------------
# MEN
#Applied Algorithm
msgid "SMESH_MEN_APPLIED_ALGORIHTMS"
-msgstr "Applied Algorithm"
+msgstr "Applied Algorithms"
#Applied Hypothesis
msgid "SMESH_MEN_APPLIED_HYPOTHESIS"
-msgstr "Applied Hypothesis"
+msgstr "Applied Hypotheses"
#Hypothesis Definition
msgid "SMESH_MEN_HYPOTHESIS"
-msgstr "Hypothesis Definition"
+msgstr "Hypotheses"
#Algorithms Definition
msgid "SMESH_MEN_ALGORITHMS"
-msgstr "Algorithms Definition"
+msgstr "Algorithms"
#-------------------------------------------------------------------------
# -------------- Hypothesis / Algorithm --------------
+#Meshers file
+msgid "MESHERS_FILE_NO_VARIABLE"
+msgstr "Environment variable SMESH_MeshersList is not defined"
+
+#Meshers file
+msgid "MESHERS_FILE_CANT_OPEN"
+msgstr "Can not open resource file"
+
+#Meshers file
+msgid "MESHERS_FILE_CHECK_VARIABLE"
+msgstr "Check environment variable SMESH_MeshersList"
+
#Hypothesis
msgid "SMESH_ADD_HYPOTHESIS"
msgstr "Hypothesis"
msgid "SMESH_OBJECT_HYPOTHESIS"
msgstr "Hypothesis"
-#Local Length
-msgid "SMESH_LOCAL_LENGTH_HYPOTHESIS"
-msgstr "Local Length"
-
-#Hypothesis Construction
-msgid "SMESH_LOCAL_LENGTH_TITLE"
-msgstr "Hypothesis Construction"
-
#Algorithms
msgid "SMESH_ADD_ALGORITHM"
msgstr "Algorithms"
msgid "SMESH_OBJECT_ALGORITHM"
msgstr "Algorithm"
-#Number of Segments
-msgid "SMESH_NB_SEGMENTS_HYPOTHESIS"
-msgstr "Number of Segments"
-
-#Hypothesis Construction
-msgid "SMESH_NB_SEGMENTS_TITLE"
-msgstr "Hypothesis Construction"
-
-#Max. Area
-msgid "SMESH_MAX_ELEMENT_AREA"
-msgstr "Max. Area"
-
-#Max. Element Area
-msgid "SMESH_MAX_ELEMENT_AREA_HYPOTHESIS"
-msgstr "Max. Element Area"
-
-#Hypothesis Construction
-msgid "SMESH_MAX_ELEMENT_AREA_TITLE"
-msgstr "Hypothesis Construction"
-
-#Max. Volume
-msgid "SMESH_MAX_ELEMENT_VOLUME"
-msgstr "Max. Volume"
-
-#Max. Element Volume
-msgid "SMESH_MAX_ELEMENT_VOLUME_HYPOTHESIS"
-msgstr "Max. Element Volume"
-
-#Hypothesis Construction
-msgid "SMESH_MAX_ELEMENT_VOLUME_TITLE"
-msgstr "Hypothesis Construction"
-
# -------------- Nodes / Segments / Elements --------------
#Opacity
msgid "SMESH_TRANSPARENCY_OPAQUE"
-msgstr "Opacity"
+msgstr "---> Opaque"
#Transparency
msgid "SMESH_TRANSPARENCY_TITLE"
-msgstr "Transparency"
+msgstr "Change Transparency"
#Fully Transparency
msgid "SMESH_TRANSPARENCY_TRANSPARENT"
-msgstr "Fully Transparency"
+msgstr "Transparent <---"
# -------------- Preferences -----------
+#Scalar Bar Preferences
+msgid "SMESH_PROPERTIES_SCALARBAR"
+msgstr "Scalar Bar Properties"
+
+#Scalar Bar Properties
+msgid "SMESH_PREFERENCES_SCALARBAR"
+msgstr "Scalar Bar Preferences"
+
+#Scalar Bar Range
+msgid "SMESH_RANGE_SCALARBAR"
+msgstr "Scalar Range"
+
+#Scalar Bar Range Min Value
+msgid "SMESH_RANGE_MIN"
+msgstr "Min value:"
+
+#Scalar Bar Range Max Value
+msgid "SMESH_RANGE_MAX"
+msgstr "Max value:"
+
+#Scalar Bar Font
+msgid "SMESH_FONT_SCALARBAR"
+msgstr "Font"
+
#Arial
msgid "SMESH_FONT_ARIAL"
msgstr "Arial"
-#Bold
-msgid "SMESH_FONT_BOLD"
-msgstr "Bold"
-
#Courier
msgid "SMESH_FONT_COURIER"
msgstr "Courier"
-#Dimensions
-msgid "SMESH_DIMENSIONS"
-msgstr "Dimensions"
-
-#Font
-msgid "SMESH_FONT"
-msgstr "Font"
-
-#Height
-msgid "SMESH_HEIGHT"
-msgstr "Height"
+#Times
+msgid "SMESH_FONT_TIMES"
+msgstr "Times"
-#Horizontal
-msgid "SMESH_HORIZONTAL"
-msgstr "Horizontal"
+#Bold
+msgid "SMESH_FONT_BOLD"
+msgstr "Bold"
#Italic
msgid "SMESH_FONT_ITALIC"
msgstr "Italic"
-#Scalar Bar Preferences
-msgid "SMESH_PREFERENCES_SCALARBAR"
-msgstr "Scalar Bar Preferences"
+#Shadow
+msgid "SMESH_FONT_SHADOW"
+msgstr "Shadow"
+
+#Title
+msgid "SMESH_TITLE"
+msgstr "Title:"
+
+#Labels
+msgid "SMESH_LABELS"
+msgstr "Labels:"
+
+#Colors & Labels
+msgid "SMESH_LABELS_COLORS_SCALARBAR"
+msgstr "Colors && Labels"
#Number Of Colors
msgid "SMESH_NUMBEROFCOLORS"
-msgstr "Number Of Colors"
+msgstr "Nb of colors:"
#Number Of Labels
msgid "SMESH_NUMBEROFLABELS"
-msgstr "Number Of Labels"
+msgstr "Nb of labels:"
#Orientation
msgid "SMESH_ORIENTATION"
msgstr "Orientation"
-#Properties
-msgid "SMESH_PROPERTIES"
-msgstr "Properties"
-
-#Shadow
-msgid "SMESH_FONT_SHADOW"
-msgstr "Shadow"
-
-#Times
-msgid "SMESH_FONT_TIMES"
-msgstr "Times"
-
#Vertical
msgid "SMESH_VERTICAL"
msgstr "Vertical"
+#Horizontal
+msgid "SMESH_HORIZONTAL"
+msgstr "Horizontal"
+
+#Position & Size
+msgid "SMESH_POSITION_SIZE_SCALARBAR"
+msgstr "Origin && Size"
+
+#X
+msgid "SMESH_X_SCALARBAR"
+msgstr "X:"
+
+#Y
+msgid "SMESH_Y_SCALARBAR"
+msgstr "Y:"
+
#Width
msgid "SMESH_WIDTH"
-msgstr "Width"
+msgstr "Width:"
+#Height
+msgid "SMESH_HEIGHT"
+msgstr "Height:"
# -------------- ScalarBar --------------
#ScalarBar
msgid "SMESH_SCALARBAR"
-msgstr "ScalarBar"
+msgstr "Scalar Bar"
#Update View
msgid "SMESH_UPDATEVIEW"
msgid "SMESH_NONMANIFOLDEDGES"
msgstr "Non Manifold Edges"
-#Edges Connectivity
-msgid "SMESH_EDGES_CONNECTIVITY"
-msgstr "Edges Connectivity"
-
#Edges Connectivity
msgid "SMESH_EDGES_CONNECTIVITY_TITLE"
msgstr "Edges Connectivity"
msgid "SMESH_MESHINFO_TITLE"
msgstr "Mesh Infos"
-#Number Of 1D Elements
-msgid "SMESH_MESHINFO_NB1D"
-msgstr "Number Of 1D Elements"
-
-#Number Of 2D Elements
-msgid "SMESH_MESHINFO_NB2D"
-msgstr "Number Of 2D Elements"
+#Mesh Infos
+msgid "SMESH_MESHINFO_NAME"
+msgstr "Name"
-#Number Of 3D Elements
-msgid "SMESH_MESHINFO_NB3D"
-msgstr "Number Of 3D Elements"
+#Faces :
+msgid "SMESH_MESHINFO_ELEMENTS"
+msgstr "Elements"
#Edges :
msgid "SMESH_MESHINFO_EDGES"
-msgstr "Edges :"
+msgstr "Edges"
#Nodes :
msgid "SMESH_MESHINFO_NODES"
-msgstr "Nodes :"
+msgstr "Nodes"
+
+#Faces :
+msgid "SMESH_MESHINFO_FACES"
+msgstr "Faces"
+
+#Total :
+msgid "SMESH_MESHINFO_TOTAL"
+msgstr "Total"
#Triangles :
msgid "SMESH_MESHINFO_TRIANGLES"
-msgstr "Triangles :"
+msgstr "Triangles"
#Quadrangles :
msgid "SMESH_MESHINFO_QUADRANGLES"
-msgstr "Quadrangles :"
+msgstr "Quadrangles"
+
+#Volumes :
+msgid "SMESH_MESHINFO_VOLUMES"
+msgstr "Volumes"
#Tetrahedrons :
msgid "SMESH_MESHINFO_TETRAS"
-msgstr "Tetrahedrons :"
+msgstr "Tetrahedrons"
#Hexahedrons :
msgid "SMESH_MESHINFO_HEXAS"
-msgstr "Hexahedrons :"
+msgstr "Hexahedrons"
+#Pyramids :
+msgid "SMESH_MESHINFO_PYRAS"
+msgstr "Pyramids"
-# -------------- Controls --------------
+#Prisms :
+msgid "SMESH_MESHINFO_PRISMS"
+msgstr "Prisms"
-#Length
-msgid "SMESH_CONTROL_LENGTH_EDGES"
-msgstr "Length"
+#Type :
+msgid "SMESH_MESHINFO_TYPE"
+msgstr "Type"
-#Area
-msgid "SMESH_CONTROL_AREA_ELEMENTS"
-msgstr "Area"
+#Entities :
+msgid "SMESH_MESHINFO_ENTITIES"
+msgstr "Entities"
-#Taper
-msgid "SMESH_CONTROL_TAPER_ELEMENTS"
-msgstr "Taper"
+#All types :
+msgid "SMESH_MESHINFO_ALL_TYPES"
+msgstr "Heterogenous"
-#Aspect Ratio
-msgid "SMESH_CONTROL_ASPECTRATIO_ELEMENTS"
-msgstr "Aspect Ratio"
+#No valid selection :
+msgid "SMESH_BAD_SELECTION"
+msgstr "No valid selection"
-#Minimum Angle
-msgid "SMESH_CONTROL_MINIMUMANGLE_ELEMENTS"
-msgstr "Minimum Angle"
+# --------- Create hypotheses/algorithms ---------
-#Warp
-msgid "SMESH_CONTROL_WARP_ELEMENTS"
-msgstr "Warp"
+msgid "SMESH_CREATE_HYPOTHESES"
+msgstr "Create hypotheses"
-#Skew
-msgid "SMESH_CONTROL_SKEW_ELEMENTS"
-msgstr "Skew"
+msgid "SMESH_CREATE_ALGORITHMS"
+msgstr "Create algorithms"
+
+msgid "SMESH_AVAILABLE_ALGORITHMS"
+msgstr "Available algorithms"
+
+msgid "SMESH_AVAILABLE_HYPOTHESES"
+msgstr "Available hypotheses"
# -------------- Edit --------------
msgid "SMESH_EDIT_USED"
msgstr "Used"
+# -------------- Group --------------
+
+#Create Group
+msgid "SMESH_CREATE_GROUP_TITLE"
+msgstr "Create Group"
+
+#Edit Group
+msgid "SMESH_EDIT_GROUP_TITLE"
+msgstr "Edit Group"
+
+#Elements Type
+msgid "SMESH_ELEMENTS_TYPE"
+msgstr "Elements Type"
+
+#Face
+msgid "SMESH_FACE"
+msgstr "Face"
+
+#Volume
+msgid "SMESH_VOLUME"
+msgstr "Volume"
+
+#Content
+msgid "SMESH_CONTENT"
+msgstr "Content"
+
+#Select rom
+msgid "SMESH_SELECT_FROM"
+msgstr "Select From"
+
+#Group
+msgid "SMESH_GROUP"
+msgstr "Group"
+
+#%1 SubMeshes
+msgid "SMESH_SUBMESH_SELECTED"
+msgstr "%1 SubMeshes"
+
+#%1 Groups
+msgid "SMESH_GROUP_SELECTED"
+msgstr "%1 Groups"
+
+
+# -------------- Preferences - Selection --------------
+msgid "SMESH_PREF_SELECTION"
+msgstr "Preferences - Selection"
+
+msgid "SMESH_SELECTION"
+msgstr "Selection"
+
+msgid "SMESH_PRESELECTION"
+msgstr "Preselection"
+
+msgid "SMESH_HILIGHT_COLOR"
+msgstr "Highlight Color"
+
+msgid "SMESH_ELEMENTS_COLOR"
+msgstr "Mesh Element Color"
+
+msgid "SMESH_PRECISION"
+msgstr "Precision"
+
+msgid "SMESH_OUTLINE_COLOR"
+msgstr "Mesh Object Color"
+
+
+# -------------- SMESHGUI_FilterDlg --------------
+msgid "SMESHGUI_FilterDlg::FACES_TLT"
+msgstr "Filter for Faces"
+
+msgid "SMESHGUI_FilterDlg::EDGES_TLT"
+msgstr "Filter for Edges"
+
+msgid "SMESHGUI_FilterDlg::ADD"
+msgstr "Add"
+
+msgid "SMESHGUI_FilterDlg::REMOVE"
+msgstr "Remove"
+
+msgid "SMESHGUI_FilterDlg::CRITERION"
+msgstr "Criterion"
+
+msgid "SMESHGUI_FilterDlg::COMPARE"
+msgstr "Compare"
+
+msgid "SMESHGUI_FilterDlg::THRESHOLD_VALUE"
+msgstr "Threshold value"
+
+msgid "SMESHGUI_FilterDlg::UNARY"
+msgstr "Unary"
+
+msgid "SMESHGUI_FilterDlg::BINARY"
+msgstr "Binary"
+
+msgid "SMESHGUI_FilterDlg::FREE_BORDERS"
+msgstr "Free borders"
+
+msgid "SMESHGUI_FilterDlg::MULTI_BORDERS"
+msgstr "Borders at multi-connections"
+
+msgid "SMESHGUI_FilterDlg::LENGTH"
+msgstr "Length"
+
+msgid "SMESHGUI_FilterDlg::ASPECT_RATIO"
+msgstr "Aspect ratio"
+
+msgid "SMESHGUI_FilterDlg::WARPING"
+msgstr "Warping"
+
+msgid "SMESHGUI_FilterDlg::MINIMUM_ANGLE"
+msgstr "Minimum angle"
+
+msgid "SMESHGUI_FilterDlg::TAPER"
+msgstr "Taper"
+
+msgid "SMESHGUI_FilterDlg::SKEW"
+msgstr "Skew"
+
+msgid "SMESHGUI_FilterDlg::AREA"
+msgstr "Area"
+
+msgid "SMESHGUI_FilterDlg::LESS_THAN"
+msgstr "Less than"
+
+msgid "SMESHGUI_FilterDlg::MORE_THAN"
+msgstr "More than"
+
+msgid "SMESHGUI_FilterDlg::EQUAL_TO"
+msgstr "Equal to"
+
+msgid "SMESHGUI_FilterDlg::NOT"
+msgstr "Not"
+
+msgid "SMESHGUI_FilterDlg::AND"
+msgstr "And"
+
+msgid "SMESHGUI_FilterDlg::OR"
+msgstr "Or"
+
+msgid "SMESHGUI_FilterDlg::ERROR"
+msgstr "Threshold value is not correctly specified\nPlease enter correct value and try again"
+
+msgid "SMESHGUI_FilterDlg::MULTIEDGES_ERROR"
+msgstr "Threshold value of borders at multi-connections can not be equal 1\nPlease enter correct value and try again"
+
+msgid "SMESHGUI_FilterDlg::SOURCE"
+msgstr "Source"
+
+msgid "SMESHGUI_FilterDlg::MESH"
+msgstr "Mesh"
+
+msgid "SMESHGUI_FilterDlg::SELECTION"
+msgstr "Current Selection"
+
+msgid "SMESHGUI_FilterDlg::CURRENT_GROUP"
+msgstr "Current Group"
+
+msgid "SMESHGUI_FilterDlg::NONE"
+msgstr "None"
+
+msgid "SMESHGUI_FilterDlg::SET_IN_VIEWER"
+msgstr "Insert filter in viewer"
+
+msgid "SMESHGUI_FilterDlg::CLEAR"
+msgstr "Clear"
+
+# -------------- SMESHGUI --------------
+msgid "SMESHGUI::MESH_IS_NOT_SELECTED"
+msgstr "There is no selected mesh\nPlease, select a mesh and try again"
+
+msgid "SMESHGUI::NOT_A_VTK_VIEWER"
+msgstr "This command is available in VTK viewer only\nPlease, create VTK viewer and try again"
+
+msgid "SMESHGUI::LENGTH_EDGES"
+msgstr "Length"
+
+msgid "SMESHGUI::FREE_BORDERS"
+msgstr "Free borders"
+
+msgid "SMESHGUI::MULTI_BORDERS"
+msgstr "Borders at multi-connections"
+
+msgid "SMESHGUI::AREA_ELEMENTS"
+msgstr "Area"
+
+msgid "SMESHGUI::TAPER_ELEMENTS"
+msgstr "Taper"
+
+msgid "SMESHGUI::ASPECTRATIO_ELEMENTS"
+msgstr "Aspect Ratio"
+
+msgid "SMESHGUI::MINIMUMANGLE_ELEMENTS"
+msgstr "Minimum Angle"
+
+msgid "SMESHGUI::WARP_ELEMENTS"
+msgstr "Warp"
+
+msgid "SMESHGUI::SKEW_ELEMENTS"
+msgstr "Skew"
+
+msgid "SMESH_INSUFFICIENT_DATA"
+msgstr "Insufficient input value"
+
+msgid "SMESH_HYP_1"
+msgstr "Algorithm misses a hypothesis"
+
+msgid "SMESH_HYP_2"
+msgstr "Concurrent hypotheses on a shape"
+
+msgid "SMESH_HYP_3"
+msgstr "Hypothesis has a bad parameter value"
+
+msgid "SMESH_HYP_4"
+msgstr "Unknown fatal error while assigning hypothesis"
+
+msgid "SMESH_HYP_5"
+msgstr "Hypothesis is not suitable in the current context"
+
+msgid "SMESH_HYP_6"
+msgstr "Non-conform mesh is produced using applied hypotheses"
+
+msgid "SMESH_HYP_7"
+msgstr "Such hypothesis is already assigned to the shape"
+
+msgid "SMESH_HYP_8"
+msgstr "Hypothesis and submesh dimensions mismatch"
+
+msgid "SMESH_DRS_1"
+msgstr "MED file contains no mesh with the given name"
+
+msgid "SMESH_DRS_2"
+msgstr ""
+"MED file has overlapped ranges of element numbers,\n"
+" the numbers from the file are ignored"
+
+msgid "SMESH_DRS_3"
+msgstr "Some elements were skipped due to incorrect file data"
+
+msgid "SMESH_DRS_4"
+msgstr " The file is incorrect,\n"
+ "some information will be missed"
+
+msgid "INF_SELECT_OBJECT"
+msgstr "Select an object"
\ No newline at end of file
top_srcdir=@top_srcdir@
top_builddir=../..
srcdir=@srcdir@
-VPATH=.:@srcdir@:@top_srcdir@/idl:$(top_builddir)/idl:${KERNEL_ROOT_DIR}/idl/salome:${MED_ROOT_DIR}/idl/salome
+VPATH=.:@srcdir@:@top_srcdir@/idl:$(top_builddir)/idl:
@COMMENCE@
+# header files
+EXPORT_HEADERS= \
+ SMESH_Gen_i.hxx \
+ SMESH_Algo_i.hxx \
+ SMESH_1D_Algo_i.hxx \
+ SMESH_2D_Algo_i.hxx \
+ SMESH_3D_Algo_i.hxx \
+ SMESH_subMesh_i.hxx \
+ SMESH_topo.hxx \
+ SMESH_Mesh_i.hxx \
+ SMESH_Hypothesis_i.hxx
+
EXPORT_PYSCRIPTS = smeshpy.py SMESH_test.py
# Libraries targets
LIB= libSMESHEngine.la
-LIB_SRC = SMESH_Gen_i.cxx SMESH_Mesh_i.cxx SMESH_MEDMesh_i.cxx \
- SMESH_MEDFamily_i.cxx SMESH_MEDSupport_i.cxx \
- SMESH_subMesh_i.cxx \
- SMESH_MeshEditor_i.cxx \
- SMESH_Hypothesis_i.cxx \
- SMESH_topo.cxx SMESH_HypothesisFactory_i.cxx \
- SMESH_Algo_i.cxx \
- SMESH_1D_Algo_i.cxx \
- SMESH_2D_Algo_i.cxx \
- SMESH_3D_Algo_i.cxx \
- SMESH_NumberOfSegments_i.cxx \
- SMESH_LocalLength_i.cxx \
- SMESH_MaxElementArea_i.cxx \
- SMESH_LengthFromEdges_i.cxx \
- SMESH_MaxElementVolume_i.cxx \
- SMESH_Regular_1D_i.cxx \
- SMESH_Quadrangle_2D_i.cxx \
- SMESH_MEFISTO_2D_i.cxx \
- SMESH_Hexa_3D_i.cxx
+LIB_SRC = \
+ SMESH_Gen_i.cxx \
+ SMESH_Mesh_i.cxx \
+ SMESH_MEDMesh_i.cxx \
+ SMESH_MEDFamily_i.cxx \
+ SMESH_MEDSupport_i.cxx \
+ SMESH_subMesh_i.cxx \
+ SMESH_MeshEditor_i.cxx \
+ SMESH_Hypothesis_i.cxx \
+ SMESH_topo.cxx \
+ SMESH_Algo_i.cxx \
+ SMESH_1D_Algo_i.cxx \
+ SMESH_2D_Algo_i.cxx \
+ SMESH_3D_Algo_i.cxx \
+ SMESH_Filter_i.cxx \
+ SMESH_Group_i.cxx
LIB_SERVER_IDL = SMESH_Gen.idl SMESH_Hypothesis.idl SMESH_Mesh.idl \
SALOME_Component.idl SALOME_Exception.idl \
- SMESH_BasicHypothesis.idl
+ SMESH_Filter.idl SMESH_Group.idl
-LIB_CLIENT_IDL = SALOMEDS.idl GEOM_Gen.idl GEOM_Shape.idl MED.idl SALOMEDS_Attributes.idl
+LIB_CLIENT_IDL = SALOMEDS.idl GEOM_Gen.idl GEOM_Shape.idl MED.idl SALOMEDS_Attributes.idl SALOME_GenericObj.idl
# Executables targets
BIN =
BIN_SRC =
# additionnal information to compil and link file
-CPPFLAGS+= $(OCC_INCLUDES) $(MED2_INCLUDES) $(HDF5_INCLUDES) -I${KERNEL_ROOT_DIR}/include/salome -I${GEOM_ROOT_DIR}/include/salome
-CXXFLAGS+= $(OCC_CXXFLAGS) $(MED2_INCLUDES) $(HDF5_INCLUDES) -I${KERNEL_ROOT_DIR}/include/salome -I${GEOM_ROOT_DIR}/include/salome
+CPPFLAGS+= $(OCC_INCLUDES) $(MED2_INCLUDES) $(HDF5_INCLUDES) -I${KERNEL_ROOT_DIR}/include/salome \
+ -I${GEOM_ROOT_DIR}/include/salome $(BOOST_CPPFLAGS)
+CXXFLAGS+= $(OCC_CXXFLAGS) $(MED2_INCLUDES) $(HDF5_INCLUDES) -I${KERNEL_ROOT_DIR}/include/salome \
+ -I${GEOM_ROOT_DIR}/include/salome
#IDLCXXFLAGS+= -Wbtp
-LDFLAGS+= $(HDF5_LIBS) $(MED2_LIBS) -lSMESHimpl -lSalomeContainer -lSalomeNS -lSalomeDS -lRegistry -lSalomeHDFPersist -lOpUtil -lGEOMClient -lSMESHDS -lSMDS -lMEFISTO2D -lMeshDriverMED -lSalomeLifeCycleCORBA -L${KERNEL_ROOT_DIR}/lib/salome -L${GEOM_ROOT_DIR}/lib/salome
-
-ifeq (@WITHNETGEN@,yes)
- LIB_SRC += SMESH_NETGEN_3D_i.cxx
- LDFLAGS += -lNETGEN
-endif
+LDFLAGS+= $(HDF5_LIBS) $(MED2_LIBS) -lSMESHimpl -lSalomeContainer -lSalomeNS -lSalomeDS -lRegistry -lSalomeHDFPersist -lOpUtil -lGEOMClient -lSMESHDS -lSMDS -lMeshDriverMED -lSalomeLifeCycleCORBA -L${KERNEL_ROOT_DIR}/lib/salome -L${GEOM_ROOT_DIR}/lib/salome -lSalomeGenericObj
@CONCLUDE@
-
--- /dev/null
+// Copyright (C) 2003 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
+// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
+//
+// This library 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.
+//
+// This library 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 this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+//
+// See http://www.opencascade.org/SALOME/ or email : webmaster.salome@opencascade.org
+
+int main(int argc, char** argv)
+{
+ return 1;
+}
// Module : SMESH
// $Header$
-using namespace std;
using namespace std;
#include "SMESH_1D_Algo_i.hxx"
-#include "SMESH_Gen.hxx"
-#include "SMESH_HypothesisFactory.hxx"
-#include "Utils_CorbaException.hxx"
#include "utilities.h"
//=============================================================================
/*!
- *
+ * SMESH_1D_Algo_i::SMESH_1D_Algo_i
+ *
+ * Constructor
*/
//=============================================================================
-SMESH_1D_Algo_i::SMESH_1D_Algo_i()
+SMESH_1D_Algo_i::SMESH_1D_Algo_i( PortableServer::POA_ptr thePOA )
+ : SALOME::GenericObj_i( thePOA ),
+ SMESH_Hypothesis_i( thePOA ),
+ SMESH_Algo_i( thePOA )
{
- MESSAGE("SMESH_1D_Algo_i::SMESH_1D_Algo_i");
+ MESSAGE( "SMESH_1D_Algo_i::SMESH_1D_Algo_i" );
}
//=============================================================================
/*!
- *
+ * SMESH_1D_Algo_i::~SMESH_1D_Algo_i
+ *
+ * Destructor
*/
//=============================================================================
SMESH_1D_Algo_i::~SMESH_1D_Algo_i()
{
- MESSAGE("SMESH_1D_Algo_i::~SMESH_1D_Algo_i");
-}
-
-//=============================================================================
-/*!
- *
- */
-//=============================================================================
-
-void SMESH_1D_Algo_i::SetImpl(::SMESH_1D_Algo* impl)
-{
- MESSAGE("SMESH_1D_Algo_i::SetImpl");
- SMESH_Algo_i::SetImpl(impl);
- _impl = impl;
+ MESSAGE( "SMESH_1D_Algo_i::~SMESH_1D_Algo_i" );
}
#include "SMESH_Algo_i.hxx"
-#include "SMESH_1D_Algo.hxx"
-
+// ======================================================
+// Generic 1D algorithm
+// ======================================================
class SMESH_1D_Algo_i:
- public POA_SMESH::SMESH_1D_Algo,
- public SMESH_Algo_i
+ public virtual POA_SMESH::SMESH_1D_Algo,
+ public virtual SMESH_Algo_i
{
-public:
- SMESH_1D_Algo_i();
-
- virtual ~SMESH_1D_Algo_i();
-
protected:
- virtual void SetImpl(::SMESH_1D_Algo* impl);
+ // Constructor : placed in protected section to prohibit creation of generic class instance
+ SMESH_1D_Algo_i( PortableServer::POA_ptr thePOA );
- ::SMESH_1D_Algo* _impl;
+public:
+ // Destructor
+ virtual ~SMESH_1D_Algo_i();
};
#endif
// Module : SMESH
// $Header$
-using namespace std;
using namespace std;
#include "SMESH_2D_Algo_i.hxx"
-#include "SMESH_Gen.hxx"
-#include "SMESH_HypothesisFactory.hxx"
-#include "Utils_CorbaException.hxx"
#include "utilities.h"
//=============================================================================
/*!
- *
+ * SMESH_2D_Algo_i::SMESH_2D_Algo_i
+ *
+ * Constructor
*/
//=============================================================================
-SMESH_2D_Algo_i::SMESH_2D_Algo_i()
+SMESH_2D_Algo_i::SMESH_2D_Algo_i( PortableServer::POA_ptr thePOA )
+ : SALOME::GenericObj_i( thePOA ),
+ SMESH_Hypothesis_i( thePOA ),
+ SMESH_Algo_i( thePOA )
{
- MESSAGE("SMESH_2D_Algo_i::SMESH_2D_Algo_i");
+ MESSAGE( "SMESH_2D_Algo_i::SMESH_2D_Algo_i" );
}
//=============================================================================
/*!
- *
+ * SMESH_2D_Algo_i::~SMESH_2D_Algo_i
+ *
+ * Destructor
*/
//=============================================================================
SMESH_2D_Algo_i::~SMESH_2D_Algo_i()
{
- MESSAGE("SMESH_2D_Algo_i::~SMESH_2D_Algo_i");
-}
-
-//=============================================================================
-/*!
- *
- */
-//=============================================================================
-
-void SMESH_2D_Algo_i::SetImpl(::SMESH_2D_Algo* impl)
-{
- MESSAGE("SMESH_2D_Algo_i::SetImpl");
- SMESH_Algo_i::SetImpl(impl);
- _impl = impl;
+ MESSAGE( "SMESH_2D_Algo_i::~SMESH_2D_Algo_i" );
}
#include "SMESH_Algo_i.hxx"
-#include "SMESH_2D_Algo.hxx"
-
+// ======================================================
+// Generic 2D algorithm
+// ======================================================
class SMESH_2D_Algo_i:
- public POA_SMESH::SMESH_2D_Algo,
- public SMESH_Algo_i
+ public virtual POA_SMESH::SMESH_2D_Algo,
+ public virtual SMESH_Algo_i
{
-public:
- SMESH_2D_Algo_i();
-
- virtual ~SMESH_2D_Algo_i();
-
protected:
- virtual void SetImpl(::SMESH_2D_Algo* impl);
+ // Constructor : placed in protected section to prohibit creation of generic class instance
+ SMESH_2D_Algo_i( PortableServer::POA_ptr thePOA );
- ::SMESH_2D_Algo* _impl;
+public:
+ // Destructor
+ virtual ~SMESH_2D_Algo_i();
};
#endif
// Module : SMESH
// $Header$
-using namespace std;
using namespace std;
#include "SMESH_3D_Algo_i.hxx"
-#include "SMESH_Gen.hxx"
-#include "SMESH_HypothesisFactory.hxx"
-#include "Utils_CorbaException.hxx"
#include "utilities.h"
//=============================================================================
/*!
- *
+ * SMESH_3D_Algo_i::SMESH_3D_Algo_i
+ *
+ * Constructor
*/
//=============================================================================
-SMESH_3D_Algo_i::SMESH_3D_Algo_i()
+SMESH_3D_Algo_i::SMESH_3D_Algo_i( PortableServer::POA_ptr thePOA )
+ : SALOME::GenericObj_i( thePOA ),
+ SMESH_Hypothesis_i( thePOA ),
+ SMESH_Algo_i( thePOA )
{
- MESSAGE("SMESH_3D_Algo_i::SMESH_3D_Algo_i");
+ MESSAGE( "SMESH_3D_Algo_i::SMESH_3D_Algo_i" );
}
//=============================================================================
/*!
- *
+ * SMESH_3D_Algo_i::~SMESH_3D_Algo_i
+ *
+ * Destructor
*/
//=============================================================================
SMESH_3D_Algo_i::~SMESH_3D_Algo_i()
{
- MESSAGE("SMESH_3D_Algo_i::~SMESH_3D_Algo_i");
-}
-
-//=============================================================================
-/*!
- *
- */
-//=============================================================================
-
-void SMESH_3D_Algo_i::SetImpl(::SMESH_3D_Algo* impl)
-{
- MESSAGE("SMESH_3D_Algo_i::SetImpl");
- SMESH_Algo_i::SetImpl(impl);
- _impl = impl;
+ MESSAGE( "SMESH_3D_Algo_i::~SMESH_3D_Algo_i" );
}
#include "SMESH_Algo_i.hxx"
-class SMESH_3D_Algo;
-
+// ======================================================
+// Generic 3D algorithm
+// ======================================================
class SMESH_3D_Algo_i:
- public POA_SMESH::SMESH_3D_Algo,
- public SMESH_Algo_i
+ public virtual POA_SMESH::SMESH_3D_Algo,
+ public virtual SMESH_Algo_i
{
-public:
- SMESH_3D_Algo_i();
-
- virtual ~SMESH_3D_Algo_i();
-
protected:
- virtual void SetImpl(::SMESH_3D_Algo* impl);
+ // Constructor : placed in protected section to prohibit creation of generic class instance
+ SMESH_3D_Algo_i( PortableServer::POA_ptr thePOA );
- ::SMESH_3D_Algo* _impl;
+public:
+ // Destructor
+ virtual ~SMESH_3D_Algo_i();
};
#endif
// Module : SMESH
// $Header$
-using namespace std;
using namespace std;
#include "SMESH_Algo_i.hxx"
-#include "SMESH_Gen.hxx"
-#include "SMESH_HypothesisFactory.hxx"
+#include "SMESH_Algo.hxx"
-#include "Utils_CorbaException.hxx"
#include "utilities.h"
#include <string>
//=============================================================================
/*!
- *
+ * SMESH_Algo_i::SMESH_Algo_i
+ *
+ * Constructor
*/
//=============================================================================
-SMESH_Algo_i::SMESH_Algo_i()
+SMESH_Algo_i::SMESH_Algo_i( PortableServer::POA_ptr thePOA )
+ : SALOME::GenericObj_i( thePOA ),
+ SMESH_Hypothesis_i( thePOA )
{
- MESSAGE("SMESH_Algo_i::SMESH_Algo_i");
+ MESSAGE( "SMESH_Algo_i::SMESH_Algo_i" );
}
//=============================================================================
/*!
- *
+ * SMESH_Algo_i::~SMESH_Algo_i
+ *
+ * Destructor
*/
//=============================================================================
SMESH_Algo_i::~SMESH_Algo_i()
{
- MESSAGE("SMESH_Algo_i::~SMESH_Algo_i");
+ MESSAGE( "SMESH_Algo_i::~SMESH_Algo_i" );
}
//=============================================================================
/*!
- *
+ * SMESH_Algo_i::GetCompatibleHypothesis
+ *
+ * Gets list of compatible hypotheses
*/
//=============================================================================
SMESH::ListOfHypothesisName* SMESH_Algo_i::GetCompatibleHypothesis()
{
- MESSAGE("SMESH_Algo_i::GetCompatibleHypothesis");
- SMESH::ListOfHypothesisName_var listOfHypothesis
- = new SMESH::ListOfHypothesisName;
- const vector<string> & hypList = _impl->GetCompatibleHypothesis();
+ MESSAGE( "SMESH_Algo_i::GetCompatibleHypothesis" );
+ SMESH::ListOfHypothesisName_var listOfHypothesis = new SMESH::ListOfHypothesisName;
+ const vector<string>& hypList = ( ( ::SMESH_Algo* )myBaseImpl )->GetCompatibleHypothesis();
int nbHyp = hypList.size();
- listOfHypothesis->length(nbHyp);
- for (int i=0; i<nbHyp; i++)
- {
- listOfHypothesis[i] = hypList[i].c_str();
- }
+ listOfHypothesis->length( nbHyp );
+ for ( int i = 0; i < nbHyp; i++ ) {
+ listOfHypothesis[ i ] = strdup( hypList[ i ].c_str() );
+ }
return listOfHypothesis._retn();
}
-
-//=============================================================================
-/*!
- *
- */
-//=============================================================================
-
-void SMESH_Algo_i::SetImpl(::SMESH_Algo* impl)
-{
- MESSAGE("SMESH_Algo_i::SetImpl");
- //SMESH_Algo_i::SetImpl(impl);
- _impl = impl;
-}
#include "SMESH_Hypothesis_i.hxx"
-#include "SMESH_Algo.hxx"
-
+// ======================================================
+// Generic algorithm
+// ======================================================
class SMESH_Algo_i:
- public POA_SMESH::SMESH_Algo,
- public SMESH_Hypothesis_i
+ public virtual POA_SMESH::SMESH_Algo,
+ public virtual SMESH_Hypothesis_i
{
public:
- SMESH_Algo_i();
+ // Constructor : placed in protected section to prohibit creation of generic class instance
+ SMESH_Algo_i( PortableServer::POA_ptr thePOA );
+public:
+ // Destructor
virtual ~SMESH_Algo_i();
-
+
+ // Gets list of compatible hypotheses
SMESH::ListOfHypothesisName* GetCompatibleHypothesis();
-
-protected:
- virtual void SetImpl(::SMESH_Algo* impl);
-
- ::SMESH_Algo* _impl;
};
#endif
--- /dev/null
+// SMESH SMESH_I : idl implementation based on 'SMESH' unit's calsses
+//
+// Copyright (C) 2003 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
+// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
+//
+// This library 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.
+//
+// This library 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 this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+//
+// See http://www.opencascade.org/SALOME/ or email : webmaster.salome@opencascade.org
+//
+//
+//
+// File : SMESH_Filter_i.cxx
+// Author : Alexey Petrov, OCC
+// Module : SMESH
+
+
+#include "SMESH_Filter_i.hxx"
+
+#include "SMDS_Iterator.hxx"
+#include "SMDS_MeshElement.hxx"
+#include "SMDS_MeshNode.hxx"
+#include "SMDSAbs_ElementType.hxx"
+#include "SMESH_Gen_i.hxx"
+#include "SMESHDS_Mesh.hxx"
+
+#include <gp_Pnt.hxx>
+#include <gp_Vec.hxx>
+#include <gp_XYZ.hxx>
+#include <Precision.hxx>
+#include <TColgp_SequenceOfXYZ.hxx>
+#include <TColStd_ListOfInteger.hxx>
+#include <TColStd_MapOfInteger.hxx>
+#include <TColStd_ListIteratorOfListOfInteger.hxx>
+
+/*
+ AUXILIARY METHODS
+*/
+
+static inline double getAngle( const gp_XYZ& P1, const gp_XYZ& P2, const gp_XYZ& P3 )
+{
+ return gp_Vec( P1 - P2 ).Angle( gp_Vec( P3 - P2 ) );
+}
+
+static inline double getArea( const gp_XYZ& P1, const gp_XYZ& P2, const gp_XYZ& P3 )
+{
+ gp_Vec aVec1( P2 - P1 );
+ gp_Vec aVec2( P3 - P1 );
+ return ( aVec1 ^ aVec2 ).Magnitude() * 0.5;
+}
+
+static inline double getArea( const gp_Pnt& P1, const gp_Pnt& P2, const gp_Pnt& P3 )
+{
+ return getArea( P1.XYZ(), P2.XYZ(), P3.XYZ() );
+}
+
+static inline double getDistance( const gp_XYZ& P1, const gp_XYZ& P2 )
+{
+ double aDist = gp_Pnt( P1 ).Distance( gp_Pnt( P2 ) );
+ return aDist;
+}
+
+static int getNbMultiConnection( SMESHDS_Mesh* theMesh, const int theId )
+{
+ if ( theMesh == 0 )
+ return 0;
+
+ const SMDS_MeshElement* anEdge = theMesh->FindElement( theId );
+ if ( anEdge == 0 || anEdge->GetType() != SMDSAbs_Edge || anEdge->NbNodes() != 2 )
+ return 0;
+
+ TColStd_MapOfInteger aMap;
+
+ int aResult = 0;
+ SMDS_ElemIteratorPtr anIter = anEdge->nodesIterator();
+ if ( anIter != 0 )
+ {
+ while( anIter->more() )
+ {
+ const SMDS_MeshNode* aNode = (SMDS_MeshNode*)anIter->next();
+ if ( aNode == 0 )
+ return 0;
+ SMDS_ElemIteratorPtr anElemIter = aNode->GetInverseElementIterator();
+ while( anElemIter->more() )
+ {
+ const SMDS_MeshElement* anElem = anElemIter->next();
+ if ( anElem != 0 && anElem->GetType() != SMDSAbs_Edge )
+ {
+ int anId = anElem->GetID();
+
+ if ( anIter->more() ) // i.e. first node
+ aMap.Add( anId );
+ else if ( aMap.Contains( anId ) )
+ aResult++;
+ }
+ }
+// delete anElemIter;
+ }
+// delete anIter;
+ }
+
+ return aResult;
+}
+
+using namespace std;
+using namespace SMESH;
+
+/*
+ FUNCTORS
+*/
+
+/*
+ Class : NumericalFunctor_i
+ Description : Base class for numerical functors
+*/
+
+NumericalFunctor_i::NumericalFunctor_i()
+: SALOME::GenericObj_i( SMESH_Gen_i::GetPOA() )
+{
+ myMesh = 0;
+ SMESH_Gen_i::GetPOA()->activate_object( this );
+}
+
+void NumericalFunctor_i::SetMesh( SMESH_Mesh_ptr theMesh )
+{
+ SMESH_Mesh_i* anImplPtr =
+ dynamic_cast<SMESH_Mesh_i*>( SMESH_Gen_i::GetServant( theMesh ).in() );
+ myMesh = anImplPtr ? anImplPtr->GetImpl().GetMeshDS() : 0;
+}
+
+bool NumericalFunctor_i::getPoints( const int theId,
+ TColgp_SequenceOfXYZ& theRes ) const
+{
+ theRes.Clear();
+
+ if ( myMesh == 0 )
+ return false;
+
+ // Get nodes of the face
+ const SMDS_MeshElement* anElem = myMesh->FindElement( theId );
+ if ( anElem == 0 || anElem->GetType() != GetType() )
+ return false;
+
+ int nbNodes = anElem->NbNodes();
+
+ SMDS_ElemIteratorPtr anIter = anElem->nodesIterator();
+ if ( anIter != 0 )
+ {
+ while( anIter->more() )
+ {
+ const SMDS_MeshNode* aNode = (SMDS_MeshNode*)anIter->next();
+ if ( aNode != 0 )
+ theRes.Append( gp_XYZ( aNode->X(), aNode->Y(), aNode->Z() ) );
+ }
+
+// delete anIter;
+ }
+
+ return true;
+}
+
+
+/*
+ Class : SMESH_MinimumAngleFunct
+ Description : Functor for calculation of minimum angle
+*/
+
+CORBA::Double MinimumAngle_i::GetValue( CORBA::Long theId )
+{
+ TColgp_SequenceOfXYZ P;
+ if ( !getPoints( theId, P ) || P.Length() != 3 && P.Length() != 4 )
+ return 0;
+
+ double aMin;
+
+ if ( P.Length() == 3 )
+ {
+ double A0 = getAngle( P( 3 ), P( 1 ), P( 2 ) );
+ double A1 = getAngle( P( 1 ), P( 2 ), P( 3 ) );
+ double A2 = getAngle( P( 2 ), P( 3 ), P( 1 ) );
+
+ aMin = Min( A0, Min( A1, A2 ) );
+ }
+ else
+ {
+ double A0 = getAngle( P( 4 ), P( 1 ), P( 2 ) );
+ double A1 = getAngle( P( 1 ), P( 2 ), P( 3 ) );
+ double A2 = getAngle( P( 2 ), P( 3 ), P( 4 ) );
+ double A3 = getAngle( P( 3 ), P( 4 ), P( 1 ) );
+
+ aMin = Min( Min( A0, A1 ), Min( A2, A3 ) );
+ }
+
+ return aMin * 180 / PI;
+}
+
+int MinimumAngle_i::GetType() const
+{
+ return SMDSAbs_Face;
+}
+
+/*
+ Class : AspectRatio_i
+ Description : Functor for calculating aspect ratio
+*/
+
+CORBA::Double AspectRatio_i::GetValue( CORBA::Long theId )
+{
+ TColgp_SequenceOfXYZ P;
+ if ( !getPoints( theId, P ) || P.Length() != 3 && P.Length() != 4 )
+ return 0;
+
+ int nbNodes = P.Length();
+
+ // Compute lengths of the sides
+
+ double aLen[ nbNodes ];
+ for ( int i = 0; i < nbNodes - 1; i++ )
+ aLen[ i ] = getDistance( P( i + 1 ), P( i + 2 ) );
+ aLen[ nbNodes - 1 ] = getDistance( P( 1 ), P( nbNodes ) );
+
+ // Compute aspect ratio
+
+ if ( nbNodes == 3 )
+ {
+ double aMaxLen = Max( aLen[ 0 ], Max( aLen[ 1 ], aLen[ 2 ] ) );
+ double anArea = getArea( P( 1 ), P( 2 ), P( 3 ) );
+ static double aCoef = sqrt( 3. ) / 4;
+
+ return anArea != 0 ? aCoef * aMaxLen * aMaxLen / anArea : 0;
+ }
+ else
+ {
+ double aMaxLen = Max( Max( aLen[ 0 ], aLen[ 1 ] ), Max( aLen[ 2 ], aLen[ 3 ] ) );
+ double aMinLen = Min( Min( aLen[ 0 ], aLen[ 1 ] ), Min( aLen[ 2 ], aLen[ 3 ] ) );
+
+ return aMinLen != 0 ? aMaxLen / aMinLen : 0;
+ }
+}
+
+int AspectRatio_i::GetType() const
+{
+ return SMDSAbs_Face;
+}
+
+/*
+ Class : Warping_i
+ Description : Functor for calculating warping
+*/
+
+CORBA::Double Warping_i::GetValue( CORBA::Long theId )
+{
+ TColgp_SequenceOfXYZ P;
+ if ( !getPoints( theId, P ) || P.Length() != 4 )
+ return 0;
+
+ gp_XYZ G = ( P( 1 ) + P( 2 ) + P( 3 ) + P( 4 ) ) / 4;
+
+ double A1 = ComputeA( P( 1 ), P( 2 ), P( 3 ), G );
+ double A2 = ComputeA( P( 2 ), P( 3 ), P( 4 ), G );
+ double A3 = ComputeA( P( 3 ), P( 4 ), P( 1 ), G );
+ double A4 = ComputeA( P( 4 ), P( 1 ), P( 2 ), G );
+
+ return Max( Max( A1, A2 ), Max( A3, A4 ) );
+}
+
+double Warping_i::ComputeA( const gp_XYZ& thePnt1,
+ const gp_XYZ& thePnt2,
+ const gp_XYZ& thePnt3,
+ const gp_XYZ& theG ) const
+{
+ double aLen1 = gp_Pnt( thePnt1 ).Distance( gp_Pnt( thePnt2 ) );
+ double aLen2 = gp_Pnt( thePnt2 ).Distance( gp_Pnt( thePnt3 ) );
+ double L = Min( aLen1, aLen2 ) * 0.5;
+
+ gp_XYZ GI = ( thePnt2 - thePnt1 ) / 2. - theG;
+ gp_XYZ GJ = ( thePnt3 - thePnt2 ) / 2. - theG;
+ gp_XYZ N = GI.Crossed( GJ );
+ N.Normalize();
+
+ double H = gp_Vec( thePnt2 - theG ).Dot( gp_Vec( N ) );
+ return asin( fabs( H / L ) ) * 180 / PI;
+}
+
+int Warping_i::GetType() const
+{
+ return SMDSAbs_Face;
+}
+
+/*
+ Class : Taper_i
+ Description : Functor for calculating taper
+*/
+
+CORBA::Double Taper_i::GetValue( CORBA::Long theId )
+{
+ TColgp_SequenceOfXYZ P;
+ if ( !getPoints( theId, P ) || P.Length() != 4 )
+ return 0;
+
+ // Compute taper
+ double J1 = getArea( P( 4 ), P( 1 ), P( 2 ) ) / 2;
+ double J2 = getArea( P( 3 ), P( 1 ), P( 2 ) ) / 2;
+ double J3 = getArea( P( 2 ), P( 3 ), P( 4 ) ) / 2;
+ double J4 = getArea( P( 3 ), P( 4 ), P( 1 ) ) / 2;
+
+ double JA = 0.25 * ( J1 + J2 + J3 + J4 );
+
+ double T1 = fabs( ( J1 - JA ) / JA );
+ double T2 = fabs( ( J2 - JA ) / JA );
+ double T3 = fabs( ( J3 - JA ) / JA );
+ double T4 = fabs( ( J4 - JA ) / JA );
+
+ return Max( Max( T1, T2 ), Max( T3, T4 ) );
+}
+
+int Taper_i::GetType() const
+{
+ return SMDSAbs_Face;
+}
+
+/*
+ Class : Skew_i
+ Description : Functor for calculating skew in degrees
+*/
+
+static inline double skewAngle( const gp_XYZ& p1, const gp_XYZ& p2, const gp_XYZ& p3 )
+{
+ gp_XYZ p12 = ( p2 + p1 ) / 2;
+ gp_XYZ p23 = ( p3 + p2 ) / 2;
+ gp_XYZ p31 = ( p3 + p1 ) / 2;
+
+ return gp_Vec( p31 - p2 ).Angle( p12 - p23 );
+}
+
+CORBA::Double Skew_i::GetValue( CORBA::Long theId )
+{
+ TColgp_SequenceOfXYZ P;
+ if ( !getPoints( theId, P ) || P.Length() != 3 && P.Length() != 4 )
+ return 0;
+
+ // Compute skew
+ static double PI2 = PI / 2;
+ if ( P.Length() == 3 )
+ {
+ double A0 = fabs( PI2 - skewAngle( P( 3 ), P( 1 ), P( 2 ) ) );
+ double A1 = fabs( PI2 - skewAngle( P( 1 ), P( 2 ), P( 3 ) ) );
+ double A2 = fabs( PI2 - skewAngle( P( 2 ), P( 3 ), P( 1 ) ) );
+
+ return Max( A0, Max( A1, A2 ) ) * 180 / PI;
+ }
+ else
+ {
+ gp_XYZ p12 = ( P( 1 ) + P( 2 ) ) / 2;
+ gp_XYZ p23 = ( P( 2 ) + P( 3 ) ) / 2;
+ gp_XYZ p34 = ( P( 3 ) + P( 4 ) ) / 2;
+ gp_XYZ p41 = ( P( 4 ) + P( 1 ) ) / 2;
+
+ double A = fabs( PI2 - gp_Vec( p34 - p12 ).Angle( p23 - p41 ) );
+
+ return A * 180 / PI;
+ }
+}
+
+int Skew_i::GetType() const
+{
+ return SMDSAbs_Face;
+}
+
+/*
+ Class : Area_i
+ Description : Functor for calculating area
+*/
+
+CORBA::Double Area_i::GetValue( CORBA::Long theId )
+{
+ TColgp_SequenceOfXYZ P;
+ if ( !getPoints( theId, P ) || P.Length() != 3 && P.Length() != 4 )
+ return 0;
+
+ if ( P.Length() == 3 )
+ return getArea( P( 1 ), P( 2 ), P( 3 ) );
+ else
+ return getArea( P( 1 ), P( 2 ), P( 3 ) ) + getArea( P( 1 ), P( 3 ), P( 4 ) );
+}
+
+int Area_i::GetType() const
+{
+ return SMDSAbs_Face;
+}
+
+/*
+ Class : Length_i
+ Description : Functor for calculating length off edge
+*/
+
+CORBA::Double Length_i::GetValue( CORBA::Long theId )
+{
+ TColgp_SequenceOfXYZ P;
+ return getPoints( theId, P ) && P.Length() == 2 ? getDistance( P( 1 ), P( 2 ) ) : 0;
+}
+
+int Length_i::GetType() const
+{
+ return SMDSAbs_Edge;
+}
+
+/*
+ Class : MultiConnection_i
+ Description : Functor for calculating number of faces conneted to the edge
+*/
+
+CORBA::Double MultiConnection_i::GetValue( CORBA::Long theId )
+{
+ return getNbMultiConnection( myMesh, theId );
+}
+
+int MultiConnection_i::GetType() const
+{
+ return SMDSAbs_Edge;
+}
+
+/*
+ PREDICATES
+*/
+
+/*
+ Class : Predicate_i
+ Description : Base class for all predicates
+*/
+Predicate_i::Predicate_i()
+: SALOME::GenericObj_i( SMESH_Gen_i::GetPOA() )
+{
+ SMESH_Gen_i::GetPOA()->activate_object( this );
+}
+
+
+/*
+ Class : FreeBorders_i
+ Description : Predicate for free borders
+*/
+
+FreeBorders_i::FreeBorders_i()
+{
+ myMesh = 0;
+}
+
+void FreeBorders_i::SetMesh( SMESH_Mesh_ptr theMesh )
+{
+ SMESH_Mesh_i* anImplPtr =
+ dynamic_cast<SMESH_Mesh_i*>( SMESH_Gen_i::GetServant( theMesh ).in() );
+ myMesh = anImplPtr ? anImplPtr->GetImpl().GetMeshDS() : 0;
+}
+
+CORBA::Boolean FreeBorders_i::IsSatisfy( CORBA::Long theId )
+{
+ return getNbMultiConnection( myMesh, theId ) == 1;
+}
+
+int FreeBorders_i::GetType() const
+{
+ return SMDSAbs_Edge;
+}
+
+/*
+ Class : Comparator_i
+ Description : Base class for comparators
+*/
+
+Comparator_i::Comparator_i()
+{
+ myMargin = 0;
+ myFunctor = 0;
+}
+
+Comparator_i::~Comparator_i()
+{
+ if ( myFunctor != 0 )
+ myFunctor->Destroy();
+}
+
+void Comparator_i::SetMesh( SMESH_Mesh_ptr theMesh )
+{
+ if ( myFunctor != 0 )
+ myFunctor->SetMesh( theMesh );
+}
+
+void Comparator_i::SetMargin( CORBA::Double theValue )
+{
+ myMargin = theValue;
+}
+
+void Comparator_i::SetNumFunctor( NumericalFunctor_ptr theFunct )
+{
+ if ( myFunctor != 0 )
+ myFunctor->Destroy();
+
+ myFunctor = dynamic_cast<NumericalFunctor_i*>( SMESH_Gen_i::GetServant( theFunct ).in() );
+
+ if ( myFunctor != 0 )
+ myFunctor->Register();
+}
+
+int Comparator_i::GetType() const
+{
+ return myFunctor != 0 ? myFunctor->GetType() : SMDSAbs_All;
+}
+
+/*
+ Class : LessThan_i
+ Description : Comparator "<"
+*/
+
+CORBA::Boolean LessThan_i::IsSatisfy( CORBA::Long theId )
+{
+ return myFunctor != 0 && myFunctor->GetValue( theId ) < myMargin;
+}
+
+/*
+ Class : MoreThan_i
+ Description : Comparator ">"
+*/
+
+CORBA::Boolean MoreThan_i::IsSatisfy( CORBA::Long theId )
+{
+ return myFunctor != 0 && myFunctor->GetValue( theId ) > myMargin;
+}
+
+/*
+ Class : EqualTo_i
+ Description : Comparator "="
+*/
+EqualTo_i::EqualTo_i()
+{
+ myToler = Precision::Confusion();
+}
+
+CORBA::Boolean EqualTo_i::IsSatisfy( CORBA::Long theId )
+{
+ return myFunctor != 0 && fabs( myFunctor->GetValue( theId ) - myMargin ) < myToler;
+}
+
+void EqualTo_i::SetTolerance( CORBA::Double theToler )
+{
+ myToler = theToler;
+}
+
+
+/*
+ Class : LogicalNOT_i
+ Description : Logical NOT predicate
+*/
+
+LogicalNOT_i::LogicalNOT_i()
+{
+ myPredicate = 0;
+}
+
+LogicalNOT_i::~LogicalNOT_i()
+{
+ if ( myPredicate )
+ myPredicate->Destroy();
+}
+
+CORBA::Boolean LogicalNOT_i::IsSatisfy( CORBA::Long theId )
+{
+ return myPredicate !=0 && !myPredicate->IsSatisfy( theId );
+}
+
+void LogicalNOT_i::SetMesh( SMESH_Mesh_ptr theMesh )
+{
+ if ( myPredicate != 0 )
+ myPredicate->SetMesh( theMesh );
+}
+
+void LogicalNOT_i::SetPredicate( Predicate_ptr thePred )
+{
+ if ( myPredicate != 0 )
+ myPredicate->Destroy();
+
+ myPredicate = dynamic_cast<Predicate_i*>( SMESH_Gen_i::GetServant( thePred ).in() );
+
+ if ( myPredicate != 0 )
+ myPredicate->Register();
+}
+
+int LogicalNOT_i::GetType() const
+{
+ return myPredicate != 0 ? myPredicate->GetType() : SMDSAbs_All;
+}
+
+
+/*
+ Class : LogicalBinary_i
+ Description : Base class for binary logical predicate
+*/
+
+LogicalBinary_i::LogicalBinary_i()
+{
+ myPredicate1 = 0;
+ myPredicate2 = 0;
+}
+LogicalBinary_i::~LogicalBinary_i()
+{
+ if ( myPredicate1 != 0 )
+ myPredicate1->Destroy();
+
+ if ( myPredicate2 != 0 )
+ myPredicate2->Destroy();
+}
+
+void LogicalBinary_i::SetMesh( SMESH_Mesh_ptr theMesh )
+{
+ if ( myPredicate1 != 0 )
+ myPredicate1->SetMesh( theMesh );
+
+ if ( myPredicate2 != 0 )
+ myPredicate2->SetMesh( theMesh );
+}
+
+void LogicalBinary_i::SetPredicate1( Predicate_ptr thePredicate )
+{
+ if ( myPredicate1 != 0 )
+ myPredicate1->Destroy();
+
+ myPredicate1 = dynamic_cast<Predicate_i*>( SMESH_Gen_i::GetServant( thePredicate ).in() );
+
+ if ( myPredicate1 != 0 )
+ myPredicate1->Register();
+}
+
+void LogicalBinary_i::SetPredicate2( Predicate_ptr thePredicate )
+{
+ if ( myPredicate2 != 0 )
+ myPredicate2->Destroy();
+
+ myPredicate2 = dynamic_cast<Predicate_i*>( SMESH_Gen_i::GetServant( thePredicate ).in() );
+
+ if ( myPredicate2 != 0 )
+ myPredicate2->Register();
+}
+
+int LogicalBinary_i::GetType() const
+{
+ if ( myPredicate1 == 0 || myPredicate2 == 0 )
+ return SMDSAbs_All;
+
+ int aType1 = myPredicate1->GetType();
+ int aType2 = myPredicate2->GetType();
+
+ return aType1 == aType2 ? aType1 : SMDSAbs_All;
+}
+
+/*
+ Class : LogicalAND_i
+ Description : Logical AND
+*/
+
+CORBA::Boolean LogicalAND_i::IsSatisfy( CORBA::Long theId )
+{
+ return myPredicate1 != 0 &&
+ myPredicate2 != 0 &&
+ myPredicate1->IsSatisfy( theId ) && myPredicate2->IsSatisfy( theId );;
+}
+
+/*
+ Class : LogicalOR_i
+ Description : Logical OR
+*/
+
+CORBA::Boolean LogicalOR_i::IsSatisfy( CORBA::Long theId )
+{
+ return myPredicate1 != 0 &&
+ myPredicate2 != 0 &&
+ myPredicate1->IsSatisfy( theId ) || myPredicate2->IsSatisfy( theId );
+}
+
+
+/*
+ FILTER
+*/
+
+Filter_i::Filter_i()
+{
+ myPredicate = 0;
+}
+
+Filter_i::~Filter_i()
+{
+ if ( myPredicate != 0 )
+ myPredicate->Destroy();
+}
+
+void Filter_i::SetPredicate( Predicate_ptr thePredicate )
+{
+ if ( myPredicate != 0 )
+ myPredicate->Destroy();
+
+ myPredicate = dynamic_cast<Predicate_i*>( SMESH_Gen_i::GetServant( thePredicate ).in() );
+
+ if ( myPredicate != 0 )
+ myPredicate->Register();
+}
+
+void Filter_i::SetMesh( SMESH_Mesh_ptr theMesh )
+{
+ if ( myPredicate != 0 )
+ myPredicate->SetMesh( theMesh );
+}
+
+SMESH::long_array* Filter_i::GetElementsId( SMESH_Mesh_ptr theMesh )
+{
+
+ SetMesh( theMesh );
+
+ SMESH_Mesh_i* anImplPtr =
+ dynamic_cast<SMESH_Mesh_i*>( SMESH_Gen_i::GetServant( theMesh ).in() );
+
+ TColStd_ListOfInteger aList;
+
+ if ( anImplPtr != 0 )
+ {
+ SMESHDS_Mesh* aMesh = anImplPtr->GetImpl().GetMeshDS();
+
+ if ( myPredicate != 0 )
+ {
+ int aType = myPredicate->GetType();
+
+ if ( aType == SMDSAbs_Edge )
+ {
+ SMDS_EdgeIteratorPtr anIter = aMesh->edgesIterator();
+ if ( anIter != 0 )
+ {
+ while( anIter->more() )
+ {
+ const SMDS_MeshElement* anElem = anIter->next();
+ if ( myPredicate->IsSatisfy( anElem->GetID() ) )
+ aList.Append( anElem->GetID() );
+ }
+ }
+// delete anIter;
+ }
+ else if ( aType == SMDSAbs_Face )
+ {
+ SMDS_FaceIteratorPtr anIter = aMesh->facesIterator();
+ if ( anIter != 0 )
+ {
+ while( anIter->more() )
+ {
+ const SMDS_MeshElement* anElem = anIter->next();
+ if ( myPredicate->IsSatisfy( anElem->GetID() ) )
+ aList.Append( anElem->GetID() );
+ }
+ }
+// delete anIter;
+ }
+ }
+ }
+
+ SMESH::long_array_var anArray = new SMESH::long_array;
+
+ anArray->length( aList.Extent() );
+ TColStd_ListIteratorOfListOfInteger anIter( aList );
+ int i = 0;
+ for( ; anIter.More(); anIter.Next() )
+ anArray[ i++ ] = anIter.Value();
+
+ return anArray._retn();
+}
+
+/*
+ FILTER MANAGER
+*/
+
+FilterManager_i::FilterManager_i()
+: SALOME::GenericObj_i( SMESH_Gen_i::GetPOA() )
+{
+ SMESH_Gen_i::GetPOA()->activate_object( this );
+}
+
+MinimumAngle_ptr FilterManager_i::CreateMinimumAngle()
+{
+ SMESH::MinimumAngle_i* aServant = new SMESH::MinimumAngle_i();
+ SMESH::MinimumAngle_var anObj = aServant->_this();
+ return anObj._retn();
+}
+
+
+AspectRatio_ptr FilterManager_i::CreateAspectRatio()
+{
+ SMESH::AspectRatio_i* aServant = new SMESH::AspectRatio_i();
+ SMESH::AspectRatio_var anObj = aServant->_this();
+ return anObj._retn();
+}
+
+
+Warping_ptr FilterManager_i::CreateWarping()
+{
+ SMESH::Warping_i* aServant = new SMESH::Warping_i();
+ SMESH::Warping_var anObj = aServant->_this();
+ return anObj._retn();
+}
+
+
+Taper_ptr FilterManager_i::CreateTaper()
+{
+ SMESH::Taper_i* aServant = new SMESH::Taper_i();
+ SMESH::Taper_var anObj = aServant->_this();
+ return anObj._retn();
+}
+
+
+Skew_ptr FilterManager_i::CreateSkew()
+{
+ SMESH::Skew_i* aServant = new SMESH::Skew_i();
+ SMESH::Skew_var anObj = aServant->_this();
+ return anObj._retn();
+}
+
+
+Area_ptr FilterManager_i::CreateArea()
+{
+ SMESH::Area_i* aServant = new SMESH::Area_i();
+ SMESH::Area_var anObj = aServant->_this();
+ return anObj._retn();
+}
+
+
+Length_ptr FilterManager_i::CreateLength()
+{
+ SMESH::Length_i* aServant = new SMESH::Length_i();
+ SMESH::Length_var anObj = aServant->_this();
+ return anObj._retn();
+}
+
+
+MultiConnection_ptr FilterManager_i::CreateMultiConnection()
+{
+ SMESH::MultiConnection_i* aServant = new SMESH::MultiConnection_i();
+ SMESH::MultiConnection_var anObj = aServant->_this();
+ return anObj._retn();
+}
+
+
+FreeBorders_ptr FilterManager_i::CreateFreeBorders()
+{
+ SMESH::FreeBorders_i* aServant = new SMESH::FreeBorders_i();
+ SMESH::FreeBorders_var anObj = aServant->_this();
+ return anObj._retn();
+}
+
+LessThan_ptr FilterManager_i::CreateLessThan()
+{
+ SMESH::LessThan_i* aServant = new SMESH::LessThan_i();
+ SMESH::LessThan_var anObj = aServant->_this();
+ return anObj._retn();
+}
+
+
+MoreThan_ptr FilterManager_i::CreateMoreThan()
+{
+ SMESH::MoreThan_i* aServant = new SMESH::MoreThan_i();
+ SMESH::MoreThan_var anObj = aServant->_this();
+ return anObj._retn();
+}
+
+EqualTo_ptr FilterManager_i::CreateEqualTo()
+{
+ SMESH::EqualTo_i* aServant = new SMESH::EqualTo_i();
+ SMESH::EqualTo_var anObj = aServant->_this();
+ return anObj._retn();
+}
+
+
+LogicalNOT_ptr FilterManager_i::CreateLogicalNOT()
+{
+ SMESH::LogicalNOT_i* aServant = new SMESH::LogicalNOT_i();
+ SMESH::LogicalNOT_var anObj = aServant->_this();
+ return anObj._retn();
+}
+
+
+LogicalAND_ptr FilterManager_i::CreateLogicalAND()
+{
+ SMESH::LogicalAND_i* aServant = new SMESH::LogicalAND_i();
+ SMESH::LogicalAND_var anObj = aServant->_this();
+ return anObj._retn();
+}
+
+
+LogicalOR_ptr FilterManager_i::CreateLogicalOR()
+{
+ SMESH::LogicalOR_i* aServant = new SMESH::LogicalOR_i();
+ SMESH::LogicalOR_var anObj = aServant->_this();
+ return anObj._retn();
+}
+
+Filter_ptr FilterManager_i::CreateFilter()
+{
+ SMESH::Filter_i* aServant = new SMESH::Filter_i();
+ SMESH::Filter_var anObj = aServant->_this();
+ return anObj._retn();
+}
--- /dev/null
+// SMESH SMESH_I : idl implementation based on 'SMESH' unit's calsses\r
+//\r
+// Copyright (C) 2003 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,\r
+// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS \r
+// \r
+// This library is free software; you can redistribute it and/or \r
+// modify it under the terms of the GNU Lesser General Public \r
+// License as published by the Free Software Foundation; either \r
+// version 2.1 of the License. \r
+// \r
+// This library is distributed in the hope that it will be useful, \r
+// but WITHOUT ANY WARRANTY; without even the implied warranty of \r
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU \r
+// Lesser General Public License for more details. \r
+// \r
+// You should have received a copy of the GNU Lesser General Public \r
+// License along with this library; if not, write to the Free Software \r
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA \r
+// \r
+// See http://www.opencascade.org/SALOME/ or email : webmaster.salome@opencascade.org \r
+//\r
+//\r
+//\r
+// File : SMESH_Filter_i.hxx\r
+// Author : Alexey Petrov, OCC\r
+// Module : SMESH\r
+\r
+#ifndef _SMESH_FILTER_I_HXX_\r
+#define _SMESH_FILTER_I_HXX_\r
+\r
+#include <SALOMEconfig.h>\r
+#include CORBA_SERVER_HEADER(SMESH_Filter)\r
+#include "SALOME_GenericObj_i.hh"\r
+\r
+class SMESHDS_Mesh;\r
+class gp_Pnt;\r
+class gp_XYZ;\r
+class TColgp_SequenceOfXYZ;\r
+\r
+namespace SMESH{\r
+\r
+/*\r
+ FUNCTORS\r
+*/\r
+\r
+/*\r
+ Class : NumericalFunctor_i\r
+ Description : Base class for numerical functors \r
+ \r
+ PortableServer::POA_ptr thePOA\r
+\r
+*/\r
+\r
+class NumericalFunctor_i: public virtual POA_SMESH::NumericalFunctor,\r
+ public virtual SALOME::GenericObj_i\r
+{\r
+public:\r
+ NumericalFunctor_i();\r
+ void SetMesh( SMESH_Mesh_ptr theMesh );\r
+ virtual int GetType() const = 0;\r
+\r
+protected:\r
+ bool getPoints( const int theId, \r
+ TColgp_SequenceOfXYZ& theRes ) const;\r
+protected:\r
+ SMESHDS_Mesh* myMesh;\r
+};\r
+\r
+/*\r
+ Class : SMESH_MinimumAngleFunct\r
+ Description : Functor for calculation of minimum angle\r
+*/\r
+\r
+class MinimumAngle_i: public virtual POA_SMESH::MinimumAngle,\r
+ public virtual NumericalFunctor_i\r
+{\r
+public:\r
+ CORBA::Double GetValue( CORBA::Long theElementId );\r
+ virtual int GetType() const;\r
+};\r
+\r
+/*\r
+ Class : AspectRatio_i\r
+ Description : Functor for calculating aspect ratio\r
+*/\r
+\r
+class AspectRatio_i: public virtual POA_SMESH::AspectRatio,\r
+ public virtual NumericalFunctor_i\r
+{\r
+public:\r
+ CORBA::Double GetValue(CORBA::Long theElementId);\r
+ virtual int GetType() const;\r
+};\r
+\r
+/*\r
+ Class : Warping_i\r
+ Description : Functor for calculating warping\r
+*/\r
+\r
+class Warping_i: public virtual POA_SMESH::Warping,\r
+ public virtual NumericalFunctor_i\r
+{\r
+public:\r
+ CORBA::Double GetValue(CORBA::Long theElementId);\r
+ virtual int GetType() const;\r
+\r
+private:\r
+ double ComputeA( const gp_XYZ&, const gp_XYZ&, \r
+ const gp_XYZ&, const gp_XYZ& ) const;\r
+};\r
+\r
+/*\r
+ Class : Taper_i\r
+ Description : Functor for calculating taper\r
+*/\r
+\r
+class Taper_i: public virtual POA_SMESH::Taper,\r
+ public virtual NumericalFunctor_i\r
+{\r
+public:\r
+ CORBA::Double GetValue( CORBA::Long theElementId );\r
+ virtual int GetType() const;\r
+};\r
+\r
+/*\r
+ Class : Skew_i\r
+ Description : Functor for calculating skew in degrees\r
+*/\r
+\r
+class Skew_i: public virtual POA_SMESH::Skew,\r
+ public virtual NumericalFunctor_i\r
+{\r
+public:\r
+ CORBA::Double GetValue( CORBA::Long theElementId );\r
+ virtual int GetType() const;\r
+};\r
+\r
+/*\r
+ Class : Area_i\r
+ Description : Functor for calculating area\r
+*/\r
+\r
+class Area_i: public virtual POA_SMESH::Area,\r
+ public virtual NumericalFunctor_i\r
+{\r
+public:\r
+ CORBA::Double GetValue( CORBA::Long theElementId );\r
+ virtual int GetType() const;\r
+};\r
+\r
+/*\r
+ Class : Length_i\r
+ Description : Functor for calculating length of edge\r
+*/\r
+\r
+class Length_i: public virtual POA_SMESH::Length,\r
+ public virtual NumericalFunctor_i\r
+{\r
+public:\r
+ CORBA::Double GetValue( CORBA::Long theElementId );\r
+ virtual int GetType() const;\r
+};\r
+\r
+/*\r
+ Class : MultiConnection_i\r
+ Description : Functor for calculating number of faces conneted to the edge\r
+*/\r
+\r
+class MultiConnection_i: public virtual POA_SMESH::MultiConnection,\r
+ public virtual NumericalFunctor_i\r
+{\r
+public:\r
+ CORBA::Double GetValue( CORBA::Long theElementId );\r
+ virtual int GetType() const;\r
+};\r
+\r
+\r
+/*\r
+ PREDICATES\r
+*/\r
+\r
+/*\r
+ Class : Predicate_i\r
+ Description : Base class for all predicates\r
+*/\r
+\r
+class Predicate_i: public virtual POA_SMESH::Predicate,\r
+ public virtual SALOME::GenericObj_i\r
+{\r
+public:\r
+ Predicate_i();\r
+ virtual int GetType() const = 0;\r
+};\r
+\r
+\r
+/*\r
+ Class : FreeBorders_i\r
+ Description : Predicate for free borders\r
+*/\r
+\r
+class FreeBorders_i: public virtual POA_SMESH::FreeBorders,\r
+ public virtual Predicate_i\r
+{\r
+public:\r
+ FreeBorders_i();\r
+ void SetMesh( SMESH_Mesh_ptr theMesh );\r
+ CORBA::Boolean IsSatisfy( CORBA::Long theElementId );\r
+ virtual int GetType() const;\r
+\r
+protected:\r
+ SMESHDS_Mesh* myMesh;\r
+};\r
+\r
+/*\r
+ Class : Comparator_i\r
+ Description : Base class for comparators\r
+*/\r
+\r
+class Comparator_i: public virtual POA_SMESH::Comparator,\r
+ public virtual Predicate_i\r
+{\r
+public:\r
+ Comparator_i();\r
+ virtual ~Comparator_i();\r
+\r
+ void SetMesh( SMESH_Mesh_ptr theMesh );\r
+ void SetMargin( CORBA::Double );\r
+ void SetNumFunctor( NumericalFunctor_ptr );\r
+\r
+ virtual int GetType() const;\r
+\r
+protected:\r
+ CORBA::Double myMargin;\r
+ NumericalFunctor_i* myFunctor;\r
+};\r
+\r
+/*\r
+ Class : LessThan_i\r
+ Description : Comparator "<"\r
+*/\r
+\r
+class LessThan_i: public virtual POA_SMESH::LessThan,\r
+ public virtual Comparator_i\r
+{\r
+public:\r
+ CORBA::Boolean IsSatisfy( CORBA::Long theElementId );\r
+};\r
+\r
+/*\r
+ Class : MoreThan_i\r
+ Description : Comparator ">"\r
+*/\r
+class MoreThan_i: public virtual POA_SMESH::MoreThan,\r
+ public virtual Comparator_i\r
+{\r
+public:\r
+ CORBA::Boolean IsSatisfy( CORBA::Long theElementId );\r
+};\r
+\r
+/*\r
+ Class : EqualTo_i\r
+ Description : Comparator "="\r
+*/\r
+class EqualTo_i: public virtual POA_SMESH::EqualTo,\r
+ public virtual Comparator_i\r
+{\r
+public:\r
+ EqualTo_i();\r
+\r
+ CORBA::Boolean IsSatisfy( CORBA::Long theElementId );\r
+\r
+ void SetTolerance( CORBA::Double );\r
+\r
+private:\r
+ CORBA::Double myToler;\r
+};\r
+\r
+/*\r
+ Class : Logical_i\r
+ Description : Base class for logical predicate\r
+*/\r
+\r
+class Logical_i: public virtual POA_SMESH::Logical,\r
+ public virtual Predicate_i\r
+ \r
+{\r
+};\r
+\r
+/*\r
+ Class : LogicalNOT_i\r
+ Description : Logical NOT predicate\r
+*/\r
+\r
+class LogicalNOT_i: public virtual POA_SMESH::LogicalNOT,\r
+ public virtual Logical_i\r
+{\r
+public:\r
+ LogicalNOT_i();\r
+ virtual ~LogicalNOT_i();\r
+\r
+ CORBA::Boolean IsSatisfy( CORBA::Long );\r
+\r
+ void SetMesh( SMESH_Mesh_ptr );\r
+ void SetPredicate( Predicate_ptr );\r
+\r
+ virtual int GetType() const;\r
+\r
+private:\r
+ Predicate_i* myPredicate;\r
+};\r
+\r
+\r
+/*\r
+ Class : LogicalBinary_i\r
+ Description : Base class for binary logical predicate\r
+*/\r
+\r
+class LogicalBinary_i: public virtual POA_SMESH::LogicalBinary,\r
+ public virtual Logical_i\r
+{\r
+public:\r
+ LogicalBinary_i();\r
+ virtual ~LogicalBinary_i();\r
+\r
+ void SetMesh( SMESH_Mesh_ptr );\r
+\r
+ void SetPredicate1( Predicate_ptr );\r
+ void SetPredicate2( Predicate_ptr );\r
+\r
+ virtual int GetType() const;\r
+\r
+protected:\r
+ Predicate_i* myPredicate1;\r
+ Predicate_i* myPredicate2;\r
+};\r
+\r
+/*\r
+ Class : LogicalAND_i\r
+ Description : Logical AND\r
+*/\r
+\r
+class LogicalAND_i: public virtual POA_SMESH::LogicalAND,\r
+ public virtual LogicalBinary_i\r
+{\r
+public:\r
+ CORBA::Boolean IsSatisfy( CORBA::Long theElementId );\r
+};\r
+\r
+/*\r
+ Class : LogicalOR_i\r
+ Description : Logical OR\r
+*/\r
+\r
+class LogicalOR_i: public virtual POA_SMESH::LogicalOR,\r
+ public virtual LogicalBinary_i\r
+{\r
+public:\r
+ CORBA::Boolean IsSatisfy( CORBA::Long theElementId );\r
+};\r
+\r
+\r
+/*\r
+ FILTER\r
+*/\r
+\r
+class Filter_i: public virtual POA_SMESH::Filter,\r
+ public virtual SALOME::GenericObj_i\r
+{\r
+public:\r
+ Filter_i();\r
+ virtual ~Filter_i();\r
+ void SetPredicate(Predicate_ptr );\r
+ long_array* GetElementsId(SMESH_Mesh_ptr );\r
+ void SetMesh( SMESH_Mesh_ptr );\r
+\r
+protected:\r
+ Predicate_i* myPredicate;\r
+};\r
+\r
+\r
+/*\r
+ FILTER MANAGER\r
+*/\r
+\r
+class FilterManager_i: public virtual POA_SMESH::FilterManager,\r
+ public virtual SALOME::GenericObj_i\r
+{\r
+public:\r
+ FilterManager_i();\r
+ MinimumAngle_ptr CreateMinimumAngle();\r
+ AspectRatio_ptr CreateAspectRatio();\r
+ Warping_ptr CreateWarping();\r
+ Taper_ptr CreateTaper();\r
+ Skew_ptr CreateSkew();\r
+ Area_ptr CreateArea();\r
+ Length_ptr CreateLength();\r
+ MultiConnection_ptr CreateMultiConnection();\r
+ \r
+ FreeBorders_ptr CreateFreeBorders();\r
+\r
+ LessThan_ptr CreateLessThan();\r
+ MoreThan_ptr CreateMoreThan();\r
+ EqualTo_ptr CreateEqualTo();\r
+ \r
+ LogicalNOT_ptr CreateLogicalNOT();\r
+ LogicalAND_ptr CreateLogicalAND();\r
+ LogicalOR_ptr CreateLogicalOR();\r
+\r
+ Filter_ptr CreateFilter();\r
+};\r
+\r
+\r
+\r
+};\r
+\r
+\r
+#endif\r
// Module : SMESH
// $Header$
+using namespace std;
#include <TopExp.hxx>
#include <TopExp_Explorer.hxx>
#include <TopoDS.hxx>
#include <TopoDS_Vertex.hxx>
#include <TopoDS_Shape.hxx>
#include <TopTools_MapOfShape.hxx>
+#include <TopTools_IndexedMapOfShape.hxx>
#include <gp_Pnt.hxx>
#include <BRep_Tool.hxx>
#include <TCollection_AsciiString.hxx>
-#include "SMESH_Gen_i.hxx"
-#include "SMESH_Mesh_i.hxx"
-#include "SMESH_LocalLength_i.hxx"
-#include "SMESH_NumberOfSegments_i.hxx"
-#include "SMESH_MaxElementArea_i.hxx"
-#include "SMESH_MaxElementVolume_i.hxx"
-
-#include "SMESHDriver.h"
-
#include "Utils_CorbaException.hxx"
+
#include "utilities.h"
+#include <fstream>
+#include <stdio.h>
+#include <dlfcn.h>
+
+#include <HDFOI.hxx>
+
+#include "SMESH_Gen_i.hxx"
+#include "SMESH_Mesh_i.hxx"
+#include "SMESH_Hypothesis_i.hxx"
+#include "SMESH_Algo_i.hxx"
+#include "SMESH_Group_i.hxx"
+
+#include "SMESHDS_Document.hxx"
+#include "SMESHDS_Group.hxx"
+#include "SMESH_topo.hxx"
+#include "SMESH_Group.hxx"
+
+#include CORBA_SERVER_HEADER(SMESH_Group)
+#include CORBA_SERVER_HEADER(SMESH_Filter)
+#include "SMESH_Filter_i.hxx"
+
+#include "Document_Reader.h"
+#include "DriverMED_W_SMESHDS_Mesh.h"
+#include "DriverMED_R_SMESHDS_Mesh.h"
+#include "DriverMED_R_SMESHDS_Document.h"
+#include "DriverUNV_R_SMESHDS_Document.h"
+#include "DriverDAT_R_SMESHDS_Document.h"
#include "SALOMEDS_Tool.hxx"
#include "SALOME_NamingService.hxx"
#include "Utils_SINGLETON.hxx"
#include "OpUtil.hxx"
-//#include <TopAbs_ShapeEnum.hxx>
+#include CORBA_CLIENT_HEADER(SALOME_ModuleCatalog)
#include "GEOM_Client.hxx"
+#include "Utils_ExceptHandlers.hxx"
#include <map>
-#include <fstream>
-#include <stdio.h>
-using namespace std;
-
-#define NUM_TMP_FILES 4
-
-// Tags definition
-long Tag_HypothesisRoot = 1;
-long Tag_AlgorithmsRoot = 2;
-long Tag_RefOnShape = 1;
-long Tag_RefOnAppliedHypothesis = 2;
-long Tag_RefOnAppliedAlgorithms = 3;
-
-long Tag_SubMeshOnVertex = 4;
-long Tag_SubMeshOnEdge = 5;
-long Tag_SubMeshOnFace = 6;
-long Tag_SubMeshOnSolid = 7;
-long Tag_SubMeshOnCompound = 8;
+#define NUM_TMP_FILES 2
+
+// Tags definition ===========================================================
+// Top level
+long Tag_HypothesisRoot = 1; // hypotheses root
+long Tag_AlgorithmsRoot = 2; // algorithms root
+// Mesh/Submesh
+long Tag_RefOnShape = 1; // references to shape
+long Tag_RefOnAppliedHypothesis = 2; // applied hypotheses root
+long Tag_RefOnAppliedAlgorithms = 3; // applied algorithms root
+// Mesh only
+long Tag_SubMeshOnVertex = 4; // sub-meshes roots by type
+long Tag_SubMeshOnEdge = 5; // ...
+long Tag_SubMeshOnFace = 6; // ...
+long Tag_SubMeshOnSolid = 7; // ...
+long Tag_SubMeshOnCompound = 8; // ...
+long Tag_NodeGroups = 9; // Group roots by type
+long Tag_EdgeGroups = 10; // ...
+long Tag_FaceGroups = 11; // ...
+long Tag_VolumeGroups = 12; // ...
+// ===========================================================================
+
+// Static variables definition
+CORBA::ORB_var SMESH_Gen_i::myOrb;
+PortableServer::POA_var SMESH_Gen_i::myPoa;
+SALOME_NamingService* SMESH_Gen_i::myNS = NULL;
+SALOME_LifeCycleCORBA* SMESH_Gen_i::myLCC = NULL;
//=============================================================================
/*!
- * default constructor: not for use
+ * FindMaxChildTag [ static internal ]
+ *
+ * Finds maximum child tag for the given object
*/
//=============================================================================
-SMESH_Gen_i::SMESH_Gen_i()
+static long FindMaxChildTag( SALOMEDS::SObject_ptr theSObject )
{
- MESSAGE("SMESH_Gen_i default constructor");
- // ****
+ long aTag = 0;
+ if ( !theSObject->_is_nil() ) {
+ SALOMEDS::Study_var aStudy = theSObject->GetStudy();
+ if ( !aStudy->_is_nil() ) {
+ SALOMEDS::ChildIterator_var anIter = aStudy->NewChildIterator( theSObject );
+ for ( ; anIter->More(); anIter->Next() ) {
+ long nTag = anIter->Value()->Tag();
+ if ( nTag > aTag )
+ aTag = nTag;
+ }
+ }
+ }
+ return aTag;
}
//=============================================================================
/*!
- * Standard constructor, used with Container.
+ * Get...Tag [ static ]
+ *
+ * Methods which determine SMESH data model structure
*/
//=============================================================================
-SMESH_Gen_i::SMESH_Gen_i(CORBA::ORB_ptr orb,
- PortableServer::POA_ptr poa,
- PortableServer::ObjectId * contId,
- const char *instanceName,
- const char *interfaceName):Engines_Component_i(orb, poa, contId,
- instanceName, interfaceName)
+long SMESH_Gen_i::GetHypothesisRootTag()
{
- MESSAGE("activate object");
- _thisObj = this;
- _id = _poa->activate_object(_thisObj);
-
- _ShapeReader = NULL;
-
+ return Tag_HypothesisRoot;
}
-//=============================================================================
-/*!
- * Standard destructor
- */
-//=============================================================================
-
-SMESH_Gen_i::~SMESH_Gen_i()
+long SMESH_Gen_i::GetAlgorithmsRootTag()
{
- MESSAGE("~SMESH_Gen_i");
- // ****
+ return Tag_AlgorithmsRoot;
}
-//=============================================================================
-/*!
- *
- */
-//=============================================================================
-
-SMESH::SMESH_Hypothesis_ptr SMESH_Gen_i::CreateHypothesis(const char *anHyp,
- CORBA::Long studyId) throw(SALOME::SALOME_Exception)
+long SMESH_Gen_i::GetRefOnShapeTag()
{
- MESSAGE("CreateHypothesis");
-
- // create a new hypothesis object servant
-
- SMESH_Hypothesis_i *myHypothesis_i = 0;
- try
- {
- myHypothesis_i = _hypothesisFactory_i.Create(anHyp, studyId, &_impl);
- }
- catch(SALOME_Exception & S_ex)
- {
- THROW_SALOME_CORBA_EXCEPTION(S_ex.what(), SALOME::BAD_PARAM);
- }
-
- // activate the CORBA servant of hypothesis
-
- SMESH::SMESH_Hypothesis_var hypothesis_i
- = SMESH::SMESH_Hypothesis::_narrow(myHypothesis_i->_this());
- return SMESH::SMESH_Hypothesis::_duplicate(hypothesis_i);
+ return Tag_RefOnShape;
}
-/**
- * CORBA implementation of SMESH_Gen::Init. See SMESH_Gen.idl.
- */
-SMESH::SMESH_Mesh_ptr SMESH_Gen_i::Init(GEOM::GEOM_Gen_ptr geomEngine,
- CORBA::Long studyId,
- GEOM::GEOM_Shape_ptr aShape) throw(SALOME::SALOME_Exception)
+long SMESH_Gen_i::GetRefOnAppliedHypothesisTag()
{
- return Init(geomEngine, studyId, aShape, -1);
+ return Tag_RefOnAppliedHypothesis;
}
-/**
- * This is NOT a CORBA implementation. Differ from the Init CORBA method
- * by allowing to specify the ID of the created mesh.
- */
-SMESH::SMESH_Mesh_ptr SMESH_Gen_i::Init(GEOM::GEOM_Gen_ptr geomEngine,
- CORBA::Long studyId, GEOM::GEOM_Shape_ptr aShape, int meshID)
- throw(SALOME::SALOME_Exception)
+long SMESH_Gen_i::GetRefOnAppliedAlgorithmsTag()
{
- MESSAGE("Init");
- // _narrow() duplicates the reference and checks the type
- GEOM::GEOM_Gen_var geom = GEOM::GEOM_Gen::_narrow(geomEngine);
- GEOM::GEOM_Shape_var myShape = GEOM::GEOM_Shape::_narrow(aShape);
-
- if (CORBA::is_nil(geom))
- THROW_SALOME_CORBA_EXCEPTION("bad geom reference", SALOME::BAD_PARAM);
- if (CORBA::is_nil(myShape))
- THROW_SALOME_CORBA_EXCEPTION("bad shape reference", SALOME::BAD_PARAM);
-
- // Get or create the GEOM_Client instance
-
- SMESH_Mesh_i *meshServant = 0;
- try
- {
- if (!_ShapeReader)
- _ShapeReader = new GEOM_Client();
- ASSERT(_ShapeReader);
+ return Tag_RefOnAppliedAlgorithms;
+}
- // explore main Shape, get local TopoDS_Shapes of all subShapes
- // SMESH_topo* myTopo = ExploreMainShape(geom, studyId, myShape);
+long SMESH_Gen_i::GetSubMeshOnVertexTag()
+{
+ return Tag_SubMeshOnVertex;
+}
- // Get studyContext_i, create it if it does'nt exist
+long SMESH_Gen_i::GetSubMeshOnEdgeTag()
+{
+ return Tag_SubMeshOnEdge;
+}
- if (_mapStudyContext_i.find(studyId) == _mapStudyContext_i.end())
- {
- _mapStudyContext_i[studyId] = new StudyContext_iStruct;
- }
- StudyContext_iStruct *myStudyContext = _mapStudyContext_i[studyId];
+long SMESH_Gen_i::GetSubMeshOnFaceTag()
+{
+ return Tag_SubMeshOnFace;
+}
- // create a new mesh object
- TopoDS_Shape myLocShape = _ShapeReader->GetShape(geom, myShape);
- SMESH_Mesh * meshImpl=_impl.Init(studyId, myLocShape, meshID);
+long SMESH_Gen_i::GetSubMeshOnSolidTag()
+{
+ return Tag_SubMeshOnSolid;
+}
- // create a new mesh object servant, store it in a map in study context
- meshServant = new SMESH_Mesh_i(this, geom, studyId, meshImpl);
- myStudyContext->mapMesh_i[meshServant->GetId()] = meshServant;
- }
- catch(SALOME_Exception & S_ex)
- {
- THROW_SALOME_CORBA_EXCEPTION(S_ex.what(), SALOME::BAD_PARAM);
- }
+long SMESH_Gen_i::GetSubMeshOnCompoundTag()
+{
+ return Tag_SubMeshOnCompound;
+}
- // activate the CORBA servant of Mesh
+long SMESH_Gen_i::GetNodeGroupsTag()
+{
+ return Tag_NodeGroups;
+}
- SMESH::SMESH_Mesh_var mesh
- = SMESH::SMESH_Mesh::_narrow(meshServant->_this());
+long SMESH_Gen_i::GetEdgeGroupsTag()
+{
+ return Tag_EdgeGroups;
+}
- meshServant->SetIor(mesh);
+long SMESH_Gen_i::GetFaceGroupsTag()
+{
+ return Tag_FaceGroups;
+}
- return SMESH::SMESH_Mesh::_duplicate(mesh);
+long SMESH_Gen_i::GetVolumeGroupsTag()
+{
+ return Tag_VolumeGroups;
}
//=============================================================================
/*!
- *
+ * GetServant [ static ]
+ *
+ * Get servant of the CORBA object
*/
//=============================================================================
-CORBA::Boolean SMESH_Gen_i::IsReadyToCompute(SMESH::SMESH_Mesh_ptr aMesh,
- GEOM::GEOM_Shape_ptr aShape) throw(SALOME::SALOME_Exception)
+PortableServer::ServantBase_var SMESH_Gen_i::GetServant( CORBA::Object_ptr theObject )
{
- MESSAGE("SMESH_Gen_i::IsReadyToCompute");
- return true;
+ if( CORBA::is_nil( theObject ) || CORBA::is_nil( GetPOA() ) )
+ return NULL;
+ try {
+ PortableServer::Servant aServant = GetPOA()->reference_to_servant( theObject );
+ return aServant;
+ }
+ catch (...) {
+ MESSAGE( "GetServant - Unknown exception was caught!!!" );
+ return NULL;
+ }
}
//=============================================================================
/*!
- *
+ * SObjectToObject [ static ]
+ *
+ * Get CORBA object corresponding to the SALOMEDS::SObject
*/
//=============================================================================
-SMESH::long_array *
- SMESH_Gen_i::GetSubShapesId(GEOM::GEOM_Gen_ptr geomEngine,
- CORBA::Long studyId,
- GEOM::GEOM_Shape_ptr mainShape,
- const SMESH::shape_array & listOfSubShape)throw(SALOME::SALOME_Exception)
+CORBA::Object_var SMESH_Gen_i::SObjectToObject( SALOMEDS::SObject_ptr theSObject )
{
- MESSAGE("SMESH_Gen_i::GetSubShapesId");
- SMESH::long_array_var shapesId = new SMESH::long_array;
- set < int >setId;
-
- GEOM::GEOM_Gen_var geom = GEOM::GEOM_Gen::_narrow(geomEngine);
- GEOM::GEOM_Shape_var myShape = GEOM::GEOM_Shape::_narrow(mainShape);
-
- if (CORBA::is_nil(geom))
- THROW_SALOME_CORBA_EXCEPTION("bad geom reference", SALOME::BAD_PARAM);
- if (CORBA::is_nil(myShape))
- THROW_SALOME_CORBA_EXCEPTION("bad shape reference", SALOME::BAD_PARAM);
-
- try
- {
- if (!_ShapeReader)
- _ShapeReader = new GEOM_Client();
- ASSERT(_ShapeReader);
- TopoDS_Shape myMainShape = _ShapeReader->GetShape(geom, myShape);
- TopTools_IndexedMapOfShape myIndexToShape;
- TopExp::MapShapes(myMainShape, myIndexToShape);
-
- for (unsigned int i = 0; i < listOfSubShape.length(); i++)
- {
- GEOM::GEOM_Shape_var aShape
- = GEOM::GEOM_Shape::_narrow(listOfSubShape[i]);
- if (CORBA::is_nil(aShape))
- THROW_SALOME_CORBA_EXCEPTION("bad shape reference",
- SALOME::BAD_PARAM);
- TopoDS_Shape locShape = _ShapeReader->GetShape(geom, aShape);
- for (TopExp_Explorer exp(locShape, TopAbs_FACE); exp.More();
- exp.Next())
- {
- const TopoDS_Face & F = TopoDS::Face(exp.Current());
- setId.insert(myIndexToShape.FindIndex(F));
- SCRUTE(myIndexToShape.FindIndex(F));
- }
- for (TopExp_Explorer exp(locShape, TopAbs_EDGE); exp.More();
- exp.Next())
- {
- const TopoDS_Edge & E = TopoDS::Edge(exp.Current());
- setId.insert(myIndexToShape.FindIndex(E));
- SCRUTE(myIndexToShape.FindIndex(E));
- }
- for (TopExp_Explorer exp(locShape, TopAbs_VERTEX); exp.More();
- exp.Next())
- {
- const TopoDS_Vertex & V = TopoDS::Vertex(exp.Current());
- setId.insert(myIndexToShape.FindIndex(V));
- SCRUTE(myIndexToShape.FindIndex(V));
- }
- }
- shapesId->length(setId.size());
- set < int >::iterator iind;
- int i = 0;
- for (iind = setId.begin(); iind != setId.end(); iind++)
- {
- SCRUTE((*iind));
- shapesId[i] = (*iind);
- SCRUTE(shapesId[i]);
- i++;
- }
- }
- catch(SALOME_Exception & S_ex)
- {
- THROW_SALOME_CORBA_EXCEPTION(S_ex.what(), SALOME::BAD_PARAM);
+ SALOMEDS::GenericAttribute_var anAttr;
+ CORBA::Object_var anObj;
+ if ( !theSObject->_is_nil() ) {
+ try {
+ if( theSObject->FindAttribute( anAttr, "AttributeIOR" ) ) {
+ SALOMEDS::AttributeIOR_var anIOR = SALOMEDS::AttributeIOR::_narrow( anAttr );
+ CORBA::String_var aValue = anIOR->Value();
+ if( strcmp( aValue, "" ) != 0 )
+ anObj = GetORB()->string_to_object( aValue );
}
-
- return shapesId._retn();
+ }
+ catch( ... ) {
+ MESSAGE( "SObjectToObject - Unknown exception was caught!!!" );
+ }
+ }
+ return anObj;
}
//=============================================================================
/*!
- *
+ * GetNS [ static ]
+ *
+ * Get SALOME_NamingService object
*/
//=============================================================================
-CORBA::Boolean SMESH_Gen_i::Compute(SMESH::SMESH_Mesh_ptr aMesh,
- GEOM::GEOM_Shape_ptr aShape) throw(SALOME::SALOME_Exception)
+SALOME_NamingService* SMESH_Gen_i::GetNS()
{
- MESSAGE("SMESH_Gen_i::Compute");
- GEOM::GEOM_Shape_var myShape = GEOM::GEOM_Shape::_narrow(aShape);
- if (CORBA::is_nil(myShape))
- THROW_SALOME_CORBA_EXCEPTION("bad shape reference", SALOME::BAD_PARAM);
-
- SMESH::SMESH_Mesh_var myMesh = SMESH::SMESH_Mesh::_narrow(aMesh);
- if (CORBA::is_nil(myMesh))
- THROW_SALOME_CORBA_EXCEPTION("bad Mesh reference", SALOME::BAD_PARAM);
-
- bool ret = false;
- try
- {
-
- // get study context from studyId given by CORBA mesh object
-
- int studyId = myMesh->GetStudyId();
- ASSERT(_mapStudyContext_i.find(studyId) != _mapStudyContext_i.end());
- StudyContext_iStruct *myStudyContext = _mapStudyContext_i[studyId];
-
- // get local Mesh_i object with Id and study context
-
- int meshId = myMesh->GetId();
- ASSERT(myStudyContext->mapMesh_i.find(meshId) !=
- myStudyContext->mapMesh_i.end());
- SMESH_Mesh_i *meshServant = myStudyContext->mapMesh_i[meshId];
- ASSERT(meshServant);
-
- // get local TopoDS_Shape
-
- GEOM::GEOM_Gen_var geom = meshServant->GetGeomEngine();
- TopoDS_Shape myLocShape = _ShapeReader->GetShape(geom, myShape);
+ if ( myNS == NULL ) {
+ myNS = SINGLETON_<SALOME_NamingService>::Instance();
+ ASSERT(SINGLETON_<SALOME_NamingService>::IsAlreadyExisting());
+ myNS->init_orb( GetORB() );
+ }
+ return myNS;
+}
- // implementation compute
+//=============================================================================
+/*!
+ * GetLCC [ static ]
+ *
+ * Get SALOME_LifeCycleCORBA object
+ */
+//=============================================================================
+SALOME_LifeCycleCORBA* SMESH_Gen_i::GetLCC() {
+ if ( myLCC == NULL ) {
+ myLCC = new SALOME_LifeCycleCORBA( GetNS() );
+ }
+ return myLCC;
+}
- ::SMESH_Mesh & myLocMesh = meshServant->GetImpl();
- ret = _impl.Compute(myLocMesh, myLocShape);
- }
- catch(SALOME_Exception & S_ex)
- {
- MESSAGE("catch exception " << S_ex.what());
- return false;
-// THROW_SALOME_CORBA_EXCEPTION(S_ex.what(), SALOME::BAD_PARAM);
- }
- return ret;
+//=============================================================================
+/*!
+ * GetGeomEngine [ static ]
+ *
+ * Get GEOM::GEOM_Gen reference
+ */
+//=============================================================================
+GEOM::GEOM_Gen_ptr SMESH_Gen_i::GetGeomEngine() {
+ GEOM::GEOM_Gen_var aGeomEngine =
+ GEOM::GEOM_Gen::_narrow( GetLCC()->FindOrLoad_Component("FactoryServer","GEOM") );
+ return aGeomEngine._retn();
}
//=============================================================================
/*!
- *
+ * SMESH_Gen_i::SMESH_Gen_i
+ *
+ * Default constructor: not for use
*/
//=============================================================================
-SALOMEDS::TMPFile * SMESH_Gen_i::Save(SALOMEDS::SComponent_ptr theComponent,
- const char *theURL, bool isMultiFile)
+SMESH_Gen_i::SMESH_Gen_i()
{
- MESSAGE("SMESH_Gen_i::SAVE");
- SALOMEDS::Study_var Study = theComponent->GetStudy();
- int studyId;
-
- // Declare a byte stream
- SALOMEDS::TMPFile_var aStreamFile;
-
- // Obtain a temporary dir
- TCollection_AsciiString tmpDir =
- (isMultiFile) ? TCollection_AsciiString((char *)theURL) :
- SALOMEDS_Tool::GetTmpDir();
-
- // Create a sequence of files processed
- SALOMEDS::ListOfFileNames_var aFileSeq = new SALOMEDS::ListOfFileNames;
- aFileSeq->length(NUM_TMP_FILES);
-
- TCollection_AsciiString aStudyName("");
-
- if (isMultiFile)
- aStudyName =
- (SALOMEDS_Tool::GetNameFromPath(theComponent->GetStudy()->URL()));
-
- // Set names of temporary files
- TCollection_AsciiString filename =
- aStudyName + TCollection_AsciiString("_SMESH.hdf");
- TCollection_AsciiString hypofile =
- aStudyName + TCollection_AsciiString("_SMESH_Hypo.txt");
- TCollection_AsciiString algofile =
- aStudyName + TCollection_AsciiString("_SMESH_Algo.txt");
- TCollection_AsciiString meshfile =
- aStudyName + TCollection_AsciiString("_SMESH_Mesh.med");
- aFileSeq[0] = CORBA::string_dup(filename.ToCString());
- aFileSeq[1] = CORBA::string_dup(hypofile.ToCString());
- aFileSeq[2] = CORBA::string_dup(algofile.ToCString());
- aFileSeq[3] = CORBA::string_dup(meshfile.ToCString());
- filename = tmpDir + filename;
- hypofile = tmpDir + hypofile;
- algofile = tmpDir + algofile;
- meshfile = tmpDir + meshfile;
-
- HDFfile *hdf_file;
- map < int, HDFgroup * >hdf_group, hdf_subgroup;
- map < int, HDFdataset * >hdf_dataset;
- FILE *destFile;
-
- SALOMEDS::ChildIterator_var itBig, it, itSM;
- SALOMEDS::SObject_var mySObject, myBranch, mySObjectChild;
- hdf_size size[1];
- int longueur, cmpt_ds = 0, cmpt_it;
- char *name_group, name_dataset[30], name_meshgroup[30];
- bool ok, _found;
- int cmpt_sm = 0, myTag;
-
-//************* HDF file creation
- hdf_file = new HDFfile(filename.ToCString());
- hdf_file->CreateOnDisk();
-//****************************
-
- itBig = Study->NewChildIterator(theComponent);
- SCRUTE(Tag_HypothesisRoot);
- SCRUTE(Tag_AlgorithmsRoot);
- for (; itBig->More(); itBig->Next())
- {
- SALOMEDS::SObject_var gotBranch = itBig->Value();
- SCRUTE(gotBranch->Name());
- SCRUTE(gotBranch->Tag());
- SCRUTE(gotBranch->GetID());
-
-//************branch 1 : hypothesis
- if (gotBranch->Tag() == Tag_HypothesisRoot)
- { //hypothesis = tag 1
- double length, maxElementsArea, maxElementsVolume;
- int numberOfSegments;
-
- destFile = fopen(hypofile.ToCString(), "w");
- it = Study->NewChildIterator(gotBranch);
- for (; it->More(); it->Next())
- {
- mySObject = it->Value();
- SALOMEDS::GenericAttribute_var anAttr;
- SALOMEDS::AttributeIOR_var anIOR;
- if (mySObject->FindAttribute(anAttr, "AttributeIOR"))
- {
- anIOR = SALOMEDS::AttributeIOR::_narrow(anAttr);
-
- SMESH::SMESH_Hypothesis_var myHyp =
- SMESH::SMESH_Hypothesis::_narrow(_orb->
- string_to_object(anIOR->Value()));
- SCRUTE(myHyp->GetName());
- fprintf(destFile, "%li\n", myHyp->GetId());
- fprintf(destFile, "%s\n", myHyp->GetName());
- if (strcmp(myHyp->GetName(), "LocalLength") == 0)
- {
- SMESH::SMESH_LocalLength_var LL =
- SMESH::SMESH_LocalLength::_narrow(myHyp);
- length = LL->GetLength();
- fprintf(destFile, "%f\n", length);
- }
- else if (strcmp(myHyp->GetName(), "NumberOfSegments") == 0)
- {
- SMESH::SMESH_NumberOfSegments_var NOS =
- SMESH::SMESH_NumberOfSegments::_narrow(myHyp);
- numberOfSegments = NOS->GetNumberOfSegments();
- fprintf(destFile, "%d\n", numberOfSegments);
- }
- else if (strcmp(myHyp->GetName(), "MaxElementArea") == 0)
- {
- SMESH::SMESH_MaxElementArea_var MEA =
- SMESH::SMESH_MaxElementArea::_narrow(myHyp);
- maxElementsArea = MEA->GetMaxElementArea();
- fprintf(destFile, "%f\n", maxElementsArea);
- }
- else if (strcmp(myHyp->GetName(), "MaxElementVolume") == 0)
- {
- SMESH::SMESH_MaxElementVolume_var MEV =
- SMESH::SMESH_MaxElementVolume::_narrow(myHyp);
- maxElementsVolume = MEV->GetMaxElementVolume();
- fprintf(destFile, "%f\n", maxElementsVolume);
- }
- }
- }
- fclose(destFile);
-
-//writes the file name in the hdf file
- longueur = hypofile.Length() + 1;
- name_group = "Hypothesis";
- //SCRUTE(name_group);
-
- size[0] = longueur;
- hdf_group[1] = new HDFgroup(name_group, hdf_file);
- hdf_group[1]->CreateOnDisk();
-
- hdf_dataset[cmpt_ds] =
- new HDFdataset(name_group, hdf_group[1], HDF_STRING, size, 1);
- hdf_dataset[cmpt_ds]->CreateOnDisk();
- hdf_dataset[cmpt_ds]->WriteOnDisk(hypofile.ToCString());
- hdf_dataset[cmpt_ds]->CloseOnDisk();
- cmpt_ds++;
-
- hdf_group[1]->CloseOnDisk();
- MESSAGE("End of Hypothesis Save");
-
- }
-//************branch 2 : algorithms
- else if (gotBranch->Tag() == Tag_AlgorithmsRoot)
- { //algos = tag 2
- destFile = fopen(algofile.ToCString(), "w");
- it = Study->NewChildIterator(gotBranch);
- for (; it->More(); it->Next())
- {
- mySObject = it->Value();
- SALOMEDS::GenericAttribute_var anAttr;
- SALOMEDS::AttributeIOR_var anIOR;
- if (mySObject->FindAttribute(anAttr, "AttributeIOR"))
- {
- anIOR = SALOMEDS::AttributeIOR::_narrow(anAttr);
- SMESH::SMESH_Algo_var myAlgo =
- SMESH::SMESH_Algo::_narrow(_orb->
- string_to_object(anIOR->Value()));
- SCRUTE(anIOR->Value());
- SCRUTE(myAlgo->_is_nil());
- fprintf(destFile, "%li\n", myAlgo->GetId());
- fprintf(destFile, "%s\n", myAlgo->GetName());
- }
- }
-
- fclose(destFile);
-
-//writes the file name in the hdf file
- longueur = algofile.Length() + 1;
- name_group = "Algorithms";
- //SCRUTE(name_group);
-
- size[0] = longueur;
- hdf_group[2] = new HDFgroup(name_group, hdf_file);
- hdf_group[2]->CreateOnDisk();
-
- hdf_dataset[cmpt_ds] =
- new HDFdataset(name_group, hdf_group[2], HDF_STRING, size, 1);
- hdf_dataset[cmpt_ds]->CreateOnDisk();
- hdf_dataset[cmpt_ds]->WriteOnDisk(algofile.ToCString());
- hdf_dataset[cmpt_ds]->CloseOnDisk();
- cmpt_ds++;
-
- hdf_group[2]->CloseOnDisk();
- MESSAGE("End of Algos Save");
-
- }
-//************branch 3 : meshes
- else if (gotBranch->Tag() >= 3)
- { //meshes = tag > 3
-
- SALOMEDS::GenericAttribute_var anAttr;
- SALOMEDS::AttributeIOR_var anIOR;
- if (gotBranch->FindAttribute(anAttr, "AttributeIOR"))
- {
- anIOR = SALOMEDS::AttributeIOR::_narrow(anAttr);
-
- SMESH::SMESH_Mesh_var myMesh =
- SMESH::SMESH_Mesh::_narrow(_orb->string_to_object(anIOR->
- Value()));
- studyId = myMesh->GetStudyId();
- SCRUTE(studyId);
-
- StudyContext_iStruct *myStudyContext =
- _mapStudyContext_i[studyId];
- int meshId = myMesh->GetId();
- SMESH_Mesh_i *meshServant = myStudyContext->mapMesh_i[meshId];
- ::SMESH_Mesh & myLocMesh = meshServant->GetImpl();
- SMESHDS_Mesh *mySMESHDSMesh = myLocMesh.GetMeshDS();
-
- SCRUTE(mySMESHDSMesh->NbNodes());
- if (mySMESHDSMesh->NbNodes() > 0)
- {
- //checks if the mesh is not empty
- Mesh_Writer *myWriter = SMESHDriver::GetMeshWriter("MED");
- myWriter->SetFile(meshfile.ToCString());
- myWriter->SetMesh(mySMESHDSMesh);
- myWriter->SetMeshId(gotBranch->Tag());
- myWriter->Add();
- }
- else
- meshfile = "No data";
-
- //********** opening of the HDF group
- sprintf(name_meshgroup, "Mesh %d", meshId);
- SCRUTE(name_meshgroup);
- hdf_group[gotBranch->Tag()] =
- new HDFgroup(name_meshgroup, hdf_file);
- hdf_group[gotBranch->Tag()]->CreateOnDisk();
- //**********
-
- //********** file where the data are stored
- longueur = strlen(meshfile.ToCString()) + 1;
- size[0] = longueur;
- strcpy(name_dataset, "Mesh data");
- hdf_dataset[cmpt_ds] =
- new HDFdataset(name_dataset, hdf_group[gotBranch->Tag()],
- HDF_STRING, size, 1);
- hdf_dataset[cmpt_ds]->CreateOnDisk();
- hdf_dataset[cmpt_ds]->WriteOnDisk(meshfile.ToCString());
- hdf_dataset[cmpt_ds]->CloseOnDisk();
- cmpt_ds++;
- //**********
-
- //********** ref on shape
- Standard_CString myRefOnObject = "";
- SALOMEDS::SObject_var myRef, myShape;
- _found = gotBranch->FindSubObject(Tag_RefOnShape, myRef);
- if (_found)
- {
- ok = myRef->ReferencedObject(myShape);
- myRefOnObject = myShape->GetID();
- SCRUTE(myRefOnObject);
-
- longueur = strlen(myRefOnObject) + 1;
- if (longueur > 1)
- {
- size[0] = longueur;
- strcpy(name_dataset, "Ref on shape");
- hdf_dataset[cmpt_ds] =
- new HDFdataset(name_dataset,
- hdf_group[gotBranch->Tag()], HDF_STRING, size, 1);
- hdf_dataset[cmpt_ds]->CreateOnDisk();
- hdf_dataset[cmpt_ds]->WriteOnDisk(myRefOnObject);
- hdf_dataset[cmpt_ds]->CloseOnDisk();
- cmpt_ds++;
-
- }
- }
- //**********
-
- //********** ref on applied hypothesis
- _found =
- gotBranch->FindSubObject(Tag_RefOnAppliedHypothesis,
- myBranch);
- if (_found)
- {
-
- strcpy(name_meshgroup, "Applied Hypothesis");
- hdf_subgroup[Tag_RefOnAppliedHypothesis] =
- new HDFgroup(name_meshgroup,
- hdf_group[gotBranch->Tag()]);
- hdf_subgroup[Tag_RefOnAppliedHypothesis]->CreateOnDisk();
-
- it = Study->NewChildIterator(myBranch);
- cmpt_it = 0;
- for (; it->More(); it->Next())
- {
- mySObject = it->Value();
- ok = mySObject->ReferencedObject(myRef);
- myRefOnObject = myRef->GetID();
-
- longueur = strlen(myRefOnObject) + 1;
- if (longueur > 1)
- {
- size[0] = longueur;
- sprintf(name_dataset, "Hyp %d", cmpt_it);
- hdf_dataset[cmpt_ds] =
- new HDFdataset(name_dataset,
- hdf_subgroup[Tag_RefOnAppliedHypothesis],
- HDF_STRING, size, 1);
- hdf_dataset[cmpt_ds]->CreateOnDisk();
- hdf_dataset[cmpt_ds]->WriteOnDisk(myRefOnObject);
- hdf_dataset[cmpt_ds]->CloseOnDisk();
- }
- cmpt_ds++;
- cmpt_it++;
- }
- hdf_subgroup[Tag_RefOnAppliedHypothesis]->CloseOnDisk();
- }
- //**********
-
- //********** ref on applied algorithms
- _found =
- gotBranch->FindSubObject(Tag_RefOnAppliedAlgorithms,
- myBranch);
- if (_found)
- {
-
- strcpy(name_meshgroup, "Applied Algorithms");
- hdf_subgroup[Tag_RefOnAppliedAlgorithms] =
- new HDFgroup(name_meshgroup,
- hdf_group[gotBranch->Tag()]);
- hdf_subgroup[Tag_RefOnAppliedAlgorithms]->CreateOnDisk();
-
- it = Study->NewChildIterator(myBranch);
- cmpt_it = 0;
- for (; it->More(); it->Next())
- {
- mySObject = it->Value();
- ok = mySObject->ReferencedObject(myRef);
- myRefOnObject = myRef->GetID();
-
- longueur = strlen(myRefOnObject) + 1;
- if (longueur > 1)
- {
- size[0] = longueur;
- sprintf(name_dataset, "Algo %d", cmpt_it);
- hdf_dataset[cmpt_ds] =
- new HDFdataset(name_dataset,
- hdf_subgroup[Tag_RefOnAppliedAlgorithms],
- HDF_STRING, size, 1);
- hdf_dataset[cmpt_ds]->CreateOnDisk();
- hdf_dataset[cmpt_ds]->WriteOnDisk(myRefOnObject);
- hdf_dataset[cmpt_ds]->CloseOnDisk();
- }
- cmpt_ds++;
- cmpt_it++;
- }
- hdf_subgroup[Tag_RefOnAppliedAlgorithms]->CloseOnDisk();
- }
- MESSAGE("end of algo applied");
- //**********
-
- //********** submeshes on subshapes
- int myLevel1Tag;
- for (int i = Tag_SubMeshOnVertex; i <= Tag_SubMeshOnCompound;
- i++)
- {
- _found = gotBranch->FindSubObject(i, myBranch);
- if (_found)
- {
- if (i == Tag_SubMeshOnVertex)
- strcpy(name_meshgroup, "SubMeshes On Vertex");
- else if (i == Tag_SubMeshOnEdge)
- strcpy(name_meshgroup, "SubMeshes On Edge");
- else if (i == Tag_SubMeshOnFace)
- strcpy(name_meshgroup, "SubMeshes On Face");
- else if (i == Tag_SubMeshOnSolid)
- strcpy(name_meshgroup, "SubMeshes On Solid");
- else if (i == Tag_SubMeshOnCompound)
- strcpy(name_meshgroup, "SubMeshes On Compound");
-
- cmpt_sm++;
- myLevel1Tag = 10 + cmpt_sm;
- hdf_subgroup[myLevel1Tag] =
- new HDFgroup(name_meshgroup,
- hdf_group[gotBranch->Tag()]);
- hdf_subgroup[myLevel1Tag]->CreateOnDisk();
-
- itSM = Study->NewChildIterator(myBranch);
- for (; itSM->More(); itSM->Next())
- { //Loop on all submeshes
- mySObject = itSM->Value();
- cmpt_sm++;
- myTag = 10 + cmpt_sm;
- mySObject->FindAttribute(anAttr, "AttributeIOR");
- anIOR = SALOMEDS::AttributeIOR::_narrow(anAttr);
- SMESH::SMESH_subMesh_var mySubMesh =
- SMESH::SMESH_subMesh::_narrow(_orb->
- string_to_object(anIOR->Value()));
-
- //sprintf(name_meshgroup,"SubMesh %d",myTag);
- sprintf(name_meshgroup, "SubMesh %ld",
- mySubMesh->GetId());
- SCRUTE(name_meshgroup);
-
- hdf_subgroup[myTag] =
- new HDFgroup(name_meshgroup,
- hdf_subgroup[myLevel1Tag]);
- hdf_subgroup[myTag]->CreateOnDisk();
-
- //********** ref on shape
- Standard_CString myRefOnObject = "";
- SALOMEDS::SObject_var myRef, myShape;
- bool _found2;
- _found2 =
- mySObject->FindSubObject(Tag_RefOnShape, myRef);
- if (_found2)
- {
- ok = myRef->ReferencedObject(myShape);
- myRefOnObject = myShape->GetID();
- SCRUTE(myRefOnObject);
-
- longueur = strlen(myRefOnObject) + 1;
- if (longueur > 1)
- {
- size[0] = longueur;
- strcpy(name_dataset, "Ref on shape");
- hdf_dataset[cmpt_ds] =
- new HDFdataset(name_dataset,
- hdf_subgroup[myTag], HDF_STRING, size,
- 1);
- hdf_dataset[cmpt_ds]->CreateOnDisk();
- hdf_dataset[cmpt_ds]->
- WriteOnDisk(myRefOnObject);
- hdf_dataset[cmpt_ds]->CloseOnDisk();
- cmpt_ds++;
- }
- }
- //**********
-
- //********** ref on applied hypothesis
- _found2 =
- mySObject->
- FindSubObject(Tag_RefOnAppliedHypothesis,
- myBranch);
- if (_found2)
- {
-
- strcpy(name_meshgroup, "Applied Hypothesis");
- cmpt_sm++;
- hdf_subgroup[10 + cmpt_sm] =
- new HDFgroup(name_meshgroup,
- hdf_subgroup[myTag]);
- hdf_subgroup[10 + cmpt_sm]->CreateOnDisk();
-
- it = Study->NewChildIterator(myBranch);
- cmpt_it = 0;
- for (; it->More(); it->Next())
- {
- mySObjectChild = it->Value();
- ok = mySObjectChild->
- ReferencedObject(myRef);
- myRefOnObject = myRef->GetID();
-
- longueur = strlen(myRefOnObject) + 1;
- if (longueur > 1)
- {
- size[0] = longueur;
- sprintf(name_dataset, "Hyp %d",
- cmpt_it);
- SCRUTE(cmpt_it);
- hdf_dataset[cmpt_ds] =
- new HDFdataset(name_dataset,
- hdf_subgroup[10 + cmpt_sm],
- HDF_STRING, size, 1);
- hdf_dataset[cmpt_ds]->CreateOnDisk();
- hdf_dataset[cmpt_ds]->
- WriteOnDisk(myRefOnObject);
- hdf_dataset[cmpt_ds]->CloseOnDisk();
- }
- cmpt_ds++;
- cmpt_it++;
- }
- hdf_subgroup[10 + cmpt_sm]->CloseOnDisk();
- }
- //**********
-
- //********** ref on applied algorithms
- _found2 =
- mySObject->
- FindSubObject(Tag_RefOnAppliedAlgorithms,
- myBranch);
- SCRUTE(_found2);
- if (_found2)
- {
-
- strcpy(name_meshgroup, "Applied Algorithms");
- cmpt_sm++;
- hdf_subgroup[10 + cmpt_sm] =
- new HDFgroup(name_meshgroup,
- hdf_subgroup[myTag]);
- hdf_subgroup[10 + cmpt_sm]->CreateOnDisk();
-
- it = Study->NewChildIterator(myBranch);
- cmpt_it = 0;
- for (; it->More(); it->Next())
- {
- mySObjectChild = it->Value();
- ok = mySObjectChild->
- ReferencedObject(myRef);
- myRefOnObject = myRef->GetID();
-
- longueur = strlen(myRefOnObject) + 1;
- if (longueur > 1)
- {
- size[0] = longueur;
- sprintf(name_dataset, "Algo %d",
- cmpt_it);
- hdf_dataset[cmpt_ds] =
- new HDFdataset(name_dataset,
- hdf_subgroup[10 + cmpt_sm],
- HDF_STRING, size, 1);
- hdf_dataset[cmpt_ds]->CreateOnDisk();
- hdf_dataset[cmpt_ds]->
- WriteOnDisk(myRefOnObject);
- hdf_dataset[cmpt_ds]->CloseOnDisk();
- }
- cmpt_ds++;
- cmpt_it++;
- }
- hdf_subgroup[10 + cmpt_sm]->CloseOnDisk();
- }
- //MESSAGE("end of algo applied");
- //**********
-
- hdf_subgroup[myTag]->CloseOnDisk();
- }
-
- hdf_subgroup[myLevel1Tag]->CloseOnDisk();
- }
-
- }
- //**********
-
- //********** closing of the HDF group
- hdf_group[gotBranch->Tag()]->CloseOnDisk();
- MESSAGE("End of Mesh Save");
- //**********
- }
- }
- MESSAGE("End of Meshes Save");
- }
-
- MESSAGE("hdf_file->CloseOnDisk()");
- hdf_file->CloseOnDisk();
-
- MESSAGE("delete hdf_file");
- delete hdf_file;
- hdf_file = 0;
+ MESSAGE( "SMESH_Gen_i::SMESH_Gen_i : default constructor" );
+}
- // Convert temporary files to stream
- MESSAGE("Convert temporary files to stream");
- aStreamFile =
- SALOMEDS_Tool::PutFilesToStream(tmpDir.ToCString(), aFileSeq.in(),
- isMultiFile);
+//=============================================================================
+/*!
+ * SMESH_Gen_i::SMESH_Gen_i
+ *
+ * Standard constructor, used with Container
+ */
+//=============================================================================
- // Remove temporary files and directory
- MESSAGE("Remove temporary files and directory");
- if (!isMultiFile)
- SALOMEDS_Tool::RemoveTemporaryFiles(tmpDir.ToCString(), aFileSeq.in(),
- true);
+SMESH_Gen_i::SMESH_Gen_i( CORBA::ORB_ptr orb,
+ PortableServer::POA_ptr poa,
+ PortableServer::ObjectId* contId,
+ const char* instanceName,
+ const char* interfaceName )
+ : Engines_Component_i( orb, poa, contId, instanceName, interfaceName )
+{
+ MESSAGE( "SMESH_Gen_i::SMESH_Gen_i : standard constructor" );
+
+ myOrb = CORBA::ORB::_duplicate(orb);
+ myPoa = PortableServer::POA::_duplicate(poa);
+
+ _thisObj = this ;
+ _id = myPoa->activate_object( _thisObj );
+
+ myShapeReader = NULL; // shape reader
+}
- MESSAGE("End SMESH_Gen_i::Save");
+//=============================================================================
+/*!
+ * SMESH_Gen_i::~SMESH_Gen_i
+ *
+ * Destructor
+ */
+//=============================================================================
- return aStreamFile._retn();
+SMESH_Gen_i::~SMESH_Gen_i()
+{
+ MESSAGE( "SMESH_Gen_i::~SMESH_Gen_i" );
+
+ // delete hypothesis creators
+ map<string, GenericHypothesisCreator_i*>::iterator itHyp;
+ for (itHyp = myHypCreatorMap.begin(); itHyp != myHypCreatorMap.end(); itHyp++)
+ {
+ delete (*itHyp).second;
+ }
+ myHypCreatorMap.clear();
+
+ // Clear study contexts data
+ map<int, StudyContext*>::iterator it;
+ for ( it = myStudyContextMap.begin(); it != myStudyContextMap.end(); ++it ) {
+ delete it->second;
+ }
+ myStudyContextMap.clear();
+ // delete shape reader
+ if ( !myShapeReader )
+ delete myShapeReader;
}
+
+//=============================================================================
+/*!
+ * SMESH_Gen_i::CreateFilterManager
+ *
+ * Create filter manager
+ */
+//=============================================================================
-SALOMEDS::TMPFile *
- SMESH_Gen_i::SaveASCII(SALOMEDS::SComponent_ptr theComponent,
- const char *theURL, bool isMultiFile)
+SMESH::FilterManager_ptr SMESH_Gen_i::CreateFilterManager()
{
- SALOMEDS::TMPFile_var aStreamFile = Save(theComponent, theURL, isMultiFile);
- return aStreamFile._retn();
+ SMESH::FilterManager_i* aFilter = new SMESH::FilterManager_i();
+ SMESH::FilterManager_var anObj = aFilter->_this();
+ return anObj._retn();
}
-void SMESH_Gen_i::loadHypothesis(char * name, HDFfile * hdf_file,
- char * hypofile, int studyId)
+//=============================================================================
+/*!
+ * SMESH_Gen_i::createHypothesis
+ *
+ * Create hypothesis of given type
+ */
+//=============================================================================
+SMESH::SMESH_Hypothesis_ptr SMESH_Gen_i::createHypothesis(const char* theHypName,
+ const char* theLibName)
+ throw (SALOME::SALOME_Exception)
{
- char name_of_group[HDF_NAME_MAX_LEN + 1];
- char objectId[10];
-
- HDFgroup * hdfGroup = new HDFgroup(name, hdf_file);
- hdfGroup->OpenOnDisk();
-
- hdfGroup->InternalObjectIndentify(0, name_of_group);
- HDFdataset * dataset = new HDFdataset(name_of_group, hdfGroup);
- dataset->OpenOnDisk();
- char *name_of_file = new char[dataset->GetSize()];
- dataset->ReadFromDisk(name_of_file);
- SCRUTE(name_of_file);
- dataset->CloseOnDisk();
- hdfGroup->CloseOnDisk();
- delete[]name_of_file;
-
- ifstream loadedFile(hypofile);
- while (!loadedFile.eof())
- {
- int hypothesisID;
- string hypothesisName;
- loadedFile >> hypothesisID;
- loadedFile >> hypothesisName;
- if(hypothesisName.length()==0) break;
- SMESH_Hypothesis_i * corbaHyp =
- _hypothesisFactory_i.Create(hypothesisName.c_str(), studyId, &_impl);
- SMESH_Hypothesis * localHyp = corbaHyp->getImpl();
- localHyp->SetID(hypothesisID);
- localHyp->LoadFrom(loadedFile);
-
- SMESH::SMESH_Hypothesis_var varHyp = corbaHyp->_this();
- string iorString = _orb->object_to_string(varHyp);
- sprintf(objectId, "%ld", varHyp->GetId());
- _SMESHCorbaObj[string("Hypo_") + string(objectId)] =
- iorString;
- }
- MESSAGE("End of Hypos Load");
+ Unexpect aCatch(SALOME_SalomeException);
+ MESSAGE( "Create Hypothesis <" << theHypName << "> from " << theLibName);
+
+ // get study context
+ StudyContext* myStudyContext = GetCurrentStudyContext();
+
+ // create a new hypothesis object servant
+ SMESH_Hypothesis_i* myHypothesis_i = 0;
+ SMESH::SMESH_Hypothesis_var hypothesis_i;
+
+ try
+ {
+ // check, if creator for this hypothesis type already exists
+ if (myHypCreatorMap.find(string(theHypName)) == myHypCreatorMap.end())
+ {
+ // load plugin library
+ MESSAGE("Loading server meshers plugin library ...");
+ void* libHandle = dlopen (theLibName, RTLD_LAZY);
+ if (!libHandle)
+ {
+ // report any error, if occured
+ const char* anError = dlerror();
+ throw(SALOME_Exception(anError));
+ }
+
+ // get method, returning hypothesis creator
+ MESSAGE("Find GetHypothesisCreator() method ...");
+ typedef GenericHypothesisCreator_i* (*GetHypothesisCreator)(const char* theHypName);
+ GetHypothesisCreator procHandle =
+ (GetHypothesisCreator)dlsym( libHandle, "GetHypothesisCreator" );
+ if (!procHandle)
+ {
+ throw(SALOME_Exception(LOCALIZED("bad hypothesis plugin library")));
+ dlclose(libHandle);
+ }
+
+ // get hypothesis creator
+ MESSAGE("Get Hypothesis Creator for " << theHypName);
+ GenericHypothesisCreator_i* aCreator = procHandle(theHypName);
+ if (!aCreator)
+ {
+ throw(SALOME_Exception(LOCALIZED("no such a hypothesis in this plugin")));
+ }
+
+ // map hypothesis creator to a hypothesis name
+ myHypCreatorMap[string(theHypName)] = aCreator;
+ }
+
+ // create a new hypothesis object, store its ref. in studyContext
+ MESSAGE("Create Hypothesis " << theHypName);
+ myHypothesis_i =
+ myHypCreatorMap[string(theHypName)]->Create
+ (myPoa, myCurrentStudy->StudyId(), &myGen);
+ myHypothesis_i->SetLibName(theLibName); // for persistency assurance
+ }
+ catch (SALOME_Exception& S_ex)
+ {
+ THROW_SALOME_CORBA_EXCEPTION(S_ex.what(), SALOME::BAD_PARAM);
+ }
+
+ if (!myHypothesis_i)
+ return hypothesis_i._retn();
+
+ // activate the CORBA servant of hypothesis
+ hypothesis_i = SMESH::SMESH_Hypothesis::_narrow( myHypothesis_i->_this() );
+ string iorString = GetORB()->object_to_string( hypothesis_i );
+ int nextId = myStudyContext->addObject( iorString );
+ MESSAGE( "Add hypo to map with id = "<< nextId << " and IOR = " << iorString.c_str() );
+
+ return hypothesis_i._retn();
}
-
-void SMESH_Gen_i::loadAlgorithms(char * name, HDFfile * hdf_file,
- char* algofile, int studyId)
+
+//=============================================================================
+/*!
+ * SMESH_Gen_i::createMesh
+ *
+ * Create empty mesh on shape
+ */
+//=============================================================================
+SMESH::SMESH_Mesh_ptr SMESH_Gen_i::createMesh()
+ throw ( SALOME::SALOME_Exception )
{
- char name_of_group[HDF_NAME_MAX_LEN + 1];
- char objectId[10];
- HDFgroup * hdfGroup = new HDFgroup(name, hdf_file);
- hdfGroup->OpenOnDisk();
-
- hdfGroup->InternalObjectIndentify(0, name_of_group);
- HDFdataset * dataset =
- new HDFdataset(name_of_group, hdfGroup);
- dataset->OpenOnDisk();
-
- char *name_of_file = new char[dataset->GetSize()];
- dataset->ReadFromDisk(name_of_file);
- dataset->CloseOnDisk();
- hdfGroup->CloseOnDisk();
- delete[]name_of_file;
-
- char * aLine = new char[100];
- FILE * loadedFile = fopen(algofile, "r");
- while (!feof(loadedFile))
- {
- int hypothesisID;
- fscanf(loadedFile, "%i", &hypothesisID);
- fscanf(loadedFile, "%s\n", aLine);
- //SCRUTE(aLine);
- if (strcmp(aLine, "") != 0)
- {
- SMESH_Hypothesis_i * corbaHyp =
- _hypothesisFactory_i.Create(aLine, studyId, &_impl);
- SMESH_Hypothesis * localHyp = corbaHyp->getImpl();
- localHyp->SetID(hypothesisID);
-
- SMESH::SMESH_Hypothesis_var myHyp = corbaHyp->_this();
-
- SMESH::SMESH_Algo_var myAlgo =
- SMESH::SMESH_Algo::_narrow(myHyp);
- string iorString = _orb->object_to_string(myAlgo);
- sprintf(objectId, "%ld", myAlgo->GetId());
- _SMESHCorbaObj[string("Hypo_") + string(objectId)] =
- iorString;
- }
- }
- fclose(loadedFile);
- delete[]aLine;
- aLine = 0;
- MESSAGE("End of Algos Load");
+ Unexpect aCatch(SALOME_SalomeException);
+ MESSAGE( "SMESH_Gen_i::createMesh" );
+
+ // get current study
+ StudyContext* myStudyContext = GetCurrentStudyContext();
+
+ // Get or create the GEOM_Client instance
+ try {
+ // create a new mesh object servant, store it in a map in study context
+ SMESH_Mesh_i* meshServant = new SMESH_Mesh_i( GetPOA(),
+ this,
+ myCurrentStudy->StudyId() );
+ // create a new mesh object
+ meshServant->SetImpl( myGen.CreateMesh( myCurrentStudy->StudyId() ) );
+
+ // activate the CORBA servant of Mesh
+ SMESH::SMESH_Mesh_var mesh = meshServant->_this();
+ string iorString = GetORB()->object_to_string( mesh );
+ int nextId = myStudyContext->addObject( iorString );
+ MESSAGE( "Add mesh to map with id = "<< nextId << " and IOR = " << iorString.c_str() );
+ return mesh._retn();
+ }
+ catch (SALOME_Exception& S_ex) {
+ THROW_SALOME_CORBA_EXCEPTION( S_ex.what(), SALOME::BAD_PARAM );
+ }
+ return SMESH::SMESH_Mesh::_nil();
}
-/**
- * @param hdfGroupMeshId The group where to read the hypothesis
- * @param _found ???
- * @param Study The study where to create the hypothesis
- * @param myNewMesh The mesh on which the hypothesis is applied
- * @param aShape The shape with which this mesh is linked
+//=============================================================================
+/*!
+ * SMESH_Gen_i::GetShapeReader
+ *
+ * Get shape reader
*/
-void SMESH_Gen_i::loadAppliedHypothesis(HDFgroup * hdfGroupMeshId,
- bool _found, SALOMEDS::Study_var Study, SMESH::SMESH_Mesh_var myNewMesh,
- GEOM::GEOM_Shape_var aShape)
+//=============================================================================
+GEOM_Client* SMESH_Gen_i::GetShapeReader()
{
- HDFgroup * hdf_subgroup = new HDFgroup("Applied Hypothesis", hdfGroupMeshId);
- hdf_subgroup->OpenOnDisk();
- int nb_datasets = hdf_subgroup->nInternalObjects();
- char name_dataset[10];
-
- for (int j = 0; j < nb_datasets; j++)
- {
- sprintf(name_dataset, "Hyp %d", j);
- HDFdataset * hdf_dataset = new HDFdataset(name_dataset, hdf_subgroup);
- hdf_dataset->OpenOnDisk();
-
- char *refFromFile = new char[hdf_dataset->GetSize()];
- hdf_dataset->ReadFromDisk(refFromFile);
- hdf_dataset->CloseOnDisk();
- delete hdf_dataset;
-
- if (_found)
- {
- SALOMEDS::SObject_var HypSO =
- Study->FindObjectID(refFromFile);
- if (!CORBA::is_nil(HypSO))
- {
- SALOMEDS::GenericAttribute_var anAttr;
- HypSO->FindAttribute(anAttr, "AttributeIOR");
- SALOMEDS::AttributeIOR_var anIOR =
- SALOMEDS::AttributeIOR::_narrow(anAttr);
- if (!CORBA::is_nil(anIOR))
- {
- char *HypIOR = anIOR->Value();
- SMESH::SMESH_Hypothesis_var anHyp =
- SMESH::SMESH_Hypothesis::_narrow(_orb->
- string_to_object(HypIOR));
- if (!CORBA::is_nil(anHyp))
- {
- myNewMesh->AddHypothesis(aShape, anHyp);
- MESSAGE("Hypothesis added ...");
- }
- }
- }
- }
- }
- hdf_subgroup->CloseOnDisk();
+ // create shape reader if necessary
+ if ( !myShapeReader )
+ myShapeReader = new GEOM_Client(GetContainerRef());
+ ASSERT( myShapeReader );
+ return myShapeReader;
}
-/**
- * @param hdfGroupMeshId The group where to read the hypothesis
- * @param _found ???
- * @param Study The study where to create the hypothesis
- * @param myNewMesh The mesh on which the hypothesis is applied
- * @param aShape The shape with which this mesh is linked
+//=============================================================================
+/*!
+ * SMESH_Gen_i::SetCurrentStudy
+ *
+ * Set current study
*/
-void SMESH_Gen_i::loadAppliedAlgorithms(HDFgroup * hdfGroupMeshId,
- bool _found, SALOMEDS::Study_var Study, SMESH::SMESH_Mesh_var myNewMesh,
- GEOM::GEOM_Shape_var aShape)
-{
- HDFgroup * hdf_subgroup = new HDFgroup("Applied Algorithms", hdfGroupMeshId);
- hdf_subgroup->OpenOnDisk();
+//=============================================================================
- int nb_datasets = hdf_subgroup->nInternalObjects();
- SCRUTE(nb_datasets);
- char name_dataset[10];
-
- for (int j = 0; j < nb_datasets; j++)
- {
- sprintf(name_dataset, "Algo %d", j);
- HDFdataset * dataset =
- new HDFdataset(name_dataset, hdf_subgroup);
- dataset->OpenOnDisk();
-
- char *refFromFile = new char[dataset->GetSize()];
- dataset->ReadFromDisk(refFromFile);
- dataset->CloseOnDisk();
-
- if (_found)
- {
- SALOMEDS::SObject_var AlgoSO =
- Study->FindObjectID(refFromFile);
- if (!CORBA::is_nil(AlgoSO))
- {
- SALOMEDS::GenericAttribute_var anAttr;
- AlgoSO->FindAttribute(anAttr, "AttributeIOR");
- SALOMEDS::AttributeIOR_var anIOR =
- SALOMEDS::AttributeIOR::_narrow(anAttr);
- if (!CORBA::is_nil(anIOR))
- {
- char *AlgoIOR = anIOR->Value();
- //SCRUTE(AlgoIOR);
- SMESH::SMESH_Hypothesis_var myHyp =
- SMESH::SMESH_Hypothesis::_narrow(_orb->
- string_to_object(AlgoIOR));
- SMESH::SMESH_Algo_var anAlgo =
- SMESH::SMESH_Algo::_narrow(myHyp);
-
- if (!CORBA::is_nil(anAlgo))
- {
- myNewMesh->AddHypothesis(aShape, anAlgo); //essayer avec _SMESHCorbaObj
- MESSAGE("Algorithms added ...");
- }
- }
- }
- }
- }
- hdf_subgroup->CloseOnDisk();
+void SMESH_Gen_i::SetCurrentStudy( SALOMEDS::Study_ptr theStudy )
+{
+ MESSAGE( "SMESH_Gen_i::SetCurrentStudy" );
+ myCurrentStudy = SALOMEDS::Study::_duplicate( theStudy );
+ // create study context, if it doesn't exist and set current study
+ int studyId = myCurrentStudy->StudyId();
+ MESSAGE( "SMESH_Gen_i::SetCurrentStudy: study Id = " << studyId );
+ if ( myStudyContextMap.find( studyId ) == myStudyContextMap.end() ) {
+ myStudyContextMap[ studyId ] = new StudyContext;
+ }
+ // set current study for geom engine
+ if ( !CORBA::is_nil( GetGeomEngine() ) )
+ GetGeomEngine()->GetCurrentStudy( myCurrentStudy->StudyId() );
}
-/**
- * @param hdfGroupMeshId The group where to read the hypothesis
- * @param msgname ???
- * @param Study The study where to create the hypothesis
- * @param myNewMesh The mesh on which the hypothesis is applied
+//=============================================================================
+/*!
+ * SMESH_Gen_i::GetCurrentStudy
+ *
+ * Get current study
*/
-void SMESH_Gen_i::loadSubMeshes(HDFgroup * hdfGroupMeshId, char * msgname,
- SALOMEDS::Study_var Study, SMESH::SMESH_Mesh_var myNewMesh)
+//=============================================================================
+
+SALOMEDS::Study_ptr SMESH_Gen_i::GetCurrentStudy()
{
- MESSAGE("SMESH_Gen_i::loadSubMeshes");
- HDFgroup * hdf_subgroupmyLevel1Tag = new HDFgroup(msgname, hdfGroupMeshId);
- hdf_subgroupmyLevel1Tag->OpenOnDisk();
+ MESSAGE( "SMESH_Gen_i::GetCurrentStudy: study Id = " << myCurrentStudy->StudyId() );
+ return SALOMEDS::Study::_duplicate( myCurrentStudy );
+}
- int nb_submeshes = hdf_subgroupmyLevel1Tag->nInternalObjects();
- char name_meshgroup[30];
- //SCRUTE(nb_submeshes);
+//=============================================================================
+/*!
+ * SMESH_Gen_i::GetCurrentStudyContext
+ *
+ * Get current study context
+ */
+//=============================================================================
+StudyContext* SMESH_Gen_i::GetCurrentStudyContext()
+{
+ ASSERT( !CORBA::is_nil( myCurrentStudy ) )
+ ASSERT( myStudyContextMap.find( myCurrentStudy->StudyId() ) != myStudyContextMap.end() );
+ return myStudyContextMap[ myCurrentStudy->StudyId() ];
+}
- for (int j = 0; j < nb_submeshes; j++)
- {
- //cmpt_sm++;
- //myTag = 10 + cmpt_sm;
- hdf_subgroupmyLevel1Tag->InternalObjectIndentify(j, name_meshgroup);
-
- HDFgroup * hdf_subgroupmyTag = new HDFgroup(name_meshgroup,
- hdf_subgroupmyLevel1Tag);
- hdf_subgroupmyTag->OpenOnDisk();
- int subMeshId = atoi((string(name_meshgroup).substr(8, 18)).c_str());
-
- MESSAGE("Ref on shape");
- //********** ref on shape
- HDFdataset * hdf_dataset =
- new HDFdataset("Ref on shape", hdf_subgroupmyTag);
- hdf_dataset->OpenOnDisk();
-
- char *refFromFile = new char[hdf_dataset->GetSize()];
- hdf_dataset->ReadFromDisk(refFromFile);
- hdf_dataset->CloseOnDisk();
-
- bool _found3 = false;
- SALOMEDS::SObject_var GSO = Study->FindObjectID(refFromFile);
- SMESH::SMESH_subMesh_var aSubMesh;
- GEOM::GEOM_Shape_var aSubShape;
-
- if (!CORBA::is_nil(GSO))
- {
- SALOMEDS::GenericAttribute_var anAttr;
- GSO->FindAttribute(anAttr, "AttributeIOR");
- SALOMEDS::AttributeIOR_var anIOR =
- SALOMEDS::AttributeIOR::_narrow(anAttr);
-
- char *SubShapeIOR = anIOR->Value();
- aSubShape =
- GEOM::GEOM_Shape::_narrow(_orb-> string_to_object(SubShapeIOR));
-
- if (!CORBA::is_nil(aSubShape))
- {
- aSubMesh = myNewMesh->GetElementsOnShape(aSubShape);
- string iorString = _orb->object_to_string(aSubMesh);
- char objectId[10];
- sprintf(objectId, "%d", subMeshId);
- _SMESHCorbaObj[string("SubMesh_") + string(objectId)] =
- iorString;
- _found3 = true;
- }
- }
+//=============================================================================
+/*!
+ * SMESH_Gen_i::CreateHypothesis
+ *
+ * Create hypothesis/algorothm of given type and publish it in the study
+ */
+//=============================================================================
- int nb_subgroup = hdf_subgroupmyTag->nInternalObjects();
- SCRUTE(nb_subgroup);
- char sgname[HDF_NAME_MAX_LEN + 1];
- for (int k = 0; k < nb_subgroup; k++)
- {
- hdf_subgroupmyTag->InternalObjectIndentify(k, sgname);
- if (strcmp(sgname, "Ref on shape") == 0)
- {
- //nothing
- }
- else if (strcmp(sgname, "Applied Hypothesis") == 0)
- {
- //********** ref on applied hypothesis
- MESSAGE("Applied Hypothesis");
- strcpy(name_meshgroup, "Applied Hypothesis");
- //cmpt_sm++;
- HDFgroup * hdf_subgroup10cmpt_sm = new HDFgroup(name_meshgroup,
- hdf_subgroupmyTag);
-
- hdf_subgroup10cmpt_sm->OpenOnDisk();
- int nb_datasets = hdf_subgroup10cmpt_sm->nInternalObjects();
- // SCRUTE(nb_datasets);
-
- char name_dataset[30];
- for (int l = 0; l < nb_datasets; l++)
- {
- sprintf(name_dataset, "Hyp %d", l);
- HDFdataset * hdf_datasetcmpt_ds =
- new HDFdataset(name_dataset, hdf_subgroup10cmpt_sm);
- hdf_datasetcmpt_ds->OpenOnDisk();
- int size = hdf_datasetcmpt_ds->GetSize();
-
- char *refFromFile = new char[size];
- hdf_datasetcmpt_ds->ReadFromDisk(refFromFile);
- hdf_datasetcmpt_ds->CloseOnDisk();
- //cmpt_ds++;
-
- if (_found3)
- {
- SALOMEDS::SObject_var HypSO =
- Study->FindObjectID(refFromFile);
- if (!CORBA::is_nil(HypSO))
- {
- SALOMEDS::GenericAttribute_var anAttr;
- SALOMEDS::AttributeIOR_var anIOR;
- HypSO->FindAttribute(anAttr, "AttributeIOR");
- anIOR = SALOMEDS::AttributeIOR:: _narrow(anAttr);
- if (!CORBA::is_nil(anIOR))
- {
- char *HypIOR = anIOR->Value();
- SMESH::SMESH_Hypothesis_var anHyp =
- SMESH::SMESH_Hypothesis::_narrow(_orb->
- string_to_object(HypIOR));
- if (!CORBA::is_nil(anHyp))
- {
- SMESH::SMESH_Mesh_var aMesh =
- aSubMesh->GetFather();
- aMesh->AddHypothesis(aSubShape, anHyp); //essayer avec _SMESHCorbaObj
- MESSAGE("Hypothesis added ...");
- }
- }
- }
- }
- }
- }
- else if (strcmp(sgname, "Applied Algorithms") == 0)
- {
- //********** ref on applied algorithms
- MESSAGE("Applied Algorithms");
- strcpy(name_meshgroup, "Applied Algorithms");
- //cmpt_sm++;
- HDFgroup * hdf_subgroup10cmpt_sm = new HDFgroup(name_meshgroup,
- hdf_subgroupmyTag);
- hdf_subgroup10cmpt_sm->OpenOnDisk();
- int nb_datasets = hdf_subgroup10cmpt_sm->nInternalObjects();
- SCRUTE(nb_datasets);
-
- char name_dataset[30];
- for (int l = 0; l < nb_datasets; l++)
- {
- sprintf(name_dataset, "Algo %d", l);
- HDFdataset * hdf_datasetcmpt_ds = new HDFdataset(
- name_dataset, hdf_subgroup10cmpt_sm);
- hdf_datasetcmpt_ds->OpenOnDisk();
- int size = hdf_datasetcmpt_ds->GetSize();
-
- char *refFromFile = new char[size];
- hdf_datasetcmpt_ds->ReadFromDisk(refFromFile);
- hdf_datasetcmpt_ds->CloseOnDisk();
- delete hdf_datasetcmpt_ds;
- //cmpt_ds++;
-
- if (_found3)
- {
- SALOMEDS::SObject_var AlgoSO =
- Study->FindObjectID(refFromFile);
- if (!CORBA::is_nil(AlgoSO))
- {
- SALOMEDS::GenericAttribute_var anAttr;
- SALOMEDS::AttributeIOR_var anIOR;
- AlgoSO->FindAttribute(anAttr, "AttributeIOR");
- anIOR = SALOMEDS::AttributeIOR::_narrow(anAttr);
- if (!CORBA::is_nil(anIOR))
- {
- char *AlgoIOR = anIOR->Value();
- //SCRUTE(AlgoIOR);
- SMESH::SMESH_Hypothesis_var myHyp =
- SMESH::SMESH_Hypothesis::_narrow(_orb->
- string_to_object(AlgoIOR));
- SMESH::SMESH_Algo_var anAlgo =
- SMESH::SMESH_Algo::_narrow(myHyp);
- //SMESH::SMESH_Algo_var anAlgo = SMESH::SMESH_Algo::_narrow(_orb->string_to_object(AlgoIOR));
- if (!CORBA::is_nil(anAlgo))
- {
- SMESH::SMESH_Mesh_var aMesh =
- aSubMesh->GetFather();
- aMesh->AddHypothesis(aSubShape, anAlgo); //essayer avec _SMESHCorbaObj
- MESSAGE("Algorithms added ...");
- }
- }
- }
- }
- }
- }
- }
- hdf_subgroupmyTag->CloseOnDisk();
- }
- hdf_subgroupmyLevel1Tag->CloseOnDisk();
+SMESH::SMESH_Hypothesis_ptr SMESH_Gen_i::CreateHypothesis( const char* theHypName,
+ const char* theLibName )
+ throw ( SALOME::SALOME_Exception )
+{
+ Unexpect aCatch(SALOME_SalomeException);
+ ASSERT( !CORBA::is_nil( myCurrentStudy ) );
+ // Create hypothesis/algorithm
+ SMESH::SMESH_Hypothesis_var hyp = this->createHypothesis( theHypName, theLibName );
+
+ // Publish hypothesis/algorithm in the study
+ if ( this->CanPublishInStudy( hyp ) ) {
+ this->PublishInStudy( myCurrentStudy, SALOMEDS::SObject::_nil(), hyp, "" );
+ }
+ return hyp._retn();
}
+
+//=============================================================================
+/*!
+ * SMESH_Gen_i::CreateMesh
+ *
+ * Create empty mesh on a shape and publish it in the study
+ */
+//=============================================================================
-GEOM::GEOM_Gen_var SMESH_Gen_i::getGeomEngine()
+SMESH::SMESH_Mesh_ptr SMESH_Gen_i::CreateMesh( GEOM::GEOM_Shape_ptr theShape )
+ throw ( SALOME::SALOME_Exception )
{
- MESSAGE("SMESH_Gen_i::getGeomEngine");
- SALOME_NamingService *_NS = SINGLETON_ < SALOME_NamingService >::Instance();
- ASSERT(SINGLETON_ < SALOME_NamingService >::IsAlreadyExisting());
- _NS->init_orb(_orb);
- SALOME_LifeCycleCORBA *myEnginesLifeCycle = new SALOME_LifeCycleCORBA(_NS);
- Engines::Component_var geomEngine =
- myEnginesLifeCycle->FindOrLoad_Component("FactoryServer", "GEOM");
- GEOM::GEOM_Gen_var myGeomEngine = GEOM::GEOM_Gen::_narrow(geomEngine);
- return myGeomEngine;
+ Unexpect aCatch(SALOME_SalomeException);
+ MESSAGE( "SMESH_Gen_i::CreateMesh" );
+ ASSERT( !CORBA::is_nil( myCurrentStudy ) );
+ // create mesh
+ SMESH::SMESH_Mesh_var mesh = this->createMesh();
+ // publish mesh in the study
+ if ( this->CanPublishInStudy( mesh ) ) {
+ this->PublishInStudy( myCurrentStudy, SALOMEDS::SObject::_nil(), mesh.in(), "" );
+ }
+ // set shape
+ SMESH_Mesh_i* meshServant = dynamic_cast<SMESH_Mesh_i*>( GetServant( mesh ).in() );
+ ASSERT( meshServant );
+ meshServant->SetShape( theShape );
+ return mesh._retn();
}
+
+//=============================================================================
+/*!
+ * SMESH_Gen_i::CreateMeshFromMED
+ *
+ * Create mesh and import data from MED file
+ */
+//=============================================================================
-GEOM::GEOM_Shape_var SMESH_Gen_i::getShape(SALOMEDS::Study_var Study, char * refFromFile)
+SMESH::mesh_array* SMESH_Gen_i::CreateMeshesFromMED( const char* theFileName,
+ SMESH::DriverMED_ReadStatus& theStatus)
+ throw ( SALOME::SALOME_Exception )
{
- MESSAGE("SMESH_Gen_i::getShape("<<Study<<","<<refFromFile<<")");
- SCRUTE(CORBA::is_nil(Study));
- SALOMEDS::SObject_var CSO = Study->FindObjectID(refFromFile);
- GEOM::GEOM_Shape_var aShape;
+ Unexpect aCatch(SALOME_SalomeException);
+ MESSAGE( "SMESH_Gen_i::CreateMeshFromMED" );
+ ASSERT( !CORBA::is_nil( myCurrentStudy ) );
+
+ // Retrieve mesh names from the file
+ DriverMED_R_SMESHDS_Mesh myReader;
+ myReader.SetFile( theFileName );
+ myReader.SetMeshId( -1 );
+ list<string> aNames = myReader.GetMeshNames();
+
+ SMESH::mesh_array_var aResult = new SMESH::mesh_array();
+ aResult->length( aNames.size() );
+ int i = 0;
+
+ // Iterate through all meshes and create mesh objects
+ theStatus = SMESH::DRS_OK;
+ for ( list<string>::iterator it = aNames.begin(); it != aNames.end(); it++ ) {
+ // create mesh
+ SMESH::SMESH_Mesh_var mesh = createMesh();
+
+ // publish mesh in the study
+ if ( CanPublishInStudy( mesh ) ) {
+ PublishInStudy( myCurrentStudy, SALOMEDS::SObject::_nil(), mesh.in(), (*it).c_str() );
+ }
+
+ // Read mesh data (groups are published automatically by ImportMEDFile())
+ SMESH_Mesh_i* meshServant = dynamic_cast<SMESH_Mesh_i*>( GetServant( mesh ).in() );
+ ASSERT( meshServant );
+ SMESH::DriverMED_ReadStatus status1 =
+ meshServant->ImportMEDFile( theFileName, (*it).c_str() );
+ if (status1 > theStatus)
+ theStatus = status1;
+
+ aResult[i++] = SMESH::SMESH_Mesh::_duplicate( mesh );
+ }
+
+ return aResult._retn();
+}
- if (!CORBA::is_nil(CSO))
- {
- SALOMEDS::GenericAttribute_var anAttr;
- CSO->FindAttribute(anAttr, "AttributeIOR");
- if (!CORBA::is_nil(CSO))
- {
- MESSAGE("The shape was not loaded. Try to load it.");
- SALOMEDS::Driver_var driver = SALOMEDS::Driver::_narrow(getGeomEngine());
- SALOMEDS::SComponent_var SCO = SALOMEDS::SComponent::_narrow(Study->FindObject("Geometry"));
- SALOMEDS::StudyBuilder_var B = Study->NewBuilder();
- B->LoadWith(SCO,driver);
- CSO->FindAttribute(anAttr, "AttributeIOR");
- }
+//=============================================================================
+/*!
+ * SMESH_Gen_i::IsReadyToCompute
+ *
+ * Returns true if mesh contains enough data to be computed
+ */
+//=============================================================================
- SALOMEDS::AttributeIOR_var anIOR =
- SALOMEDS::AttributeIOR::_narrow(anAttr);
-
- char *ShapeIOR = anIOR->Value();
- aShape =
- GEOM::GEOM_Shape::_narrow(_orb->string_to_object(ShapeIOR));
- }
- return aShape;
+CORBA::Boolean SMESH_Gen_i::IsReadyToCompute( SMESH::SMESH_Mesh_ptr theMesh,
+ GEOM::GEOM_Shape_ptr theShape )
+ throw ( SALOME::SALOME_Exception )
+{
+ Unexpect aCatch(SALOME_SalomeException);
+ MESSAGE( "SMESH_Gen_i::IsReadyToCompute" );
+
+ if ( CORBA::is_nil( theShape ) )
+ THROW_SALOME_CORBA_EXCEPTION( "bad shape reference",
+ SALOME::BAD_PARAM );
+
+ if ( CORBA::is_nil( theMesh ) )
+ THROW_SALOME_CORBA_EXCEPTION( "bad Mesh reference",
+ SALOME::BAD_PARAM );
+
+ try {
+ // get mesh servant
+ SMESH_Mesh_i* meshServant = dynamic_cast<SMESH_Mesh_i*>( GetServant( theMesh ).in() );
+ ASSERT( meshServant );
+ if ( meshServant ) {
+ // get local TopoDS_Shape
+ TopoDS_Shape myLocShape = GetShapeReader()->GetShape( GetGeomEngine(), theShape );
+ // call implementation
+ ::SMESH_Mesh& myLocMesh = meshServant->GetImpl();
+ return myGen.CheckAlgoState( myLocMesh, myLocShape );
+ }
+ }
+ catch ( SALOME_Exception& S_ex ) {
+ MESSAGE( "catch exception "<< S_ex.what() );
+ }
+ return false;
}
-void SMESH_Gen_i::loadMesh(char * name, HDFfile * hdf_file,
- char* meshfile, SALOMEDS::Study_var Study)
+//=============================================================================
+/*!
+ * SMESH_Gen_i::GetSubShapesId
+ *
+ * Get sub-shapes unique ID's list
+ */
+//=============================================================================
+
+SMESH::long_array* SMESH_Gen_i::GetSubShapesId( GEOM::GEOM_Shape_ptr theMainShape,
+ const SMESH::shape_array& theListOfSubShape )
+ throw ( SALOME::SALOME_Exception )
{
- MESSAGE("SMESH_Gen_i::loadMesh("<<name<<","<<meshfile<<")");
+ Unexpect aCatch(SALOME_SalomeException);
+ MESSAGE( "SMESH_Gen_i::GetSubShapesId" );
- char msgname[HDF_NAME_MAX_LEN + 1];
- char objectId[10];
- char name_of_group[HDF_NAME_MAX_LEN + 1];
-
- int myMeshId =
- atoi((string(name).substr(5, 5)).c_str());
- SCRUTE(myMeshId);
-
- HDFgroup * hdfGroupMeshId = new HDFgroup(name, hdf_file);
- hdfGroupMeshId->OpenOnDisk();
-
- int nb_meshsubgroup = hdfGroupMeshId->nInternalObjects();
- SCRUTE(nb_meshsubgroup);
-
- //********** Loading of the file name where the data are stored
- strcpy(name_of_group, "Mesh data");
- HDFdataset * dataset =
- new HDFdataset(name_of_group, hdfGroupMeshId);
- dataset->OpenOnDisk();
-
- char *datafilename = new char[dataset->GetSize()];
- dataset->ReadFromDisk(datafilename);
- dataset->CloseOnDisk();
- MESSAGE("datafilename="<<datafilename<<" but this is ignored. We will read from "<<meshfile);
- datafilename=meshfile;
-
- //********** Loading of the reference on the shape
- //********** and mesh initialization
- strcpy(name_of_group, "Ref on shape");
- dataset =
- new HDFdataset(name_of_group, hdfGroupMeshId);
- dataset->OpenOnDisk();
-
- char *refFromFile = new char[dataset->GetSize()];
- dataset->ReadFromDisk(refFromFile);
- dataset->CloseOnDisk();
+ SMESH::long_array_var shapesId = new SMESH::long_array;
+ set<int> setId;
- bool _found = false;
- SCRUTE(refFromFile);
- SMESH::SMESH_Mesh_var myNewMesh;
- GEOM::GEOM_Shape_var aShape=getShape(Study, refFromFile);
+ if ( CORBA::is_nil( theMainShape ) )
+ THROW_SALOME_CORBA_EXCEPTION( "bad shape reference",
+ SALOME::BAD_PARAM );
- if (!CORBA::is_nil(aShape))
- {
- _found = true;
- myNewMesh = Init(getGeomEngine(), Study->StudyId(), aShape, myMeshId);
- string iorString = _orb->object_to_string(myNewMesh);
- sprintf(objectId, "%ld", myNewMesh->GetId());
- string key=string("Mesh_")+string(objectId);
- MESSAGE("IOR of "<<key<<" is "<< iorString)
- _SMESHCorbaObj[key] = iorString;
+ try
+ {
+ if (! myShapeReader) myShapeReader = new GEOM_Client(GetContainerRef());
+ ASSERT(myShapeReader);
+ TopoDS_Shape myMainShape = GetShapeReader()->GetShape(GetGeomEngine(),theMainShape);
+ TopTools_IndexedMapOfShape myIndexToShape;
+ TopExp::MapShapes(myMainShape,myIndexToShape);
-
- //**********
- //********** Loading of mesh data
- if (strcmp(datafilename, "No data") != 0)
- {
- StudyContext_iStruct *myStudyContext =
- _mapStudyContext_i[Study->StudyId()];
- int meshId = myNewMesh->GetId();
- SMESH_Mesh_i *meshServant =
- myStudyContext->mapMesh_i[meshId];
- ::SMESH_Mesh & myLocMesh = meshServant->GetImpl();
- SMESHDS_Mesh *mySMESHDSMesh = myLocMesh.GetMeshDS();
-
- Mesh_Reader *myReader = SMESHDriver::GetMeshReader("MED");
- myReader->SetMesh(mySMESHDSMesh);
- myReader->SetMeshId(myMeshId);
- myReader->SetFile(datafilename);
- myReader->Read();
- mySMESHDSMesh->logFullUpdate();
- MESSAGE("Loaded a mesh with " << mySMESHDSMesh->NbNodes() <<" nodes");
- }
+ for (int i=0; i<theListOfSubShape.length(); i++)
+ {
+ GEOM::GEOM_Shape_var aShape
+ = GEOM::GEOM_Shape::_narrow(theListOfSubShape[i]);
+ if (CORBA::is_nil(aShape))
+ THROW_SALOME_CORBA_EXCEPTION("bad shape reference", \
+ SALOME::BAD_PARAM);
+ TopoDS_Shape locShape = GetShapeReader()->GetShape(GetGeomEngine(),aShape);
+ for (TopExp_Explorer exp(locShape,TopAbs_FACE); exp.More(); exp.Next())
+ {
+ const TopoDS_Face& F = TopoDS::Face(exp.Current());
+ setId.insert(myIndexToShape.FindIndex(F));
+ SCRUTE(myIndexToShape.FindIndex(F));
+ }
+ for (TopExp_Explorer exp(locShape,TopAbs_EDGE); exp.More(); exp.Next())
+ {
+ const TopoDS_Edge& E = TopoDS::Edge(exp.Current());
+ setId.insert(myIndexToShape.FindIndex(E));
+ SCRUTE(myIndexToShape.FindIndex(E));
+ }
+ for (TopExp_Explorer exp(locShape,TopAbs_VERTEX); exp.More(); exp.Next())
+ {
+ const TopoDS_Vertex& V = TopoDS::Vertex(exp.Current());
+ setId.insert(myIndexToShape.FindIndex(V));
+ SCRUTE(myIndexToShape.FindIndex(V));
+ }
}
- //**********
- //}
- //else if (strcmp(msgname,"Applied Hypothesis")==0) {
- for (int ii = 0; ii < nb_meshsubgroup; ii++)
+ shapesId->length(setId.size());
+ set<int>::iterator iind;
+ int i=0;
+ for (iind = setId.begin(); iind != setId.end(); iind++)
{
- hdfGroupMeshId->InternalObjectIndentify(ii, msgname);
- if (strcmp(msgname, "Mesh data") == 0)
- {
- //nothing
- }
- else if (strcmp(msgname, "Ref on shape") == 0)
- {
- //nothing
- }
- else if (strcmp(msgname, "Applied Hypothesis") == 0)
- {
- loadAppliedHypothesis(hdfGroupMeshId, _found, Study, myNewMesh,
- aShape);
- }
- else if (strcmp(msgname, "Applied Algorithms") == 0)
- {
- loadAppliedAlgorithms(hdfGroupMeshId, _found, Study, myNewMesh,
- aShape);
- }
- else if (string(msgname).substr(0, 9) == string("SubMeshes"))
- {
- loadSubMeshes(hdfGroupMeshId, msgname, Study, myNewMesh);
- }
+ SCRUTE((*iind));
+ shapesId[i] = (*iind);
+ SCRUTE(shapesId[i]);
+ i++;
}
- hdfGroupMeshId->CloseOnDisk();
+ }
+ catch (SALOME_Exception& S_ex)
+ {
+ THROW_SALOME_CORBA_EXCEPTION(S_ex.what(), SALOME::BAD_PARAM);
+ }
+
+ return shapesId._retn();
}
-/**
- * Load the part of the study related to SMESH.
+//=============================================================================
+/*!
+ * SMESH_Gen_i::Compute
+ *
+ * Compute mesh on a shape
*/
-bool SMESH_Gen_i::Load(SALOMEDS::SComponent_ptr theComponent,
- const SALOMEDS::TMPFile & theStream, const char *theURL, bool isMultiFile)
-{
- MESSAGE("SMESH_Gen_i::Load");
- // Get temporary files location
- TCollection_AsciiString tmpDir =
- isMultiFile ? TCollection_AsciiString((char *)theURL) : SALOMEDS_Tool::
- GetTmpDir();
-
- // Convert the stream into sequence of files to process
- SALOMEDS::ListOfFileNames_var aFileSeq =
- SALOMEDS_Tool::PutStreamToFiles(theStream, tmpDir.ToCString(),
- isMultiFile);
-
- TCollection_AsciiString aStudyName("");
- if (isMultiFile)
- aStudyName =
- (SALOMEDS_Tool::GetNameFromPath(theComponent->GetStudy()->URL()));
-
- // Set names of temporary files
- TCollection_AsciiString filename =
- tmpDir + aStudyName + TCollection_AsciiString("_SMESH.hdf");
- TCollection_AsciiString hypofile =
- tmpDir + aStudyName + TCollection_AsciiString("_SMESH_Hypo.txt");
- TCollection_AsciiString algofile =
- tmpDir + aStudyName + TCollection_AsciiString("_SMESH_Algo.txt");
- TCollection_AsciiString meshfile =
- tmpDir + aStudyName + TCollection_AsciiString("_SMESH_Mesh.med");
-
- SALOMEDS::Study_var Study = theComponent->GetStudy();
- int studyId = Study->StudyId();
- SCRUTE(studyId);
-
- SALOMEDS::AttributeName_var aName;
-
- SALOMEDS::SComponent_var fathergeom = Study->FindComponent("GEOM");
- SALOMEDS::SComponent_var myGeomSComp =
- SALOMEDS::SComponent::_narrow(fathergeom);
- SCRUTE(fathergeom);
-
- char name[HDF_NAME_MAX_LEN + 1];
- map < int, HDFgroup * > hdf_subgroup;
+//=============================================================================
+CORBA::Boolean SMESH_Gen_i::Compute( SMESH::SMESH_Mesh_ptr theMesh,
+ GEOM::GEOM_Shape_ptr theShape )
+ throw ( SALOME::SALOME_Exception )
+{
+ Unexpect aCatch(SALOME_SalomeException);
+ MESSAGE( "SMESH_Gen_i::Compute" );
+
+ if ( CORBA::is_nil( theShape ) )
+ THROW_SALOME_CORBA_EXCEPTION( "bad shape reference",
+ SALOME::BAD_PARAM );
+
+ if ( CORBA::is_nil( theMesh ) )
+ THROW_SALOME_CORBA_EXCEPTION( "bad Mesh reference",
+ SALOME::BAD_PARAM );
+
+ try {
+ // get mesh servant
+ SMESH_Mesh_i* meshServant = dynamic_cast<SMESH_Mesh_i*>( GetServant( theMesh ).in() );
+ ASSERT( meshServant );
+ if ( meshServant ) {
+ // get local TopoDS_Shape
+ TopoDS_Shape myLocShape = GetShapeReader()->GetShape( GetGeomEngine(), theShape );
+ // call implementarion compute
+ ::SMESH_Mesh& myLocMesh = meshServant->GetImpl();
+ return myGen.Compute( myLocMesh, myLocShape);
+ }
+ }
+ catch ( SALOME_Exception& S_ex ) {
+ MESSAGE( "Compute(): catch exception "<< S_ex.what() );
+ }
+ catch ( ... ) {
+ MESSAGE( "Compute(): unknown exception " );
+ }
+ return false;
+}
- //************* HDF file opening
- HDFfile *hdf_file = new HDFfile(filename.ToCString());
- try
- {
- hdf_file->OpenOnDisk(HDF_RDONLY);
+//=============================================================================
+/*!
+ * SMESH_Gen_i::Save
+ *
+ * Save SMESH module's data
+ */
+//=============================================================================
+SALOMEDS::TMPFile* SMESH_Gen_i::Save( SALOMEDS::SComponent_ptr theComponent,
+ const char* theURL,
+ bool isMultiFile )
+{
+ INFOS( "SMESH_Gen_i::Save" );
+
+ ASSERT( theComponent->GetStudy()->StudyId() == myCurrentStudy->StudyId() )
+ StudyContext* myStudyContext = GetCurrentStudyContext();
+
+ // Declare a byte stream
+ SALOMEDS::TMPFile_var aStreamFile;
+
+ // Obtain a temporary dir
+ TCollection_AsciiString tmpDir =
+ ( isMultiFile ) ? TCollection_AsciiString( ( char* )theURL ) : SALOMEDS_Tool::GetTmpDir();
+
+ // Create a sequence of files processed
+ SALOMEDS::ListOfFileNames_var aFileSeq = new SALOMEDS::ListOfFileNames;
+ aFileSeq->length( NUM_TMP_FILES );
+
+ TCollection_AsciiString aStudyName( "" );
+ if ( isMultiFile )
+ aStudyName = ( SALOMEDS_Tool::GetNameFromPath( myCurrentStudy->URL() ) );
+
+ // Set names of temporary files
+ TCollection_AsciiString filename =
+ aStudyName + TCollection_AsciiString( "_SMESH.hdf" ); // for SMESH data itself
+ TCollection_AsciiString meshfile =
+ aStudyName + TCollection_AsciiString( "_SMESH_Mesh.med" ); // for mesh data to be stored in MED file
+ aFileSeq[ 0 ] = CORBA::string_dup( filename.ToCString() );
+ aFileSeq[ 1 ] = CORBA::string_dup( meshfile.ToCString() );
+ filename = tmpDir + filename;
+ meshfile = tmpDir + meshfile;
+
+ HDFfile* aFile;
+ HDFdataset* aDataset;
+ HDFgroup* aTopGroup;
+ HDFgroup* aGroup;
+ HDFgroup* aSubGroup;
+ HDFgroup* aSubSubGroup;
+ hdf_size aSize[ 1 ];
+
+ // MED writer to be used by storage process
+ DriverMED_W_SMESHDS_Mesh myWriter;
+ myWriter.SetFile( meshfile.ToCString() );
+
+ // Write data
+ // ---> create HDF file
+ aFile = new HDFfile( filename.ToCString() );
+ aFile->CreateOnDisk();
+
+ // --> iterator for top-level objects
+ SALOMEDS::ChildIterator_var itBig = myCurrentStudy->NewChildIterator( theComponent );
+ for ( ; itBig->More(); itBig->Next() ) {
+ SALOMEDS::SObject_var gotBranch = itBig->Value();
+
+ // --> hypotheses root branch (only one for the study)
+ if ( gotBranch->Tag() == GetHypothesisRootTag() ) {
+ // create hypotheses root HDF group
+ aTopGroup = new HDFgroup( "Hypotheses", aFile );
+ aTopGroup->CreateOnDisk();
+
+ // iterator for all hypotheses
+ SALOMEDS::ChildIterator_var it = myCurrentStudy->NewChildIterator( gotBranch );
+ for ( ; it->More(); it->Next() ) {
+ SALOMEDS::SObject_var mySObject = it->Value();
+ CORBA::Object_var anObject = SObjectToObject( mySObject );
+ if ( !CORBA::is_nil( anObject ) ) {
+ SMESH::SMESH_Hypothesis_var myHyp = SMESH::SMESH_Hypothesis::_narrow( anObject );
+ if ( !myHyp->_is_nil() ) {
+ SMESH_Hypothesis_i* myImpl = dynamic_cast<SMESH_Hypothesis_i*>( GetServant( myHyp ).in() );
+ if ( myImpl ) {
+ string hypname = string( myHyp->GetName() );
+ string libname = string( myHyp->GetLibName() );
+ int id = myStudyContext->findId( string( GetORB()->object_to_string( anObject ) ) );
+ string hypdata = string( myImpl->SaveTo() );
+
+ // for each hypothesis create HDF group basing on its id
+ char hypGrpName[30];
+ sprintf( hypGrpName, "Hypothesis %d", id );
+ aGroup = new HDFgroup( hypGrpName, aTopGroup );
+ aGroup->CreateOnDisk();
+ // --> type name of hypothesis
+ aSize[ 0 ] = hypname.length() + 1;
+ aDataset = new HDFdataset( "Name", aGroup, HDF_STRING, aSize, 1 );
+ aDataset->CreateOnDisk();
+ aDataset->WriteOnDisk( ( char* )( hypname.c_str() ) );
+ aDataset->CloseOnDisk();
+ // --> server plugin library name of hypothesis
+ aSize[ 0 ] = libname.length() + 1;
+ aDataset = new HDFdataset( "LibName", aGroup, HDF_STRING, aSize, 1 );
+ aDataset->CreateOnDisk();
+ aDataset->WriteOnDisk( ( char* )( libname.c_str() ) );
+ aDataset->CloseOnDisk();
+ // --> persistent data of hypothesis
+ aSize[ 0 ] = hypdata.length() + 1;
+ aDataset = new HDFdataset( "Data", aGroup, HDF_STRING, aSize, 1 );
+ aDataset->CreateOnDisk();
+ aDataset->WriteOnDisk( ( char* )( hypdata.c_str() ) );
+ aDataset->CloseOnDisk();
+ // close hypothesis HDF group
+ aGroup->CloseOnDisk();
+ }
+ }
}
- catch(HDFexception)
- {
- MESSAGE("Load(): " << filename << " not found!");
- return false;
+ }
+ // close hypotheses root HDF group
+ aTopGroup->CloseOnDisk();
+ }
+ // --> algorithms root branch (only one for the study)
+ else if ( gotBranch->Tag() == GetAlgorithmsRootTag() ) {
+ // create algorithms root HDF group
+ aTopGroup = new HDFgroup( "Algorithms", aFile );
+ aTopGroup->CreateOnDisk();
+
+ // iterator for all algorithms
+ SALOMEDS::ChildIterator_var it = myCurrentStudy->NewChildIterator( gotBranch );
+ for ( ; it->More(); it->Next() ) {
+ SALOMEDS::SObject_var mySObject = it->Value();
+ CORBA::Object_var anObject = SObjectToObject( mySObject );
+ if ( !CORBA::is_nil( anObject ) ) {
+ SMESH::SMESH_Hypothesis_var myHyp = SMESH::SMESH_Hypothesis::_narrow( anObject );
+ if ( !myHyp->_is_nil() ) {
+ SMESH_Hypothesis_i* myImpl = dynamic_cast<SMESH_Hypothesis_i*>( GetServant( myHyp ).in() );
+ if ( myImpl ) {
+ string hypname = string( myHyp->GetName() );
+ string libname = string( myHyp->GetLibName() );
+ int id = myStudyContext->findId( string( GetORB()->object_to_string( anObject ) ) );
+ string hypdata = string( myImpl->SaveTo() );
+
+ // for each algorithm create HDF group basing on its id
+ char hypGrpName[30];
+ sprintf( hypGrpName, "Algorithm %d", id );
+ aGroup = new HDFgroup( hypGrpName, aTopGroup );
+ aGroup->CreateOnDisk();
+ // --> type name of algorithm
+ aSize[0] = hypname.length() + 1;
+ aDataset = new HDFdataset( "Name", aGroup, HDF_STRING, aSize, 1 );
+ aDataset->CreateOnDisk();
+ aDataset->WriteOnDisk( ( char* )( hypname.c_str() ) );
+ aDataset->CloseOnDisk();
+ // --> server plugin library name of hypothesis
+ aSize[0] = libname.length() + 1;
+ aDataset = new HDFdataset( "LibName", aGroup, HDF_STRING, aSize, 1 );
+ aDataset->CreateOnDisk();
+ aDataset->WriteOnDisk( ( char* )( libname.c_str() ) );
+ aDataset->CloseOnDisk();
+ // --> persistent data of algorithm
+ aSize[0] = hypdata.length() + 1;
+ aDataset = new HDFdataset( "Data", aGroup, HDF_STRING, aSize, 1 );
+ aDataset->CreateOnDisk();
+ aDataset->WriteOnDisk( ( char* )( hypdata.c_str() ) );
+ aDataset->CloseOnDisk();
+ // close algorithm HDF group
+ aGroup->CloseOnDisk();
+ }
+ }
}
+ }
+ // close algorithms root HDF group
+ aTopGroup->CloseOnDisk();
+ }
+ // --> mesh objects roots branches
+ else if ( gotBranch->Tag() > GetAlgorithmsRootTag() ) {
+ CORBA::Object_var anObject = SObjectToObject( gotBranch );
+ if ( !CORBA::is_nil( anObject ) ) {
+ SMESH::SMESH_Mesh_var myMesh = SMESH::SMESH_Mesh::_narrow( anObject ) ;
+ if ( !myMesh->_is_nil() ) {
+ SMESH_Mesh_i* myImpl = dynamic_cast<SMESH_Mesh_i*>( GetServant( myMesh ).in() );
+ if ( myImpl ) {
+ int id = myStudyContext->findId( string( GetORB()->object_to_string( anObject ) ) );
+ ::SMESH_Mesh& myLocMesh = myImpl->GetImpl();
+ SMESHDS_Mesh* mySMESHDSMesh = myLocMesh.GetMeshDS();
+
+ // for each mesh open the HDF group basing on its id
+ char meshGrpName[ 30 ];
+ sprintf( meshGrpName, "Mesh %d", id );
+ aTopGroup = new HDFgroup( meshGrpName, aFile );
+ aTopGroup->CreateOnDisk();
+
+ // --> put dataset to hdf file which is a flag that mesh has data
+ string strHasData = "0";
+ // check if the mesh is not empty
+ if ( mySMESHDSMesh->NbNodes() > 0 ) {
+ // write mesh data to med file
+ myWriter.SetMesh( mySMESHDSMesh );
+ myWriter.SetMeshId( id );
+ strHasData = "1";
+ }
+ aSize[ 0 ] = strHasData.length() + 1;
+ aDataset = new HDFdataset( "Has data", aTopGroup, HDF_STRING, aSize, 1 );
+ aDataset->CreateOnDisk();
+ aDataset->WriteOnDisk( ( char* )( strHasData.c_str() ) );
+ aDataset->CloseOnDisk();
+
+ // write reference on a shape if exists
+ SALOMEDS::SObject_var myRef;
+ bool found = gotBranch->FindSubObject( GetRefOnShapeTag(), myRef );
+ if ( found ) {
+ SALOMEDS::SObject_var myShape;
+ bool ok = myRef->ReferencedObject( myShape );
+ if ( ok ) {
+ string myRefOnObject = myShape->GetID();
+ if ( myRefOnObject.length() > 0 ) {
+ aSize[ 0 ] = myRefOnObject.length() + 1;
+ aDataset = new HDFdataset( "Ref on shape", aTopGroup, HDF_STRING, aSize, 1 );
+ aDataset->CreateOnDisk();
+ aDataset->WriteOnDisk( ( char* )( myRefOnObject.c_str() ) );
+ aDataset->CloseOnDisk();
+ }
+ }
+ }
+
+ // write applied hypotheses if exist
+ SALOMEDS::SObject_var myHypBranch;
+ found = gotBranch->FindSubObject( GetRefOnAppliedHypothesisTag(), myHypBranch );
+ if ( found ) {
+ aGroup = new HDFgroup( "Applied Hypotheses", aTopGroup );
+ aGroup->CreateOnDisk();
+
+ SALOMEDS::ChildIterator_var it = myCurrentStudy->NewChildIterator( myHypBranch );
+ int hypNb = 0;
+ for ( ; it->More(); it->Next() ) {
+ SALOMEDS::SObject_var mySObject = it->Value();
+ SALOMEDS::SObject_var myRefOnHyp;
+ bool ok = mySObject->ReferencedObject( myRefOnHyp );
+ if ( ok ) {
+ // san - it is impossible to recover applied hypotheses
+ // using their entries within Load() method,
+ // for there are no AttributeIORs in the study when Load() is working.
+ // Hence, it is better to store persistent IDs of hypotheses as references to them
+
+ //string myRefOnObject = myRefOnHyp->GetID();
+ CORBA::Object_var anObject = SObjectToObject( myRefOnHyp );
+ int id = myStudyContext->findId( string( GetORB()->object_to_string( anObject ) ) );
+ //if ( myRefOnObject.length() > 0 ) {
+ //aSize[ 0 ] = myRefOnObject.length() + 1;
+ char hypName[ 30 ], hypId[ 30 ];
+ sprintf( hypName, "Hyp %d", ++hypNb );
+ sprintf( hypId, "%d", id );
+ aSize[ 0 ] = strlen( hypId ) + 1;
+ aDataset = new HDFdataset( hypName, aGroup, HDF_STRING, aSize, 1 );
+ aDataset->CreateOnDisk();
+ //aDataset->WriteOnDisk( ( char* )( myRefOnObject.c_str() ) );
+ aDataset->WriteOnDisk( hypId );
+ aDataset->CloseOnDisk();
+ //}
+ }
+ }
+ aGroup->CloseOnDisk();
+ }
+
+ // write applied algorithms if exist
+ SALOMEDS::SObject_var myAlgoBranch;
+ found = gotBranch->FindSubObject( GetRefOnAppliedAlgorithmsTag(), myAlgoBranch );
+ if ( found ) {
+ aGroup = new HDFgroup( "Applied Algorithms", aTopGroup );
+ aGroup->CreateOnDisk();
+
+ SALOMEDS::ChildIterator_var it = myCurrentStudy->NewChildIterator( myAlgoBranch );
+ int algoNb = 0;
+ for ( ; it->More(); it->Next() ) {
+ SALOMEDS::SObject_var mySObject = it->Value();
+ SALOMEDS::SObject_var myRefOnAlgo;
+ bool ok = mySObject->ReferencedObject( myRefOnAlgo );
+ if ( ok ) {
+ // san - it is impossible to recover applied algorithms
+ // using their entries within Load() method,
+ // for there are no AttributeIORs in the study when Load() is working.
+ // Hence, it is better to store persistent IDs of algorithms as references to them
+
+ //string myRefOnObject = myRefOnAlgo->GetID();
+ CORBA::Object_var anObject = SObjectToObject( myRefOnAlgo );
+ int id = myStudyContext->findId( string( GetORB()->object_to_string( anObject ) ) );
+ //if ( myRefOnObject.length() > 0 ) {
+ //aSize[ 0 ] = myRefOnObject.length() + 1;
+ char algoName[ 30 ], algoId[ 30 ];
+ sprintf( algoName, "Algo %d", ++algoNb );
+ sprintf( algoId, "%d", id );
+ aSize[ 0 ] = strlen( algoId ) + 1;
+ aDataset = new HDFdataset( algoName, aGroup, HDF_STRING, aSize, 1 );
+ aDataset->CreateOnDisk();
+ //aDataset->WriteOnDisk( ( char* )( myRefOnObject.c_str() ) );
+ aDataset->WriteOnDisk( algoId );
+ aDataset->CloseOnDisk();
+ //}
+ }
+ }
+ aGroup->CloseOnDisk();
+ }
+
+ // --> submesh objects sub-branches
+ for ( int i = GetSubMeshOnVertexTag(); i <= GetSubMeshOnCompoundTag(); i++ ) {
+ SALOMEDS::SObject_var mySubmeshBranch;
+ found = gotBranch->FindSubObject( i, mySubmeshBranch );
+ if ( found ) {
+ char name_meshgroup[ 30 ];
+ if ( i == GetSubMeshOnVertexTag() )
+ strcpy( name_meshgroup, "SubMeshes On Vertex" );
+ else if ( i == GetSubMeshOnEdgeTag() )
+ strcpy( name_meshgroup, "SubMeshes On Edge" );
+ else if ( i == GetSubMeshOnFaceTag() )
+ strcpy( name_meshgroup, "SubMeshes On Face" );
+ else if ( i == GetSubMeshOnSolidTag() )
+ strcpy( name_meshgroup, "SubMeshes On Solid" );
+ else if ( i == GetSubMeshOnCompoundTag() )
+ strcpy( name_meshgroup, "SubMeshes On Compound" );
+
+ // for each type of submeshes create container HDF group
+ aGroup = new HDFgroup( name_meshgroup, aTopGroup );
+ aGroup->CreateOnDisk();
+
+ // iterator for all submeshes of given type
+ SALOMEDS::ChildIterator_var itSM = myCurrentStudy->NewChildIterator( mySubmeshBranch );
+ for ( ; itSM->More(); itSM->Next() ) {
+ SALOMEDS::SObject_var mySObject = itSM->Value();
+ CORBA::Object_var anSubObject = SObjectToObject( mySObject );
+ if ( !CORBA::is_nil( anSubObject ) ) {
+ SMESH::SMESH_subMesh_var mySubMesh = SMESH::SMESH_subMesh::_narrow( anSubObject ) ;
+ int subid = myStudyContext->findId( string( GetORB()->object_to_string( anSubObject ) ) );
+
+ // for each mesh open the HDF group basing on its id
+ char submeshGrpName[ 30 ];
+ sprintf( submeshGrpName, "SubMesh %d", subid );
+ aSubGroup = new HDFgroup( submeshGrpName, aGroup );
+ aSubGroup->CreateOnDisk();
+
+// // Put submesh data to MED convertor
+// if ( myImpl->_mapSubMesh.find( mySubMesh->GetId() ) != myImpl->_mapSubMesh.end() ) {
+// MESSAGE( "VSR - SMESH_Gen_i::Save(): saving submesh with ID = "
+// << mySubMesh->GetId() << " to MED file" );
+// ::SMESH_subMesh* aLocalSubmesh = myImpl->_mapSubMesh[mySubMesh->GetId()];
+// myWriter.AddSubMesh( aLocalSubmesh->GetSubMeshDS(), subid );
+// }
+
+ // write reference on a shape if exists
+ SALOMEDS::SObject_var mySubRef;
+ found = mySObject->FindSubObject( GetRefOnShapeTag(), mySubRef );
+ if ( found ) {
+ SALOMEDS::SObject_var myShape;
+ bool ok = mySubRef->ReferencedObject( myShape );
+ if ( ok ) {
+ string myRefOnObject = myShape->GetID();
+ if ( myRefOnObject.length() > 0 ) {
+ aSize[ 0 ] = myRefOnObject.length() + 1;
+ aDataset = new HDFdataset( "Ref on shape", aSubGroup, HDF_STRING, aSize, 1 );
+ aDataset->CreateOnDisk();
+ aDataset->WriteOnDisk( ( char* )( myRefOnObject.c_str() ) );
+ aDataset->CloseOnDisk();
+ }
+ }
+ }
+
+ // write applied hypotheses if exist
+ SALOMEDS::SObject_var mySubHypBranch;
+ found = mySObject->FindSubObject( GetRefOnAppliedHypothesisTag(), mySubHypBranch );
+ if ( found ) {
+ aSubSubGroup = new HDFgroup( "Applied Hypotheses", aSubGroup );
+ aSubSubGroup->CreateOnDisk();
+
+ SALOMEDS::ChildIterator_var it = myCurrentStudy->NewChildIterator( mySubHypBranch );
+ int hypNb = 0;
+ for ( ; it->More(); it->Next() ) {
+ SALOMEDS::SObject_var mySubSObject = it->Value();
+ SALOMEDS::SObject_var myRefOnHyp;
+ bool ok = mySubSObject->ReferencedObject( myRefOnHyp );
+ if ( ok ) {
+ //string myRefOnObject = myRefOnHyp->GetID();
+ CORBA::Object_var anObject = SObjectToObject( myRefOnHyp );
+ int id = myStudyContext->findId( string( GetORB()->object_to_string( anObject ) ) );
+ //if ( myRefOnObject.length() > 0 ) {
+ //aSize[ 0 ] = myRefOnObject.length() + 1;
+ char hypName[ 30 ], hypId[ 30 ];
+ sprintf( hypName, "Hyp %d", ++hypNb );
+ sprintf( hypId, "%d", id );
+ aSize[ 0 ] = strlen( hypId ) + 1;
+ aDataset = new HDFdataset( hypName, aSubSubGroup, HDF_STRING, aSize, 1 );
+ aDataset->CreateOnDisk();
+ //aDataset->WriteOnDisk( ( char* )( myRefOnObject.c_str() ) );
+ aDataset->WriteOnDisk( hypId );
+ aDataset->CloseOnDisk();
+ //}
+ }
+ }
+ aSubSubGroup->CloseOnDisk();
+ }
+
+ // write applied algorithms if exist
+ SALOMEDS::SObject_var mySubAlgoBranch;
+ found = mySObject->FindSubObject( GetRefOnAppliedAlgorithmsTag(), mySubAlgoBranch );
+ if ( found ) {
+ aSubSubGroup = new HDFgroup( "Applied Algorithms", aSubGroup );
+ aSubSubGroup->CreateOnDisk();
+
+ SALOMEDS::ChildIterator_var it = myCurrentStudy->NewChildIterator( mySubAlgoBranch );
+ int algoNb = 0;
+ for ( ; it->More(); it->Next() ) {
+ SALOMEDS::SObject_var mySubSObject = it->Value();
+ SALOMEDS::SObject_var myRefOnAlgo;
+ bool ok = mySubSObject->ReferencedObject( myRefOnAlgo );
+ if ( ok ) {
+ //string myRefOnObject = myRefOnAlgo->GetID();
+ CORBA::Object_var anObject = SObjectToObject( myRefOnAlgo );
+ int id = myStudyContext->findId( string( GetORB()->object_to_string( anObject ) ) );
+ //if ( myRefOnObject.length() > 0 ) {
+ //aSize[ 0 ] = myRefOnObject.length() + 1;
+ char algoName[ 30 ], algoId[ 30 ];
+ sprintf( algoName, "Algo %d", ++algoNb );
+ sprintf( algoId, "%d", id );
+ aSize[ 0 ] = strlen( algoId ) + 1;
+ aDataset = new HDFdataset( algoName, aSubSubGroup, HDF_STRING, aSize, 1 );
+ aDataset->CreateOnDisk();
+ //aDataset->WriteOnDisk( ( char* )( myRefOnObject.c_str() ) );
+ aDataset->WriteOnDisk( algoId );
+ aDataset->CloseOnDisk();
+ //}
+ }
+ }
+ aSubSubGroup->CloseOnDisk();
+ }
+ // close submesh HDF group
+ aSubGroup->CloseOnDisk();
+ }
+ }
+ // close container of submeshes by type HDF group
+ aGroup->CloseOnDisk();
+ }
+ }
+ // All sub-meshes will be stored in MED file
+ myWriter.AddAllSubMeshes();
+
+ // groups root sub-branch
+ SALOMEDS::SObject_var myGroupsBranch;
+ for ( int i = GetNodeGroupsTag(); i <= GetVolumeGroupsTag(); i++ ) {
+ found = gotBranch->FindSubObject( i, myGroupsBranch );
+ if ( found ) {
+ char name_group[ 30 ];
+ if ( i == GetNodeGroupsTag() )
+ strcpy( name_group, "Groups of Nodes" );
+ else if ( i == GetEdgeGroupsTag() )
+ strcpy( name_group, "Groups of Edges" );
+ else if ( i == GetFaceGroupsTag() )
+ strcpy( name_group, "Groups of Faces" );
+ else if ( i == GetVolumeGroupsTag() )
+ strcpy( name_group, "Groups of Volumes" );
+
+ aGroup = new HDFgroup( name_group, aTopGroup );
+ aGroup->CreateOnDisk();
+
+ SALOMEDS::ChildIterator_var it = myCurrentStudy->NewChildIterator( myGroupsBranch );
+ int grpNb = 0;
+ for ( ; it->More(); it->Next() ) {
+ SALOMEDS::SObject_var mySObject = it->Value();
+ CORBA::Object_var aSubObject = SObjectToObject( mySObject );
+ if ( !CORBA::is_nil( aSubObject ) ) {
+ SMESH_Group_i* myGroupImpl = dynamic_cast<SMESH_Group_i*>( GetServant( aSubObject ).in() );
+ if ( !myGroupImpl )
+ continue;
+
+ int anId = myStudyContext->findId( string( GetORB()->object_to_string( aSubObject ) ) );
+
+ // For each group, create a dataset named "Group <group_persistent_id>"
+ // and store the group's user name into it
+ char grpName[ 30 ];
+ sprintf( grpName, "Group %d", anId );
+ char* aUserName = myGroupImpl->GetName();
+ aSize[ 0 ] = strlen( aUserName ) + 1;
+
+ aDataset = new HDFdataset( grpName, aGroup, HDF_STRING, aSize, 1 );
+ aDataset->CreateOnDisk();
+ aDataset->WriteOnDisk( aUserName );
+ aDataset->CloseOnDisk();
+
+ // Store the group contents into MED file
+ if ( myLocMesh.GetGroup( myGroupImpl->GetLocalID() ) ) {
+ MESSAGE( "VSR - SMESH_Gen_i::Save(): saving group with StoreName = "
+ << grpName << " to MED file" );
+ SMESHDS_Group* aGrpDS = myLocMesh.GetGroup( myGroupImpl->GetLocalID() )->GetGroupDS();
+ aGrpDS->SetStoreName( grpName );
+
+ // Pass SMESHDS_Group to MED writer
+ myWriter.AddGroup( aGrpDS );
+ }
+ }
+ }
+ aGroup->CloseOnDisk();
+ }
+ }
- //****************************
+ // Flush current mesh information into MED file
+ if ( strcmp( strHasData.c_str(), "1" ) == 0 )
+ myWriter.Add();
- int nb_group = hdf_file->nInternalObjects();
- SCRUTE(nb_group);
- for (int i = 0; i < nb_group; i++)
- {
- hdf_file->InternalObjectIndentify(i, name);
- if (strcmp(name, "Hypothesis") == 0)
- loadHypothesis(name, hdf_file, hypofile.ToCString(), studyId);
- else if (strcmp(name, "Algorithms") == 0)
- loadAlgorithms(name, hdf_file, algofile.ToCString(), studyId);
- else if (string(name).substr(0, 4) == string("Mesh"))
- loadMesh(name, hdf_file, meshfile.ToCString(), Study);
+ // close mesh HDF group
+ aTopGroup->CloseOnDisk();
+ }
}
+ }
+ }
+ }
- MESSAGE("End of SMESH_Gen::Load");
+ // close HDF file
+ aFile->CloseOnDisk();
+ delete aFile;
- hdf_file->CloseOnDisk();
+ // Convert temporary files to stream
+ aStreamFile = SALOMEDS_Tool::PutFilesToStream( tmpDir.ToCString(), aFileSeq.in(), isMultiFile );
- // Remove temporary files created from the stream
- if (isMultiFile)
- SALOMEDS_Tool::RemoveTemporaryFiles(tmpDir.ToCString(), aFileSeq.in(),
- true);
+ // Remove temporary files and directory
+ if ( !isMultiFile )
+ SALOMEDS_Tool::RemoveTemporaryFiles( tmpDir.ToCString(), aFileSeq.in(), true );
- return true;
+ INFOS( "SMESH_Gen_i::Save() completed" );
+ return aStreamFile._retn();
}
-bool SMESH_Gen_i::LoadASCII(SALOMEDS::SComponent_ptr theComponent,
- const SALOMEDS::TMPFile & theStream, const char *theURL, bool isMultiFile)
+//=============================================================================
+/*!
+ * SMESH_Gen_i::SaveASCII
+ *
+ * Save SMESH module's data in ASCII format (not implemented yet)
+ */
+//=============================================================================
+
+SALOMEDS::TMPFile* SMESH_Gen_i::SaveASCII( SALOMEDS::SComponent_ptr theComponent,
+ const char* theURL,
+ bool isMultiFile ) {
+ MESSAGE( "SMESH_Gen_i::SaveASCII" );
+ SALOMEDS::TMPFile_var aStreamFile = Save( theComponent, theURL, isMultiFile );
+ return aStreamFile._retn();
+}
+
+//=============================================================================
+/*!
+ * SMESH_Gen_i::loadGeomData
+ *
+ * Load GEOM module data
+ */
+//=============================================================================
+
+void SMESH_Gen_i::loadGeomData( SALOMEDS::SComponent_ptr theCompRoot )
{
- return Load(theComponent, theStream, theURL, isMultiFile);
+ if ( theCompRoot->_is_nil() )
+ return;
+
+ SALOMEDS::Study_var aStudy = SALOMEDS::Study::_narrow( theCompRoot->GetStudy() );
+ if ( aStudy->_is_nil() )
+ return;
+
+ SALOMEDS::StudyBuilder_var aStudyBuilder = aStudy->NewBuilder();
+ aStudyBuilder->LoadWith( theCompRoot, GetGeomEngine() );
}
//=============================================================================
/*!
- *
+ * SMESH_Gen_i::Load
+ *
+ * Load SMESH module's data
*/
//=============================================================================
-void SMESH_Gen_i::Close(SALOMEDS::SComponent_ptr theComponent)
+bool SMESH_Gen_i::Load( SALOMEDS::SComponent_ptr theComponent,
+ const SALOMEDS::TMPFile& theStream,
+ const char* theURL,
+ bool isMultiFile )
{
- MESSAGE("Close");
- SALOMEDS::Study_var aStudy = theComponent->GetStudy();
- SALOMEDS::ChildIterator_var itBig = aStudy->NewChildIterator(theComponent);
- for (; itBig->More(); itBig->Next())
- {
- SALOMEDS::SObject_var gotBranch = itBig->Value();
-
- // branch 1 : hypothesis
- if (gotBranch->Tag() == Tag_HypothesisRoot ||
- gotBranch->Tag() == Tag_AlgorithmsRoot)
- {
- SALOMEDS::ChildIterator_var it =
- aStudy->NewChildIterator(gotBranch);
- for (; it->More(); it->Next())
- {
- SALOMEDS::SObject_var mySObject = it->Value();
- SALOMEDS::GenericAttribute_var anAttr;
- SALOMEDS::AttributeIOR_var anIOR;
- if (mySObject->FindAttribute(anAttr, "AttributeIOR"))
- {
- anIOR = SALOMEDS::AttributeIOR::_narrow(anAttr);
- SMESH::SMESH_Hypothesis_var myHyp =
- SMESH::SMESH_Hypothesis::_narrow(_orb->
- string_to_object(anIOR->Value()));
- char objectId[10];
- sprintf(objectId, "%ld", myHyp->GetId());
-// cout<<"********** delete Hyp "<<objectId<<endl;
- _SMESHCorbaObj.erase(string("Hypo_") + string(objectId));
- myHyp =
- SMESH::SMESH_Hypothesis::_narrow(_orb->
- string_to_object(anIOR->Value()));
- }
- }
+ INFOS( "SMESH_Gen_i::Load" );
+
+ ASSERT( theComponent->GetStudy()->StudyId() == myCurrentStudy->StudyId() )
+ StudyContext* myStudyContext = GetCurrentStudyContext();
+
+ // Get temporary files location
+ TCollection_AsciiString tmpDir =
+ isMultiFile ? TCollection_AsciiString( ( char* )theURL ) : SALOMEDS_Tool::GetTmpDir();
+
+ // Convert the stream into sequence of files to process
+ SALOMEDS::ListOfFileNames_var aFileSeq = SALOMEDS_Tool::PutStreamToFiles( theStream,
+ tmpDir.ToCString(),
+ isMultiFile );
+ TCollection_AsciiString aStudyName( "" );
+ if ( isMultiFile )
+ aStudyName = ( SALOMEDS_Tool::GetNameFromPath( myCurrentStudy->URL() ) );
+
+ // Set names of temporary files
+ TCollection_AsciiString filename = tmpDir + aStudyName + TCollection_AsciiString( "_SMESH.hdf" );
+ TCollection_AsciiString meshfile = tmpDir + aStudyName + TCollection_AsciiString( "_SMESH_Mesh.med" );
+
+ int size;
+ HDFfile* aFile;
+ HDFdataset* aDataset;
+ HDFgroup* aTopGroup;
+ HDFgroup* aGroup;
+ HDFgroup* aSubGroup;
+ HDFgroup* aSubSubGroup;
+
+ // Read data
+ // ---> open HDF file
+ aFile = new HDFfile( filename.ToCString() );
+ try {
+ aFile->OpenOnDisk( HDF_RDONLY );
+ }
+ catch ( HDFexception ) {
+ MESSAGE( "Load(): " << filename << " not found!" );
+ return false;
+ }
+
+ DriverMED_R_SMESHDS_Mesh myReader;
+ myReader.SetFile( meshfile.ToCString() );
+
+ // get total number of top-level groups
+ int aNbGroups = aFile->nInternalObjects();
+ if ( aNbGroups > 0 ) {
+ // --> in first turn we should read&create hypotheses
+ if ( aFile->ExistInternalObject( "Hypotheses" ) ) {
+ // open hypotheses root HDF group
+ aTopGroup = new HDFgroup( "Hypotheses", aFile );
+ aTopGroup->OpenOnDisk();
+
+ // get number of hypotheses
+ int aNbObjects = aTopGroup->nInternalObjects();
+ for ( int j = 0; j < aNbObjects; j++ ) {
+ // try to identify hypothesis
+ char hypGrpName[ HDF_NAME_MAX_LEN+1 ];
+ aTopGroup->InternalObjectIndentify( j, hypGrpName );
+
+ if ( string( hypGrpName ).substr( 0, 10 ) == string( "Hypothesis" ) ) {
+ // open hypothesis group
+ aGroup = new HDFgroup( hypGrpName, aTopGroup );
+ aGroup->OpenOnDisk();
+
+ // --> get hypothesis id
+ int id = atoi( string( hypGrpName ).substr( 10 ).c_str() );
+ string hypname;
+ string libname;
+ string hypdata;
+
+ // get number of datasets
+ int aNbSubObjects = aGroup->nInternalObjects();
+ for ( int k = 0; k < aNbSubObjects; k++ ) {
+ // identify dataset
+ char name_of_subgroup[ HDF_NAME_MAX_LEN+1 ];
+ aGroup->InternalObjectIndentify( k, name_of_subgroup );
+ // --> get hypothesis name
+ if ( strcmp( name_of_subgroup, "Name" ) == 0 ) {
+ aDataset = new HDFdataset( name_of_subgroup, aGroup );
+ aDataset->OpenOnDisk();
+ size = aDataset->GetSize();
+ char* hypname_str = new char[ size ];
+ aDataset->ReadFromDisk( hypname_str );
+ hypname = string( hypname_str );
+ delete hypname_str;
+ aDataset->CloseOnDisk();
+ }
+ // --> get hypothesis plugin library name
+ if ( strcmp( name_of_subgroup, "LibName" ) == 0 ) {
+ aDataset = new HDFdataset( name_of_subgroup, aGroup );
+ aDataset->OpenOnDisk();
+ size = aDataset->GetSize();
+ char* libname_str = new char[ size ];
+ aDataset->ReadFromDisk( libname_str );
+ SCRUTE( libname_str );
+ libname = string( libname_str );
+ delete libname_str;
+ aDataset->CloseOnDisk();
+ }
+ // --> get hypothesis data
+ if ( strcmp( name_of_subgroup, "Data" ) == 0 ) {
+ aDataset = new HDFdataset( name_of_subgroup, aGroup );
+ aDataset->OpenOnDisk();
+ size = aDataset->GetSize();
+ char* hypdata_str = new char[ size ];
+ aDataset->ReadFromDisk( hypdata_str );
+ hypdata = string( hypdata_str );
+ delete hypdata_str;
+ aDataset->CloseOnDisk();
+ }
+ }
+ // close hypothesis HDF group
+ aGroup->CloseOnDisk();
+
+ // --> restore hypothesis from data
+ if ( id > 0 && !hypname.empty()/* && !hypdata.empty()*/ ) { // VSR : persistent data can be empty
+ MESSAGE("VSR - load hypothesis : id = " << id <<
+ ", name = " << hypname.c_str() << ", persistent string = " << hypdata.c_str());
+ SMESH::SMESH_Hypothesis_var myHyp;
+
+ try { // protect persistence mechanism against exceptions
+ myHyp = this->createHypothesis( hypname.c_str(), libname.c_str() );
+ }
+ catch (...) {
+ MESSAGE( "Exception during hypothesis creation" );
+ }
+
+ SMESH_Hypothesis_i* myImpl = dynamic_cast<SMESH_Hypothesis_i*>( GetServant( myHyp ).in() );
+ if ( myImpl ) {
+ myImpl->LoadFrom( hypdata.c_str() );
+ string iorString = GetORB()->object_to_string( myHyp );
+ int newId = myStudyContext->findId( iorString );
+ myStudyContext->mapOldToNew( id, newId );
+ }
+ else
+ MESSAGE( "VSR - SMESH_Gen::Load - can't get servant" );
+ }
+ }
+ }
+ // close hypotheses root HDF group
+ aTopGroup->CloseOnDisk();
+ }
+
+ // --> then we should read&create algorithms
+ if ( aFile->ExistInternalObject( "Algorithms" ) ) {
+ // open algorithms root HDF group
+ aTopGroup = new HDFgroup( "Algorithms", aFile );
+ aTopGroup->OpenOnDisk();
+
+ // get number of algorithms
+ int aNbObjects = aTopGroup->nInternalObjects();
+ for ( int j = 0; j < aNbObjects; j++ ) {
+ // try to identify algorithm
+ char hypGrpName[ HDF_NAME_MAX_LEN+1 ];
+ aTopGroup->InternalObjectIndentify( j, hypGrpName );
+
+ if ( string( hypGrpName ).substr( 0, 9 ) == string( "Algorithm" ) ) {
+ // open algorithm group
+ aGroup = new HDFgroup( hypGrpName, aTopGroup );
+ aGroup->OpenOnDisk();
+
+ // --> get algorithm id
+ int id = atoi( string( hypGrpName ).substr( 9 ).c_str() );
+ string hypname;
+ string libname;
+ string hypdata;
+
+ // get number of datasets
+ int aNbSubObjects = aGroup->nInternalObjects();
+ for ( int k = 0; k < aNbSubObjects; k++ ) {
+ // identify dataset
+ char name_of_subgroup[ HDF_NAME_MAX_LEN+1 ];
+ aGroup->InternalObjectIndentify( k, name_of_subgroup );
+ // --> get algorithm name
+ if ( strcmp( name_of_subgroup, "Name" ) == 0 ) {
+ aDataset = new HDFdataset( name_of_subgroup, aGroup );
+ aDataset->OpenOnDisk();
+ size = aDataset->GetSize();
+ char* hypname_str = new char[ size ];
+ aDataset->ReadFromDisk( hypname_str );
+ hypname = string( hypname_str );
+ delete hypname_str;
+ aDataset->CloseOnDisk();
+ }
+ // --> get algorithm plugin library name
+ if ( strcmp( name_of_subgroup, "LibName" ) == 0 ) {
+ aDataset = new HDFdataset( name_of_subgroup, aGroup );
+ aDataset->OpenOnDisk();
+ size = aDataset->GetSize();
+ char* libname_str = new char[ size ];
+ aDataset->ReadFromDisk( libname_str );
+ SCRUTE( libname_str );
+ libname = string( libname_str );
+ delete libname_str;
+ aDataset->CloseOnDisk();
+ }
+ // --> get algorithm data
+ if ( strcmp( name_of_subgroup, "Data" ) == 0 ) {
+ aDataset = new HDFdataset( name_of_subgroup, aGroup );
+ aDataset->OpenOnDisk();
+ size = aDataset->GetSize();
+ char* hypdata_str = new char[ size ];
+ aDataset->ReadFromDisk( hypdata_str );
+ SCRUTE( hypdata_str );
+ hypdata = string( hypdata_str );
+ delete hypdata_str;
+ aDataset->CloseOnDisk();
+ }
+ }
+ // close algorithm HDF group
+ aGroup->CloseOnDisk();
+
+ // --> restore algorithm from data
+ if ( id > 0 && !hypname.empty()/* && !hypdata.empty()*/ ) { // VSR : persistent data can be empty
+ MESSAGE("VSR - load algo : id = " << id <<
+ ", name = " << hypname.c_str() << ", persistent string = " << hypdata.c_str());
+ SMESH::SMESH_Hypothesis_var myHyp;
+
+ try { // protect persistence mechanism against exceptions
+ myHyp = this->createHypothesis( hypname.c_str(), libname.c_str() );
+ }
+ catch (...) {
+ MESSAGE( "Exception during hypothesis creation" );
+ }
+
+ SMESH_Hypothesis_i* myImpl = dynamic_cast<SMESH_Hypothesis_i*>( GetServant( myHyp ).in() );
+ if ( myImpl ) {
+ myImpl->LoadFrom( hypdata.c_str() );
+ string iorString = GetORB()->object_to_string( myHyp );
+ int newId = myStudyContext->findId( iorString );
+ myStudyContext->mapOldToNew( id, newId );
+ }
+ else
+ MESSAGE( "VSR - SMESH_Gen::Load - can't get servant" );
+ }
+ }
+ }
+ // close algorithms root HDF group
+ aTopGroup->CloseOnDisk();
+ }
+
+ // --> the rest groups should be meshes
+ for ( int i = 0; i < aNbGroups; i++ ) {
+ // identify next group
+ char meshName[ HDF_NAME_MAX_LEN+1 ];
+ aFile->InternalObjectIndentify( i, meshName );
+
+ if ( string( meshName ).substr( 0, 4 ) == string( "Mesh" ) ) {
+ // --> get mesh id
+ int id = atoi( string( meshName ).substr( 4 ).c_str() );
+ if ( id <= 0 )
+ continue;
+
+ bool hasData = false;
+
+ // open mesh HDF group
+ aTopGroup = new HDFgroup( meshName, aFile );
+ aTopGroup->OpenOnDisk();
+
+ // get number of child HDF objects
+ int aNbObjects = aTopGroup->nInternalObjects();
+ if ( aNbObjects > 0 ) {
+ // create mesh
+ MESSAGE( "VSR - load mesh : id = " << id );
+ SMESH::SMESH_Mesh_var myNewMesh = this->createMesh();
+ SMESH_Mesh_i* myNewMeshImpl = dynamic_cast<SMESH_Mesh_i*>( GetServant( myNewMesh ).in() );
+ if ( !myNewMeshImpl )
+ continue;
+ string iorString = GetORB()->object_to_string( myNewMesh );
+ int newId = myStudyContext->findId( iorString );
+ myStudyContext->mapOldToNew( id, newId );
+
+ ::SMESH_Mesh& myLocMesh = myNewMeshImpl->GetImpl();
+ SMESHDS_Mesh* mySMESHDSMesh = myLocMesh.GetMeshDS();
+
+ // try to find mesh data dataset
+ if ( aTopGroup->ExistInternalObject( "Has data" ) ) {
+ // load mesh "has data" flag
+ aDataset = new HDFdataset( "Has data", aTopGroup );
+ aDataset->OpenOnDisk();
+ size = aDataset->GetSize();
+ char* strHasData = new char[ size ];
+ aDataset->ReadFromDisk( strHasData );
+ aDataset->CloseOnDisk();
+ if ( strcmp( strHasData, "1") == 0 ) {
+ // read mesh data from MED file
+ myReader.SetMesh( mySMESHDSMesh );
+ myReader.SetMeshId( id );
+ myReader.ReadMySelf();
+ hasData = true;
+ }
+ }
+
+ // try to read and set reference to shape
+ GEOM::GEOM_Shape_var aShape;
+ if ( aTopGroup->ExistInternalObject( "Ref on shape" ) ) {
+ // load mesh "Ref on shape" - it's an entry to SObject
+ aDataset = new HDFdataset( "Ref on shape", aTopGroup );
+ aDataset->OpenOnDisk();
+ size = aDataset->GetSize();
+ char* refFromFile = new char[ size ];
+ aDataset->ReadFromDisk( refFromFile );
+ aDataset->CloseOnDisk();
+ if ( strlen( refFromFile ) > 0 ) {
+ SALOMEDS::SObject_var shapeSO = myCurrentStudy->FindObjectID( refFromFile );
+
+ // Make sure GEOM data are loaded first
+ loadGeomData( shapeSO->GetFatherComponent() );
+
+ CORBA::Object_var shapeObject = SObjectToObject( shapeSO );
+ if ( !CORBA::is_nil( shapeObject ) ) {
+ aShape = GEOM::GEOM_Shape::_narrow( shapeObject );
+ if ( !aShape->_is_nil() )
+ myNewMeshImpl->setShape( aShape );
+ }
+ }
+ }
+
+ // try to get applied hypotheses
+ if ( aTopGroup->ExistInternalObject( "Applied Hypotheses" ) ) {
+ aGroup = new HDFgroup( "Applied Hypotheses", aTopGroup );
+ aGroup->OpenOnDisk();
+ // get number of applied hypotheses
+ int aNbSubObjects = aGroup->nInternalObjects();
+ MESSAGE( "VSR - number of applied hypotheses = " << aNbSubObjects );
+ for ( int j = 0; j < aNbSubObjects; j++ ) {
+ char name_dataset[ HDF_NAME_MAX_LEN+1 ];
+ aGroup->InternalObjectIndentify( j, name_dataset );
+ // check if it is a hypothesis
+ if ( string( name_dataset ).substr( 0, 3 ) == string( "Hyp" ) ) {
+ aDataset = new HDFdataset( name_dataset, aGroup );
+ aDataset->OpenOnDisk();
+ size = aDataset->GetSize();
+ char* refFromFile = new char[ size ];
+ aDataset->ReadFromDisk( refFromFile );
+ aDataset->CloseOnDisk();
+
+ // san - it is impossible to recover applied hypotheses using their entries within Load() method
+
+ //SALOMEDS::SObject_var hypSO = myCurrentStudy->FindObjectID( refFromFile );
+ //CORBA::Object_var hypObject = SObjectToObject( hypSO );
+ int id = atoi( refFromFile );
+ string anIOR = myStudyContext->getIORbyOldId( id );
+ if ( !anIOR.empty() ) {
+ CORBA::Object_var hypObject = GetORB()->string_to_object( anIOR.c_str() );
+ if ( !CORBA::is_nil( hypObject ) ) {
+ SMESH::SMESH_Hypothesis_var anHyp = SMESH::SMESH_Hypothesis::_narrow( hypObject );
+ if ( !anHyp->_is_nil() && !aShape->_is_nil() )
+ myNewMeshImpl->addHypothesis( aShape, anHyp );
+ }
+ }
+ }
+ }
+ aGroup->CloseOnDisk();
+ }
+
+ // try to get applied algorithms
+ if ( aTopGroup->ExistInternalObject( "Applied Algorithms" ) ) {
+ aGroup = new HDFgroup( "Applied Algorithms", aTopGroup );
+ aGroup->OpenOnDisk();
+ // get number of applied algorithms
+ int aNbSubObjects = aGroup->nInternalObjects();
+ MESSAGE( "VSR - number of applied algos " << aNbSubObjects );
+ for ( int j = 0; j < aNbSubObjects; j++ ) {
+ char name_dataset[ HDF_NAME_MAX_LEN+1 ];
+ aGroup->InternalObjectIndentify( j, name_dataset );
+ // check if it is an algorithm
+ if ( string( name_dataset ).substr( 0, 4 ) == string( "Algo" ) ) {
+ aDataset = new HDFdataset( name_dataset, aGroup );
+ aDataset->OpenOnDisk();
+ size = aDataset->GetSize();
+ char* refFromFile = new char[ size ];
+ aDataset->ReadFromDisk( refFromFile );
+ aDataset->CloseOnDisk();
+
+ // san - it is impossible to recover applied algorithms using their entries within Load() method
+
+ //SALOMEDS::SObject_var hypSO = myCurrentStudy->FindObjectID( refFromFile );
+ //CORBA::Object_var hypObject = SObjectToObject( hypSO );
+ int id = atoi( refFromFile );
+ string anIOR = myStudyContext->getIORbyOldId( id );
+ if ( !anIOR.empty() ) {
+ CORBA::Object_var hypObject = GetORB()->string_to_object( anIOR.c_str() );
+ if ( !CORBA::is_nil( hypObject ) ) {
+ SMESH::SMESH_Hypothesis_var anHyp = SMESH::SMESH_Hypothesis::_narrow( hypObject );
+ if ( !anHyp->_is_nil() && !aShape->_is_nil() )
+ myNewMeshImpl->addHypothesis( aShape, anHyp );
+ }
}
- // branch 2 : algorithms
- else if (gotBranch->Tag() >= 3)
- {
- SALOMEDS::ChildIterator_var it =
- aStudy->NewChildIterator(gotBranch);
- for (; it->More(); it->Next())
- {
- SALOMEDS::SObject_var mySObject = it->Value();
- SALOMEDS::GenericAttribute_var anAttr;
- SALOMEDS::AttributeIOR_var anIOR;
- if (mySObject->FindAttribute(anAttr, "AttributeIOR"))
- {
- anIOR = SALOMEDS::AttributeIOR::_narrow(anAttr);
- SMESH::SMESH_Mesh_var myMesh =
- SMESH::SMESH_Mesh::_narrow(_orb->
- string_to_object(anIOR->Value()));
- if (!myMesh->_is_nil())
- {
- char objectId[10];
- sprintf(objectId, "%ld", myMesh->GetId());
-// cout<<"********** delete Mesh "<<objectId<<endl;
- _SMESHCorbaObj.erase(string("Mesh_") +
- string(objectId));
- CORBA::release(myMesh);
- }
- else
- {
- SMESH::SMESH_subMesh_var mySubMesh =
- SMESH::SMESH_subMesh::_narrow(_orb->
- string_to_object(anIOR->Value()));
- if (!mySubMesh->_is_nil())
- {
- char objectId[10];
- sprintf(objectId, "%ld", mySubMesh->GetId());
-// cout<<"********** delete SubMesh "<<objectId<<endl;
- _SMESHCorbaObj.erase(string("SubMesh_") +
- string(objectId));
- CORBA::release(mySubMesh);
- }
- }
- }
+ }
+ }
+ aGroup->CloseOnDisk();
+ }
+
+ // --> try to find submeshes containers for each type of submesh
+ for ( int j = GetSubMeshOnVertexTag(); j <= GetSubMeshOnCompoundTag(); j++ ) {
+ char name_meshgroup[ 30 ];
+ if ( j == GetSubMeshOnVertexTag() )
+ strcpy( name_meshgroup, "SubMeshes On Vertex" );
+ else if ( j == GetSubMeshOnEdgeTag() )
+ strcpy( name_meshgroup, "SubMeshes On Edge" );
+ else if ( j == GetSubMeshOnFaceTag() )
+ strcpy( name_meshgroup, "SubMeshes On Face" );
+ else if ( j == GetSubMeshOnSolidTag() )
+ strcpy( name_meshgroup, "SubMeshes On Solid" );
+ else if ( j == GetSubMeshOnCompoundTag() )
+ strcpy( name_meshgroup, "SubMeshes On Compound" );
+
+ // try to get submeshes container HDF group
+ if ( aTopGroup->ExistInternalObject( name_meshgroup ) ) {
+ // open submeshes containers HDF group
+ aGroup = new HDFgroup( name_meshgroup, aTopGroup );
+ aGroup->OpenOnDisk();
+
+ // get number of submeshes
+ int aNbSubMeshes = aGroup->nInternalObjects();
+ for ( int k = 0; k < aNbSubMeshes; k++ ) {
+ // identify submesh
+ char name_submeshgroup[ HDF_NAME_MAX_LEN+1 ];
+ aGroup->InternalObjectIndentify( k, name_submeshgroup );
+ if ( string( name_submeshgroup ).substr( 0, 7 ) == string( "SubMesh" ) ) {
+ // --> get submesh id
+ int subid = atoi( string( name_submeshgroup ).substr( 7 ).c_str() );
+ if ( subid <= 0 )
+ continue;
+ // open submesh HDF group
+ aSubGroup = new HDFgroup( name_submeshgroup, aGroup );
+ aSubGroup->OpenOnDisk();
+
+ // try to read and set reference to subshape
+ GEOM::GEOM_Shape_var aSubShape;
+ SMESH::SMESH_subMesh_var aSubMesh;
+
+ if ( aSubGroup->ExistInternalObject( "Ref on shape" ) ) {
+ // load submesh "Ref on shape" - it's an entry to SObject
+ aDataset = new HDFdataset( "Ref on shape", aSubGroup );
+ aDataset->OpenOnDisk();
+ size = aDataset->GetSize();
+ char* refFromFile = new char[ size ];
+ aDataset->ReadFromDisk( refFromFile );
+ aDataset->CloseOnDisk();
+ if ( strlen( refFromFile ) > 0 ) {
+ SALOMEDS::SObject_var subShapeSO = myCurrentStudy->FindObjectID( refFromFile );
+ CORBA::Object_var subShapeObject = SObjectToObject( subShapeSO );
+ if ( !CORBA::is_nil( subShapeObject ) ) {
+ aSubShape = GEOM::GEOM_Shape::_narrow( subShapeObject );
+ if ( !aSubShape->_is_nil() )
+ aSubMesh = SMESH::SMESH_subMesh::_duplicate
+ ( myNewMeshImpl->createSubMesh( aSubShape ) );
+ if ( aSubMesh->_is_nil() )
+ continue;
+ string iorSubString = GetORB()->object_to_string( aSubMesh );
+ int newSubId = myStudyContext->findId( iorSubString );
+ myStudyContext->mapOldToNew( subid, newSubId );
+ }
+ }
+ }
+
+ if ( aSubMesh->_is_nil() )
+ continue;
+
+ // VSR: Get submesh data from MED convertor
+// int anInternalSubmeshId = aSubMesh->GetId(); // this is not a persistent ID, it's an internal one computed from sub-shape
+// if (myNewMeshImpl->_mapSubMesh.find(anInternalSubmeshId) != myNewMeshImpl->_mapSubMesh.end()) {
+// MESSAGE("VSR - SMESH_Gen_i::Load(): loading from MED file submesh with ID = " <<
+// subid << " for subshape # " << anInternalSubmeshId);
+// SMESHDS_SubMesh* aSubMeshDS =
+// myNewMeshImpl->_mapSubMesh[anInternalSubmeshId]->CreateSubMeshDS();
+// if ( !aSubMeshDS ) {
+// MESSAGE("VSR - SMESH_Gen_i::Load(): FAILED to create a submesh for subshape # " <<
+// anInternalSubmeshId << " in current mesh!");
+// }
+// else
+// myReader.GetSubMesh( aSubMeshDS, subid );
+// }
+
+ // try to get applied hypotheses
+ if ( aSubGroup->ExistInternalObject( "Applied Hypotheses" ) ) {
+ // open "applied hypotheses" HDF group
+ aSubSubGroup = new HDFgroup( "Applied Hypotheses", aSubGroup );
+ aSubSubGroup->OpenOnDisk();
+ // get number of applied hypotheses
+ int aNbSubObjects = aSubSubGroup->nInternalObjects();
+ for ( int l = 0; l < aNbSubObjects; l++ ) {
+ char name_dataset[ HDF_NAME_MAX_LEN+1 ];
+ aSubSubGroup->InternalObjectIndentify( l, name_dataset );
+ // check if it is a hypothesis
+ if ( string( name_dataset ).substr( 0, 3 ) == string( "Hyp" ) ) {
+ aDataset = new HDFdataset( name_dataset, aSubSubGroup );
+ aDataset->OpenOnDisk();
+ size = aDataset->GetSize();
+ char* refFromFile = new char[ size ];
+ aDataset->ReadFromDisk( refFromFile );
+ aDataset->CloseOnDisk();
+
+ //SALOMEDS::SObject_var hypSO = myCurrentStudy->FindObjectID( refFromFile );
+ //CORBA::Object_var hypObject = SObjectToObject( hypSO );
+ int id = atoi( refFromFile );
+ string anIOR = myStudyContext->getIORbyOldId( id );
+ if ( !anIOR.empty() ) {
+ CORBA::Object_var hypObject = GetORB()->string_to_object( anIOR.c_str() );
+ if ( !CORBA::is_nil( hypObject ) ) {
+ SMESH::SMESH_Hypothesis_var anHyp = SMESH::SMESH_Hypothesis::_narrow( hypObject );
+ if ( !anHyp->_is_nil() && !aShape->_is_nil() )
+ myNewMeshImpl->addHypothesis( aSubShape, anHyp );
+ }
}
+ }
+ }
+ // close "applied hypotheses" HDF group
+ aSubSubGroup->CloseOnDisk();
+ }
+
+ // try to get applied algorithms
+ if ( aSubGroup->ExistInternalObject( "Applied Algorithms" ) ) {
+ // open "applied algorithms" HDF group
+ aSubSubGroup = new HDFgroup( "Applied Algorithms", aSubGroup );
+ aSubSubGroup->OpenOnDisk();
+ // get number of applied algorithms
+ int aNbSubObjects = aSubSubGroup->nInternalObjects();
+ for ( int l = 0; l < aNbSubObjects; l++ ) {
+ char name_dataset[ HDF_NAME_MAX_LEN+1 ];
+ aSubSubGroup->InternalObjectIndentify( l, name_dataset );
+ // check if it is an algorithm
+ if ( string( name_dataset ).substr( 0, 4 ) == string( "Algo" ) ) {
+ aDataset = new HDFdataset( name_dataset, aSubSubGroup );
+ aDataset->OpenOnDisk();
+ size = aDataset->GetSize();
+ char* refFromFile = new char[ size ];
+ aDataset->ReadFromDisk( refFromFile );
+ aDataset->CloseOnDisk();
+
+ //SALOMEDS::SObject_var hypSO = myCurrentStudy->FindObjectID( refFromFile );
+ //CORBA::Object_var hypObject = SObjectToObject( hypSO );
+ int id = atoi( refFromFile );
+ string anIOR = myStudyContext->getIORbyOldId( id );
+ if ( !anIOR.empty() ) {
+ CORBA::Object_var hypObject = GetORB()->string_to_object( anIOR.c_str() );
+ if ( !CORBA::is_nil( hypObject ) ) {
+ SMESH::SMESH_Hypothesis_var anHyp = SMESH::SMESH_Hypothesis::_narrow( hypObject );
+ if ( !anHyp->_is_nil() && !aShape->_is_nil() )
+ myNewMeshImpl->addHypothesis( aSubShape, anHyp );
+ }
+ }
+ }
+ }
+ // close "applied algorithms" HDF group
+ aSubSubGroup->CloseOnDisk();
+ }
+
+ // close submesh HDF group
+ aSubGroup->CloseOnDisk();
+ }
+ }
+ // close submeshes containers HDF group
+ aGroup->CloseOnDisk();
+ }
+ }
+
+ if(hasData){
+ // Read sub-meshes from MED
+ MESSAGE("JFA - Create all sub-meshes");
+ myReader.CreateAllSubMeshes();
+ }
+
+ // Recompute State (as computed sub-meshes are restored from MED)
+ if ( !aShape->_is_nil() ) {
+ MESSAGE("JFA - Compute State Engine ...");
+// map<int, ::SMESH_subMesh*>::iterator anAllSubMeshes = myNewMeshImpl->_mapSubMesh.begin();
+// for (; anAllSubMeshes != myNewMeshImpl->_mapSubMesh.end(); anAllSubMeshes++)
+// {
+// (*anAllSubMeshes).second->GetSubMeshDS(); // init SMESH_subMesh::_meshDS
+// (*anAllSubMeshes).second->ComputeStateEngine(SMESH_subMesh::SUBMESH_RESTORED);
+// }
+ TopoDS_Shape myLocShape = GetShapeReader()->GetShape( GetGeomEngine(), aShape );
+ myNewMeshImpl->GetImpl().GetSubMesh(myLocShape)->ComputeStateEngine(SMESH_subMesh::SUBMESH_RESTORED);
+ MESSAGE("JFA - Compute State Engine finished");
+ }
+
+ // try to get groups
+ for ( int ii = GetNodeGroupsTag(); ii <= GetVolumeGroupsTag(); ii++ ) {
+ char name_group[ 30 ];
+ if ( ii == GetNodeGroupsTag() )
+ strcpy( name_group, "Groups of Nodes" );
+ else if ( ii == GetEdgeGroupsTag() )
+ strcpy( name_group, "Groups of Edges" );
+ else if ( ii == GetFaceGroupsTag() )
+ strcpy( name_group, "Groups of Faces" );
+ else if ( ii == GetVolumeGroupsTag() )
+ strcpy( name_group, "Groups of Volumes" );
+
+ if ( aTopGroup->ExistInternalObject( name_group ) ) {
+ aGroup = new HDFgroup( name_group, aTopGroup );
+ aGroup->OpenOnDisk();
+ // get number of groups
+ int aNbSubObjects = aGroup->nInternalObjects();
+ for ( int j = 0; j < aNbSubObjects; j++ ) {
+ char name_dataset[ HDF_NAME_MAX_LEN+1 ];
+ aGroup->InternalObjectIndentify( j, name_dataset );
+ // check if it is an group
+ if ( string( name_dataset ).substr( 0, 5 ) == string( "Group" ) ) {
+ // --> get group id
+ int subid = atoi( string( name_dataset ).substr( 5 ).c_str() );
+ if ( subid <= 0 )
+ continue;
+ aDataset = new HDFdataset( name_dataset, aGroup );
+ aDataset->OpenOnDisk();
+
+ // Retrieve actual group name
+ size = aDataset->GetSize();
+ char* nameFromFile = new char[ size ];
+ aDataset->ReadFromDisk( nameFromFile );
+ aDataset->CloseOnDisk();
+
+ // Create group servant
+ SMESH::SMESH_Group_var aNewGroup = SMESH::SMESH_Group::_duplicate
+ ( myNewMeshImpl->createGroup( (SMESH::ElementType)(ii - GetNodeGroupsTag() + 1),
+ nameFromFile ) );
+ // Obtain a SMESHDS_Group object
+ if ( aNewGroup->_is_nil() )
+ continue;
+
+ string iorSubString = GetORB()->object_to_string( aNewGroup );
+ int newSubId = myStudyContext->findId( iorSubString );
+ myStudyContext->mapOldToNew( subid, newSubId );
+
+ SMESH_Group_i* aGroupImpl = dynamic_cast<SMESH_Group_i*>( GetServant( aNewGroup ).in() );
+ if ( !aGroupImpl )
+ continue;
+
+ SMESH_Group* aLocalGroup = myLocMesh.GetGroup( aGroupImpl->GetLocalID() );
+ if ( !aLocalGroup )
+ continue;
+
+ SMESHDS_Group* aGroupDS = aLocalGroup->GetGroupDS();
+ aGroupDS->SetStoreName( name_dataset );
+
+ // Fill group with contents from MED file
+ myReader.GetGroup( aGroupDS );
}
+ }
+ aGroup->CloseOnDisk();
+ }
+ }
}
+ // close mesh group
+ aTopGroup->CloseOnDisk();
+ }
+ }
+ }
+ // close HDF file
+ aFile->CloseOnDisk();
+ delete aFile;
+
+ // Remove temporary files created from the stream
+ if ( !isMultiFile )
+ SALOMEDS_Tool::RemoveTemporaryFiles( tmpDir.ToCString(), aFileSeq.in(), true );
+
+ INFOS( "SMESH_Gen_i::Load completed" );
+ return true;
}
//=============================================================================
/*!
- *
+ * SMESH_Gen_i::LoadASCII
+ *
+ * Load SMESH module's data in ASCII format (not implemented yet)
*/
//=============================================================================
-char *SMESH_Gen_i::ComponentDataType()
-{
- MESSAGE("SMESH_Gen_i::ComponentDataType");
- return strdup("SMESH");
+bool SMESH_Gen_i::LoadASCII( SALOMEDS::SComponent_ptr theComponent,
+ const SALOMEDS::TMPFile& theStream,
+ const char* theURL,
+ bool isMultiFile ) {
+ MESSAGE( "SMESH_Gen_i::LoadASCII" );
+ return Load( theComponent, theStream, theURL, isMultiFile );
}
//=============================================================================
/*!
- *
+ * SMESH_Gen_i::Close
+ *
+ * Clears study-connected data when it is closed
*/
//=============================================================================
-char *SMESH_Gen_i::IORToLocalPersistentID(SALOMEDS::SObject_ptr theSObject,
- const char *IORString, CORBA::Boolean isMultiFile, CORBA::Boolean isASCII)
+void SMESH_Gen_i::Close( SALOMEDS::SComponent_ptr theComponent )
{
- MESSAGE("SMESH_Gen_i::IORToLocalPersistentID");
+ MESSAGE( "SMESH_Gen_i::Close" );
+
+ // Clear study contexts data
+ int studyId = myCurrentStudy->StudyId();
+ if ( myStudyContextMap.find( studyId ) != myStudyContextMap.end() ) {
+ delete myStudyContextMap[ studyId ];
+ myStudyContextMap.erase( studyId );
+ }
+ return;
+}
- char objectId[10];
+//=============================================================================
+/*!
+ * SMESH_Gen_i::ComponentDataType
+ *
+ * Get component data type
+ */
+//=============================================================================
- SMESH::SMESH_Algo_var myAlgo =
- SMESH::SMESH_Algo::_narrow(_orb->string_to_object(IORString));
- if (!CORBA::is_nil(myAlgo))
- {
- string prefix = "Hypo_";
- sprintf(objectId, "%ld", myAlgo->GetId());
- string lpID = prefix + string(objectId);
- return CORBA::string_dup(lpID.c_str());
- }
- else
- {
- SMESH::SMESH_Hypothesis_var myHypo =
- SMESH::SMESH_Hypothesis::_narrow(_orb->string_to_object(IORString));
- if (!CORBA::is_nil(myHypo))
- {
- string prefix = "Hypo_";
- sprintf(objectId, "%ld", myHypo->GetId());
- string lpID = prefix + string(objectId);
- return CORBA::string_dup(lpID.c_str());
- }
- else
- {
- SMESH::SMESH_Mesh_var myMesh =
- SMESH::SMESH_Mesh::_narrow(_orb->string_to_object(IORString));
- if (!CORBA::is_nil(myMesh))
- {
- string prefix = "Mesh_";
- sprintf(objectId, "%ld", myMesh->GetId());
- string lpID = prefix + string(objectId);
- return CORBA::string_dup(lpID.c_str());
- }
- else
- {
- SMESH::SMESH_subMesh_var mySubMesh =
- SMESH::SMESH_subMesh::_narrow(_orb->
- string_to_object(IORString));
- if (!CORBA::is_nil(mySubMesh))
- {
- string prefix = "SubMesh_";
- sprintf(objectId, "%ld", mySubMesh->GetId());
- string lpID = prefix + string(objectId);
- return CORBA::string_dup(lpID.c_str());
- }
- else
- return (strdup("no object"));
- }
- }
- }
+char* SMESH_Gen_i::ComponentDataType()
+{
+ MESSAGE( "SMESH_Gen_i::ComponentDataType" );
+ return strdup( "SMESH" );
}
+
//=============================================================================
/*!
+ * SMESH_Gen_i::IORToLocalPersistentID
*
+ * Transform data from transient form to persistent
*/
//=============================================================================
-char *SMESH_Gen_i::LocalPersistentIDToIOR(SALOMEDS::SObject_ptr theSObject,
- const char *aLocalPersistentID,
- CORBA::Boolean isMultiFile, CORBA::Boolean isASCII)
+char* SMESH_Gen_i::IORToLocalPersistentID( SALOMEDS::SObject_ptr theSObject,
+ const char* IORString,
+ CORBA::Boolean isMultiFile,
+ CORBA::Boolean isASCII )
{
- MESSAGE("SMESH_Gen_i::LocalPersistentIDToIOR");
- SCRUTE(aLocalPersistentID);
- string clef = string(aLocalPersistentID);
- SCRUTE(_SMESHCorbaObj[clef].c_str());
- return CORBA::string_dup(_SMESHCorbaObj[clef].c_str());
+ MESSAGE( "SMESH_Gen_i::IORToLocalPersistentID" );
+ StudyContext* myStudyContext = GetCurrentStudyContext();
+
+ if ( strcmp( IORString, "" ) != 0 ) {
+ int anId = myStudyContext->findId( IORString );
+ if ( anId ) {
+ MESSAGE( "VSR " << anId )
+ char strId[ 20 ];
+ sprintf( strId, "%d", anId );
+ return CORBA::string_dup( strId );
+ }
+ }
+ return strdup( "" );
}
//=============================================================================
/*!
- *
+ * SMESH_Gen_i::LocalPersistentIDToIOR
+ *
+ * Transform data from persistent form to transient
*/
//=============================================================================
-SMESH_topo *SMESH_Gen_i::ExploreMainShape(GEOM::GEOM_Gen_ptr geomEngine,
- CORBA::Long studyId, GEOM::GEOM_Shape_ptr aShape)
+char* SMESH_Gen_i::LocalPersistentIDToIOR( SALOMEDS::SObject_ptr theSObject,
+ const char* aLocalPersistentID,
+ CORBA::Boolean isMultiFile,
+ CORBA::Boolean isASCII )
{
- MESSAGE("SMESH_Mesh_i::ExploreMainShape");
- // _narrow() duplicates the reference and check the type
- GEOM::GEOM_Gen_var geom = GEOM::GEOM_Gen::_narrow(geomEngine);
- GEOM::GEOM_Shape_var myShape = GEOM::GEOM_Shape::_narrow(aShape);
-
- if (CORBA::is_nil(geom))
- THROW_SALOME_CORBA_EXCEPTION("bad geom reference", SALOME::BAD_PARAM);
- if (CORBA::is_nil(myShape))
- THROW_SALOME_CORBA_EXCEPTION("bad shape reference", SALOME::BAD_PARAM);
- MESSAGE("---");
- SCRUTE(myShape->Name());
- geom->GetCurrentStudy(studyId);
- SCRUTE(studyId);
- TopoDS_Shape mainShape = _ShapeReader->GetShape(geom, myShape);
- MESSAGE("---");
-
- // create an SMESH_topo object for the mainShape
-
- SMESH_topo *myTopo = new SMESH_topo();
- MESSAGE("---");
-
- // explore local TopoDS_Shape, store reference of local TopoDS subShapes
-
- for (TopExp_Explorer exp(mainShape, TopAbs_COMPOUND); exp.More();
- exp.Next())
- {
- const TopoDS_Compound & E = TopoDS::Compound(exp.Current());
- int i = myTopo->_myShapes[TopAbs_COMPOUND].Add(E);
- SCRUTE(i);
- }
- for (TopExp_Explorer exp(mainShape, TopAbs_COMPSOLID); exp.More();
- exp.Next())
- {
- const TopoDS_CompSolid & E = TopoDS::CompSolid(exp.Current());
- int i = myTopo->_myShapes[TopAbs_COMPSOLID].Add(E);
- SCRUTE(i);
- }
- for (TopExp_Explorer exp(mainShape, TopAbs_SOLID); exp.More(); exp.Next())
- {
- const TopoDS_Solid & E = TopoDS::Solid(exp.Current());
- int i = myTopo->_myShapes[TopAbs_SOLID].Add(E);
- SCRUTE(i);
- }
- for (TopExp_Explorer exp(mainShape, TopAbs_SHELL); exp.More(); exp.Next())
- {
- const TopoDS_Shell & E = TopoDS::Shell(exp.Current());
- int i = myTopo->_myShapes[TopAbs_SHELL].Add(E);
- SCRUTE(i);
- }
- for (TopExp_Explorer exp(mainShape, TopAbs_FACE); exp.More(); exp.Next())
- {
- const TopoDS_Face & E = TopoDS::Face(exp.Current());
- int i = myTopo->_myShapes[TopAbs_FACE].Add(E);
- SCRUTE(i);
- }
- for (TopExp_Explorer exp(mainShape, TopAbs_WIRE); exp.More(); exp.Next())
- {
- const TopoDS_Wire & E = TopoDS::Wire(exp.Current());
- int i = myTopo->_myShapes[TopAbs_WIRE].Add(E);
- SCRUTE(i);
- }
- for (TopExp_Explorer exp(mainShape, TopAbs_EDGE); exp.More(); exp.Next())
- {
- const TopoDS_Edge & E = TopoDS::Edge(exp.Current());
- int i = myTopo->_myShapes[TopAbs_EDGE].Add(E);
- SCRUTE(i);
- }
- for (TopExp_Explorer exp(mainShape, TopAbs_VERTEX); exp.More(); exp.Next())
- {
- const TopoDS_Vertex & E = TopoDS::Vertex(exp.Current());
- int i = myTopo->_myShapes[TopAbs_VERTEX].Add(E);
- SCRUTE(i);
- }
+ MESSAGE( "SMESH_Gen_i::LocalPersistentIDToIOR(): id = " << aLocalPersistentID );
+ StudyContext* myStudyContext = GetCurrentStudyContext();
+
+ if ( strcmp( aLocalPersistentID, "" ) != 0 ) {
+ int anId = atoi( aLocalPersistentID );
+ return CORBA::string_dup( myStudyContext->getIORbyOldId( anId ).c_str() );
+ }
+ return strdup( "" );
+}
- // explore subShapes of distant CORBA object,
- // associate distant CORBA subShape references
- // with local reference to local TopoDS subShape
+//=============================================================================
+/*!
+ * SMESH_Gen_i::CanPublishInStudy
+ *
+ * Returns true if object can be published in the study
+ */
+//=============================================================================
- string filenode = "toposhape.txt";
- ofstream fic(filenode.c_str());
+bool SMESH_Gen_i::CanPublishInStudy(CORBA::Object_ptr theIOR)
+{
+ SMESH::SMESH_Mesh_var aMesh = SMESH::SMESH_Mesh::_narrow(theIOR);
+ if( !aMesh->_is_nil() )
+ return true;
- for (int shapeType = TopAbs_COMPOUND; shapeType < TopAbs_SHAPE; shapeType++)
- {
- fic << "shape type : " << SMESH_shapeTypeNames[shapeType];
-
- GEOM::GEOM_Gen::ListOfGeomShapes_var subShapes
- = geom->SubShapeAll(myShape, shapeType);
- int nbSubShapes = subShapes->length();
- int nbLocal = myTopo->_myShapes[shapeType].Extent();
- fic << " - number of elements: " << nbSubShapes << endl;
- ASSERT(nbSubShapes == nbLocal);
-
- for (int i = 0; i < nbSubShapes; i++)
- {
- GEOM::GEOM_Shape_var aSubShape = subShapes[i];
- string idShape = SMESH_topo::GetShapeLocalId(aSubShape);
- fic << " " << idShape;
- SCRUTE(idShape);
- TopoDS_Shape aLocShape = _ShapeReader->GetShape(geom, aSubShape);
- for (int j = 1; j <= nbLocal; j++)
- if (aLocShape.IsSame(myTopo->_myShapes[shapeType].FindKey(j)))
- {
- MESSAGE(" --- trouve = " << j);
- myTopo->_mapIndShapes[shapeType][idShape] = j;
- fic << " --- trouve = " << j;
- break;
- }
- fic << endl;
- }
- }
- fic.close();
+ SMESH::SMESH_subMesh_var aSubMesh = SMESH::SMESH_subMesh::_narrow(theIOR);
+ if( !aSubMesh->_is_nil() )
+ return true;
+
+ SMESH::SMESH_Hypothesis_var aHyp = SMESH::SMESH_Hypothesis::_narrow(theIOR);
+ if( !aHyp->_is_nil() )
+ return true;
- return myTopo;
+ SMESH::SMESH_Group_var aGroup = SMESH::SMESH_Group::_narrow(theIOR);
+ if( !aGroup->_is_nil() )
+ return true;
+
+ return false;
}
-/**
- * Import a mesh from a file
- * @param fileName file name to be imported
- * @param fileType Currently it could be either "DAT", "UNV" or "MED".
+//=============================================================================
+/*!
+ * SMESH_Gen_i::PublishInStudy
+ *
+ * Publish object in the study
*/
-SMESH::SMESH_Mesh_ptr SMESH_Gen_i::Import(CORBA::Long studyId,
- const char *fileName, const char *fileType)
-{
- MESSAGE("SMESH_Gen_I::Import");
- SMESH_Mesh_i *meshServant;
- try
- {
- if (_mapStudyContext_i.find(studyId) == _mapStudyContext_i.end())
- {
- _mapStudyContext_i[studyId] = new StudyContext_iStruct;
- }
- StudyContext_iStruct *myStudyContext = _mapStudyContext_i[studyId];
+//=============================================================================
- // create a new mesh object
- SMESH_Mesh * meshImpl=_impl.Import(studyId, fileName, fileType);
-
- // create a new mesh object servant, store it in a map in study context
- meshServant = new SMESH_Mesh_i(this, NULL, studyId, meshImpl);
- myStudyContext->mapMesh_i[meshImpl->GetId()] = meshServant;
+SALOMEDS::SObject_ptr SMESH_Gen_i::PublishInStudy(SALOMEDS::Study_ptr theStudy,
+ SALOMEDS::SObject_ptr theSObject,
+ CORBA::Object_ptr theIOR,
+ const char* theName)
+throw (SALOME::SALOME_Exception)
+{
+ Unexpect aCatch(SALOME_SalomeException);
+ MESSAGE( "********** SMESH_Gen_i::PublishInStudy()" );
+ SALOMEDS::SObject_var aSO;
+
+ // san - first try to find SObject corresponding to SMESH component in theStudy
+ // It is dangerous to use FindComponent("MESH") for this, as some other component
+ // of type "MESH" might be present in theStudy.
+ // So component's user name obtained from ModuleCatalog is passed to FindObject()...
+ SALOME_ModuleCatalog::ModuleCatalog_var aCat =
+ SALOME_ModuleCatalog::ModuleCatalog::_narrow( GetNS()->Resolve("/Kernel/ModulCatalog") );
+ if ( CORBA::is_nil( aCat ) )
+ return aSO._retn();
+
+ SALOME_ModuleCatalog::Acomponent_var aComp = aCat->GetComponent( "SMESH" );
+ if ( CORBA::is_nil( aComp ) )
+ return aSO._retn();
+
+ SALOMEDS::SComponent_var father =
+ SALOMEDS::SComponent::_narrow( theStudy->FindObject( strdup( aComp->componentusername() ) ) );
+ SALOMEDS::StudyBuilder_var aStudyBuilder = theStudy->NewBuilder();
+
+ SALOMEDS::GenericAttribute_var anAttr;
+ SALOMEDS::AttributeName_var aName;
+ SALOMEDS::AttributePixMap_var aPixmap;
+
+ if ( father->_is_nil() ) {
+ father = aStudyBuilder->NewComponent( "MESH" );
+ anAttr = aStudyBuilder->FindOrCreateAttribute( father, "AttributeName" );
+ aName = SALOMEDS::AttributeName::_narrow( anAttr );
+ aName ->SetValue( strdup( aComp->componentusername() ) );
+ anAttr = aStudyBuilder->FindOrCreateAttribute( father, "AttributePixMap" );
+ aPixmap = SALOMEDS::AttributePixMap::_narrow( anAttr );
+ aPixmap ->SetPixMap( "ICON_OBJBROWSER_SMESH" );
+ aStudyBuilder->DefineComponentInstance( father, SMESH_Gen::_this() );
+ }
+
+ if ( father->_is_nil() )
+ return aSO._retn();
+
+ SALOMEDS::AttributeIOR_var anIOR;
+ SALOMEDS::AttributeSelectable_var aSelAttr;
+ TCollection_AsciiString anObjName("obj");
+
+ // Publishing a mesh
+ SMESH::SMESH_Mesh_var aMesh = SMESH::SMESH_Mesh::_narrow( theIOR );
+ if( !aMesh->_is_nil() ) {
+ // Find correct free tag
+ long aTag = FindMaxChildTag( father.in() );
+ if ( aTag <= GetAlgorithmsRootTag() )
+ aTag = GetAlgorithmsRootTag() + 1;
+ else
+ aTag++;
+ // Add New Mesh
+ SALOMEDS::SObject_var newMesh = aStudyBuilder->NewObjectToTag( father, aTag );
+ anAttr = aStudyBuilder->FindOrCreateAttribute( newMesh, "AttributePixMap" );
+ aPixmap = SALOMEDS::AttributePixMap::_narrow( anAttr );
+ aPixmap ->SetPixMap( "ICON_SMESH_TREE_MESH" );
+ anAttr = aStudyBuilder->FindOrCreateAttribute( newMesh, "AttributeIOR" );
+ anIOR = SALOMEDS::AttributeIOR::_narrow(anAttr);
+ anIOR ->SetValue( GetORB()->object_to_string( aMesh ) );
+ aSO = SALOMEDS::SObject::_narrow( newMesh );
+ anObjName = TCollection_AsciiString( "Mesh" );
+ }
+
+ // Publishing a sub-mesh
+ SMESH::SMESH_subMesh_var aSubMesh = SMESH::SMESH_subMesh::_narrow( theIOR );
+ if( aSO->_is_nil() && !aSubMesh->_is_nil() ) {
+ // try to obtain a parent mesh's SObject
+ MESSAGE( "********** SMESH_Gen_i::PublishInStudy(): publishing submesh..." );
+ SALOMEDS::SObject_var aParentSO;
+ SMESH::SMESH_Mesh_var aParentMesh;
+ SMESH_subMesh_i* aServant = dynamic_cast<SMESH_subMesh_i*>( GetServant( aSubMesh ).in() );
+ if ( aServant != NULL ) {
+ aParentMesh = aServant->_mesh_i->_this();
+ if ( !aParentMesh->_is_nil() ) {
+ aParentSO = theStudy->FindObjectIOR( GetORB()->object_to_string( aParentMesh ) );
+ }
+ }
+
+ // Find submesh sub-tree tag
+ if ( !aParentSO->_is_nil() ) {
+ long aRootTag = GetSubMeshOnVertexTag();
+ char* aRootName = "";
+
+ SMESH_Mesh_i* aMeshServant = aServant->_mesh_i;
+ if ( aMeshServant->_mapSubMesh.find( aServant->GetId() ) != aMeshServant->_mapSubMesh.end() ) {
+ MESSAGE( "********** SMESH_Gen_i::PublishInStudy(): local submesh found" )
+ SMESH_subMesh* aLocalSubMesh = aMeshServant->_mapSubMesh[aServant->GetId()];
+ switch ( aLocalSubMesh->GetSubShape().ShapeType() ) {
+ case TopAbs_VERTEX:
+ aRootTag = GetSubMeshOnVertexTag();
+ aRootName = "SubMeshes on Vertex";
+ break;
+ case TopAbs_EDGE:
+ aRootTag = GetSubMeshOnEdgeTag();
+ aRootName = "SubMeshes on Edge";
+ break;
+ case TopAbs_FACE:
+ aRootTag = GetSubMeshOnFaceTag();
+ aRootName = "SubMeshes on Face";
+ break;
+ case TopAbs_SOLID:
+ aRootTag = GetSubMeshOnSolidTag();
+ aRootName = "SubMeshes on Solid";
+ break;
+ default:
+ aRootTag = GetSubMeshOnCompoundTag();
+ aRootName = "SubMeshes on Compound";
+ break;
}
- catch(SALOME_Exception & S_ex)
- {
- THROW_SALOME_CORBA_EXCEPTION(S_ex.what(), SALOME::BAD_PARAM);
+ }
+
+ // Find or create submesh root
+ SALOMEDS::SObject_var aRootSO;
+ if ( !aParentSO->FindSubObject ( aRootTag, aRootSO ) ) {
+ MESSAGE( "********** SMESH_Gen_i::PublishInStudy(): creating submesh root..." )
+ aRootSO = aStudyBuilder->NewObjectToTag( aParentSO, aRootTag );
+ anAttr = aStudyBuilder->FindOrCreateAttribute( aRootSO, "AttributeName" );
+ aName = SALOMEDS::AttributeName::_narrow( anAttr );
+ aName ->SetValue( aRootName );
+ anAttr = aStudyBuilder->FindOrCreateAttribute( aRootSO, "AttributeSelectable" );
+ aSelAttr = SALOMEDS::AttributeSelectable::_narrow( anAttr );
+ aSelAttr ->SetSelectable( false );
+ }
+
+ // Add new submesh to corresponding sub-tree
+ MESSAGE( "********** SMESH_Gen_i::PublishInStudy(): adding submesh to study..." )
+ SALOMEDS::SObject_var newMesh = aStudyBuilder->NewObject( aRootSO );
+ anAttr = aStudyBuilder->FindOrCreateAttribute( newMesh, "AttributePixMap" );
+ aPixmap = SALOMEDS::AttributePixMap::_narrow( anAttr );
+ aPixmap ->SetPixMap( "ICON_SMESH_TREE_MESH" );
+ anAttr = aStudyBuilder->FindOrCreateAttribute( newMesh, "AttributeIOR" );
+ anIOR = SALOMEDS::AttributeIOR::_narrow(anAttr);
+ anIOR ->SetValue( GetORB()->object_to_string( aSubMesh ) );
+ aSO = SALOMEDS::SObject::_narrow( newMesh );
+ anObjName = TCollection_AsciiString( "SubMesh" );
+ }
+ }
+
+ // Publishing a hypothesis or algorithm
+ SMESH::SMESH_Hypothesis_var aHyp = SMESH::SMESH_Hypothesis::_narrow( theIOR );
+ if( aSO->_is_nil() && !aHyp->_is_nil() ) {
+ //Find or Create Hypothesis root
+ SALOMEDS::SObject_var HypothesisRoot;
+ Standard_Integer aRootTag =
+ SMESH::SMESH_Algo::_narrow( theIOR )->_is_nil() ? GetHypothesisRootTag() : GetAlgorithmsRootTag();
+
+ if ( !father->FindSubObject ( aRootTag, HypothesisRoot ) ) {
+ HypothesisRoot = aStudyBuilder->NewObjectToTag( father, aRootTag );
+ anAttr = aStudyBuilder->FindOrCreateAttribute( HypothesisRoot, "AttributeName" );
+ aName = SALOMEDS::AttributeName::_narrow( anAttr );
+ aName ->SetValue( aRootTag == GetHypothesisRootTag() ? "Hypotheses" : "Algorithms" );
+ anAttr = aStudyBuilder->FindOrCreateAttribute( HypothesisRoot, "AttributeSelectable" );
+ aSelAttr = SALOMEDS::AttributeSelectable::_narrow( anAttr );
+ aSelAttr ->SetSelectable( false );
+ anAttr = aStudyBuilder->FindOrCreateAttribute( HypothesisRoot, "AttributePixMap" );
+ aPixmap = SALOMEDS::AttributePixMap::_narrow( anAttr );
+ aPixmap ->SetPixMap( aRootTag == GetHypothesisRootTag() ? "ICON_SMESH_TREE_HYPO" : "ICON_SMESH_TREE_ALGO" );
+ }
+
+ // Add New Hypothesis
+ string aPmName;
+ SALOMEDS::SObject_var newHypo = aStudyBuilder->NewObject( HypothesisRoot );
+ anAttr = aStudyBuilder->FindOrCreateAttribute( newHypo, "AttributePixMap" );
+ aPixmap = SALOMEDS::AttributePixMap::_narrow( anAttr );
+ aPmName = ( aRootTag == GetHypothesisRootTag() ? "ICON_SMESH_TREE_HYPO_" : "ICON_SMESH_TREE_ALGO_" );
+ aPmName += aHyp->GetName();
+ aPixmap ->SetPixMap( aPmName.c_str() );
+ anAttr = aStudyBuilder->FindOrCreateAttribute( newHypo, "AttributeIOR" );
+ anIOR = SALOMEDS::AttributeIOR::_narrow(anAttr);
+ anIOR ->SetValue( GetORB()->object_to_string( aHyp ) );
+ aSO = SALOMEDS::SObject::_narrow( newHypo );
+ anObjName = TCollection_AsciiString( aHyp->GetName() );
+ }
+
+ // Publishing a group
+ SMESH::SMESH_Group_var aGroup = SMESH::SMESH_Group::_narrow(theIOR);
+ if( aSO->_is_nil() && !aGroup->_is_nil() ) {
+ // try to obtain a parent mesh's SObject
+ MESSAGE( "********** SMESH_Gen_i::PublishInStudy(): publishing group..." );
+ SALOMEDS::SObject_var aParentSO;
+ SMESH::SMESH_Mesh_var aParentMesh;
+ SMESH_Group_i* aServant = dynamic_cast<SMESH_Group_i*>( GetServant( aGroup ).in() );
+ if ( aServant != NULL ) {
+ aParentMesh = SMESH::SMESH_Mesh::_narrow( GetPOA()->servant_to_reference( aServant->GetMeshServant() ) );
+ if ( !aParentMesh->_is_nil() ) {
+ MESSAGE( "********** SMESH_Gen_i::PublishInStudy(): publishing group: refernce to mesh is OK" );
+ string anIOR = GetORB()->object_to_string( aParentMesh );
+ MESSAGE( "********** SMESH_Gen_i::PublishInStudy(): publishing group: mesh IOR = "<<anIOR.c_str() );
+ aParentSO = theStudy->FindObjectIOR( anIOR.c_str() );
+ }
+ }
+
+ // Find proper group sub-tree tag
+ if ( !aParentSO->_is_nil() ) {
+ MESSAGE( "********** SMESH_Gen_i::PublishInStudy(): publishing group: parent mesh found" );
+ int aType = (int)aGroup->GetType();
+ const char* aRootNames[] = { "Compound Groups", "Groups of Nodes", "Groups of Edges", "Groups of Faces", "Groups of Volumes" };
+
+ // Currently, groups with heterogenous content are not supported
+ if ( aType != SMESH::ALL ) {
+ MESSAGE( "********** SMESH_Gen_i::PublishInStudy(): publishing group: group type OK" );
+ long aRootTag = GetNodeGroupsTag() + aType - 1;
+
+ // Find or create groups root
+ SALOMEDS::SObject_var aRootSO;
+ if ( !aParentSO->FindSubObject ( aRootTag, aRootSO ) ) {
+ MESSAGE( "********** SMESH_Gen_i::PublishInStudy(): creating groups root..." )
+ aRootSO = aStudyBuilder->NewObjectToTag( aParentSO, aRootTag );
+ anAttr = aStudyBuilder->FindOrCreateAttribute( aRootSO, "AttributeName" );
+ aName = SALOMEDS::AttributeName::_narrow( anAttr );
+ aName ->SetValue( aRootNames[aType] );
+ anAttr = aStudyBuilder->FindOrCreateAttribute( aRootSO, "AttributeSelectable" );
+ aSelAttr = SALOMEDS::AttributeSelectable::_narrow( anAttr );
+ aSelAttr ->SetSelectable( false );
}
- // activate the CORBA servant of Mesh
-
- SMESH::SMESH_Mesh_var mesh
- = SMESH::SMESH_Mesh::_narrow(meshServant->_this());
-
- meshServant->SetIor(mesh);
- return SMESH::SMESH_Mesh::_duplicate(mesh);
+ // Add new group to corresponding sub-tree
+ MESSAGE( "********** SMESH_Gen_i::PublishInStudy(): adding group to study..." )
+ SALOMEDS::SObject_var aGroupSO = aStudyBuilder->NewObject( aRootSO );
+ anAttr = aStudyBuilder->FindOrCreateAttribute( aGroupSO, "AttributePixMap" );
+ aPixmap = SALOMEDS::AttributePixMap::_narrow( anAttr );
+ aPixmap ->SetPixMap( "ICON_SMESH_TREE_GROUP" );
+ anAttr = aStudyBuilder->FindOrCreateAttribute( aGroupSO, "AttributeIOR" );
+ anIOR = SALOMEDS::AttributeIOR::_narrow( anAttr );
+ anIOR ->SetValue( GetORB()->object_to_string( aGroup ) );
+ aSO = SALOMEDS::SObject::_narrow( aGroupSO );
+ anObjName = TCollection_AsciiString( "Group" );
+ }
+ }
+ }
+
+ // Setting SObject's name
+ if ( !aSO->_is_nil() ) {
+ if ( strlen( theName ) == 0 )
+ anObjName += TCollection_AsciiString( "_" ) + TCollection_AsciiString( aSO->Tag() );
+ else
+ anObjName = TCollection_AsciiString( strdup( theName ) );
+ anAttr = aStudyBuilder->FindOrCreateAttribute( aSO, "AttributeName" );
+ aName = SALOMEDS::AttributeName::_narrow( anAttr );
+ aName ->SetValue( anObjName.ToCString() );
+ }
+
+ MESSAGE( "********** SMESH_Gen_i::PublishInStudy(): COMPLETED" )
+ return aSO._retn();
}
-
+
//=============================================================================
/*!
- * C factory, accessible with dlsym, after dlopen
+ * SMESHEngine_factory
+ *
+ * C factory, accessible with dlsym, after dlopen
*/
//=============================================================================
extern "C"
{
- PortableServer::ObjectId * SMESHEngine_factory(CORBA::ORB_ptr orb,
- PortableServer::POA_ptr poa,
- PortableServer::ObjectId * contId,
- const char *instanceName, const char *interfaceName)
- {
- MESSAGE("PortableServer::ObjectId * SMESHEngine_factory()");
- SCRUTE(interfaceName);
- SMESH_Gen_i *mySMESH_Gen
- = new SMESH_Gen_i(orb, poa, contId, instanceName, interfaceName);
- return mySMESH_Gen->getId();
- }
+ PortableServer::ObjectId* SMESHEngine_factory( CORBA::ORB_ptr orb,
+ PortableServer::POA_ptr poa,
+ PortableServer::ObjectId* contId,
+ const char* instanceName,
+ const char* interfaceName )
+ {
+ MESSAGE( "PortableServer::ObjectId* SMESHEngine_factory()" );
+ SCRUTE(interfaceName);
+ SMESH_Gen_i * mySMESH_Gen
+ = new SMESH_Gen_i(orb, poa, contId, instanceName, interfaceName);
+ return mySMESH_Gen->getId() ;
+ }
}
#include CORBA_CLIENT_HEADER(SALOMEDS)
#include CORBA_CLIENT_HEADER(SALOMEDS_Attributes)
-
-class SMESH_Mesh_i;
-
-#include "SMESH_HypothesisFactory_i.hxx"
#include "SMESH_Mesh_i.hxx"
+#include "SMESH_Hypothesis_i.hxx"
#include "SALOME_Component_i.hxx"
#include "SALOME_NamingService.hxx"
#include "SMESH_topo.hxx"
#include "GEOM_Client.hxx"
-#include <HDFOI.hxx>
-
#include <map>
-typedef struct studyContext_iStruct
+class SMESH_Mesh_i;
+class SALOME_LifeCycleCORBA;
+
+// ===========================================================
+// Study context - stores study-connected objects references
+// ==========================================================
+class StudyContext
{
- map<int,SMESH_Mesh_i*> mapMesh_i;
-} StudyContext_iStruct;
+public:
+ // constructor
+ StudyContext() {}
+ // destructor
+ ~StudyContext()
+ {
+ mapIdToIOR.clear();
+ mapIdToId.clear();
+ }
+ // register object in the internal map and return its id
+ int addObject( string theIOR )
+ {
+ int nextId = getNextId();
+ mapIdToIOR[ nextId ] = theIOR;
+ return nextId;
+ }
+ // find the object id in the internal map by the IOR
+ int findId( string theIOR )
+ {
+ map<int, string>::iterator imap;
+ for ( imap = mapIdToIOR.begin(); imap != mapIdToIOR.end(); ++imap ) {
+ if ( imap->second == theIOR )
+ return imap->first;
+ }
+ return 0;
+ }
+ // get object's IOR by id
+ string getIORbyId( const int theId )
+ {
+ if ( mapIdToIOR.find( theId ) != mapIdToIOR.end() )
+ return mapIdToIOR[ theId ];
+ return string( "" );
+ }
+ // get object's IOR by old id
+ string getIORbyOldId( const int theOldId )
+ {
+ if ( mapIdToId.find( theOldId ) != mapIdToId.end() )
+ return getIORbyId( mapIdToId[ theOldId ] );
+ return string( "" );
+ }
+ // maps old object id to the new one (used when restoring data)
+ void mapOldToNew( const int oldId, const int newId ) {
+ mapIdToId[ oldId ] = newId;
+ }
+
+private:
+ // get next free object identifier
+ int getNextId()
+ {
+ int id = 1;
+ while( mapIdToIOR.find( id ) != mapIdToIOR.end() )
+ id++;
+ return id;
+ }
+
+ map<int, string> mapIdToIOR; // persistent-to-transient map
+ map<int, int> mapIdToId; // used to translate object from persistent to transient form
+};
+// ===========================================================
+// SMESH module's engine
+// ==========================================================
class SMESH_Gen_i:
- public POA_SMESH::SMESH_Gen,
- public Engines_Component_i
+ public virtual POA_SMESH::SMESH_Gen,
+ public virtual Engines_Component_i
{
public:
+ // Get ORB object
+ static CORBA::ORB_var GetORB() { return myOrb;}
+ // Get SMESH module's POA object
+ static PortableServer::POA_var GetPOA() { return myPoa;}
+ // Get Naming Service object
+ static SALOME_NamingService* GetNS();
+ // Get SALOME_LifeCycleCORBA object
+ static SALOME_LifeCycleCORBA* GetLCC();
+ // Retrieve and get GEOM engine reference
+ static GEOM::GEOM_Gen_ptr GetGeomEngine();
+ // Get object of the CORBA reference
+ static PortableServer::ServantBase_var GetServant( CORBA::Object_ptr theObject );
+ // Get CORBA object corresponding to the SALOMEDS::SObject
+ static CORBA::Object_var SObjectToObject( SALOMEDS::SObject_ptr theSObject );
+ // Default constructor
SMESH_Gen_i();
- SMESH_Gen_i(CORBA::ORB_ptr orb,
- PortableServer::POA_ptr poa,
- PortableServer::ObjectId * contId,
- const char *instanceName,
- const char *interfaceName);
+ // Standard constructor
+ SMESH_Gen_i( CORBA::ORB_ptr orb,
+ PortableServer::POA_ptr poa,
+ PortableServer::ObjectId* contId,
+ const char* instanceName,
+ const char* interfaceName );
+ // Destructor
virtual ~SMESH_Gen_i();
- SMESH::SMESH_Hypothesis_ptr CreateHypothesis(const char* anHyp,
- CORBA::Long studyId)
- throw (SALOME::SALOME_Exception);
+ // *****************************************
+ // Interface methods
+ // *****************************************
+
+ // Set current study
+ void SetCurrentStudy( SALOMEDS::Study_ptr theStudy );
+ // Get current study
+ SALOMEDS::Study_ptr GetCurrentStudy();
+
+ // Create hypothesis/algorothm of given type
+ SMESH::SMESH_Hypothesis_ptr CreateHypothesis (const char* theHypType,
+ const char* theLibName)
+ throw ( SALOME::SALOME_Exception );
+
+ // Create empty mesh on a shape
+ SMESH::SMESH_Mesh_ptr CreateMesh( GEOM::GEOM_Shape_ptr theShape )
+ throw ( SALOME::SALOME_Exception );
+
+ // Create mesh(es) and import data from MED file
+ SMESH::mesh_array* CreateMeshesFromMED( const char* theFileName,
+ SMESH::DriverMED_ReadStatus& theStatus )
+ throw ( SALOME::SALOME_Exception );
+
+ // Compute mesh on a shape
+ CORBA::Boolean Compute( SMESH::SMESH_Mesh_ptr theMesh,
+ GEOM::GEOM_Shape_ptr theShape )
+ throw ( SALOME::SALOME_Exception );
+
+ // Returns true if mesh contains enough data to be computed
+ CORBA::Boolean IsReadyToCompute( SMESH::SMESH_Mesh_ptr theMesh,
+ GEOM::GEOM_Shape_ptr theShape )
+ throw ( SALOME::SALOME_Exception );
+
+ // Get sub-shapes unique ID's list
+ SMESH::long_array* GetSubShapesId( GEOM::GEOM_Shape_ptr theMainShape,
+ const SMESH::shape_array& theListOfSubShape )
+ throw ( SALOME::SALOME_Exception );
+
+
+ // ****************************************************
+ // Interface inherited methods (from SALOMEDS::Driver)
+ // ****************************************************
+
+ // Save SMESH data
+ SALOMEDS::TMPFile* Save( SALOMEDS::SComponent_ptr theComponent,
+ const char* theURL,
+ bool isMultiFile );
+ // Load SMESH data
+ bool Load( SALOMEDS::SComponent_ptr theComponent,
+ const SALOMEDS::TMPFile& theStream,
+ const char* theURL,
+ bool isMultiFile );
+ // Save SMESH data in ASCII format
+ SALOMEDS::TMPFile* SaveASCII( SALOMEDS::SComponent_ptr theComponent,
+ const char* theURL,
+ bool isMultiFile );
+ // Load SMESH data in ASCII format
+ bool LoadASCII( SALOMEDS::SComponent_ptr theComponent,
+ const SALOMEDS::TMPFile& theStream,
+ const char* theURL,
+ bool isMultiFile );
+
+ // Create filter manager
+ SMESH::FilterManager_ptr CreateFilterManager();
+
+ // Clears study-connected data when it is closed
+ void Close( SALOMEDS::SComponent_ptr theComponent );
- SMESH::SMESH_Mesh_ptr Init(GEOM::GEOM_Gen_ptr geomEngine,
- CORBA::Long studyId,
- GEOM::GEOM_Shape_ptr aShape)
- throw (SALOME::SALOME_Exception);
-
- SMESH::SMESH_Mesh_ptr Init(GEOM::GEOM_Gen_ptr geomEngine,
- CORBA::Long studyId,
- GEOM::GEOM_Shape_ptr aShape,
- int meshID)
- throw (SALOME::SALOME_Exception);
-
- CORBA::Boolean Compute(SMESH::SMESH_Mesh_ptr aMesh,
- GEOM::GEOM_Shape_ptr aShape)
- throw (SALOME::SALOME_Exception);
-
- CORBA::Boolean IsReadyToCompute(SMESH::SMESH_Mesh_ptr aMesh,
- GEOM::GEOM_Shape_ptr aShape)
- throw (SALOME::SALOME_Exception);
-
- SMESH::long_array* GetSubShapesId(GEOM::GEOM_Gen_ptr geomEngine,
- CORBA::Long studyId,
- GEOM::GEOM_Shape_ptr mainShape,
- const SMESH::shape_array& listOfSubShape)
- throw (SALOME::SALOME_Exception);
-
- SMESH::SMESH_Mesh_ptr Import(CORBA::Long studyId, const char* fileName,
- const char* fileType);
-
- // inherited methods from SALOMEDS::Driver
-
- SALOMEDS::TMPFile* Save(SALOMEDS::SComponent_ptr theComponent,
- const char* theURL,
- bool isMultiFile);
- bool Load(SALOMEDS::SComponent_ptr theComponent,
- const SALOMEDS::TMPFile& theStream,
- const char* theURL,
- bool isMultiFile);
-
- SALOMEDS::TMPFile* SaveASCII(SALOMEDS::SComponent_ptr theComponent,
- const char* theURL,
- bool isMultiFile);
- bool LoadASCII(SALOMEDS::SComponent_ptr theComponent,
- const SALOMEDS::TMPFile& theStream,
- const char* theURL,
- bool isMultiFile);
-
- void Close(SALOMEDS::SComponent_ptr theComponent);
+ // Get component data type
char* ComponentDataType();
- char* IORToLocalPersistentID(SALOMEDS::SObject_ptr theSObject,
- const char* IORString,
- CORBA::Boolean isMultiFile,
- CORBA::Boolean isASCII);
- char* LocalPersistentIDToIOR(SALOMEDS::SObject_ptr theSObject,
- const char* aLocalPersistentID,
- CORBA::Boolean isMultiFile,
- CORBA::Boolean isASCII);
-
- bool CanPublishInStudy(CORBA::Object_ptr theIOR) { return false; }
- SALOMEDS::SObject_ptr PublishInStudy(SALOMEDS::Study_ptr theStudy,
- SALOMEDS::SObject_ptr theSObject,
- CORBA::Object_ptr theObject,
- const char* theName) throw (SALOME::SALOME_Exception) {
- SALOMEDS::SObject_var aResultSO;
- return aResultSO._retn();
- }
+ // Transform data from transient form to persistent
+ char* IORToLocalPersistentID( SALOMEDS::SObject_ptr theSObject,
+ const char* IORString,
+ CORBA::Boolean isMultiFile,
+ CORBA::Boolean isASCII );
+ // Transform data from persistent form to transient
+ char* LocalPersistentIDToIOR( SALOMEDS::SObject_ptr theSObject,
+ const char* aLocalPersistentID,
+ CORBA::Boolean isMultiFile,
+ CORBA::Boolean isASCII );
+
+ // Returns true if object can be published in the study
+ bool CanPublishInStudy( CORBA::Object_ptr theIOR );
+ // Publish object in the study
+ SALOMEDS::SObject_ptr PublishInStudy( SALOMEDS::Study_ptr theStudy,
+ SALOMEDS::SObject_ptr theSObject,
+ CORBA::Object_ptr theObject,
+ const char* theName )
+ throw ( SALOME::SALOME_Exception );
- CORBA::Boolean CanCopy(SALOMEDS::SObject_ptr theObject) {return false;}
- SALOMEDS::TMPFile* CopyFrom(SALOMEDS::SObject_ptr theObject, CORBA::Long& theObjectID) {return false;}
- CORBA::Boolean CanPaste(const char* theComponentName, CORBA::Long theObjectID) {return false;}
- SALOMEDS::SObject_ptr PasteInto(const SALOMEDS::TMPFile& theStream,
- CORBA::Long theObjectID,
- SALOMEDS::SObject_ptr theObject) {
+ // Copy-paste methods - returns true if object can be copied to the clipboard
+ CORBA::Boolean CanCopy( SALOMEDS::SObject_ptr theObject ) { return false; }
+ // Copy-paste methods - copy object to the clipboard
+ SALOMEDS::TMPFile* CopyFrom( SALOMEDS::SObject_ptr theObject, CORBA::Long& theObjectID ) { return false; }
+ // Copy-paste methods - returns true if object can be pasted from the clipboard
+ CORBA::Boolean CanPaste( const char* theComponentName, CORBA::Long theObjectID ) { return false; }
+ // Copy-paste methods - paste object from the clipboard
+ SALOMEDS::SObject_ptr PasteInto( const SALOMEDS::TMPFile& theStream,
+ CORBA::Long theObjectID,
+ SALOMEDS::SObject_ptr theObject ) {
SALOMEDS::SObject_var aResultSO;
return aResultSO._retn();
}
- GEOM_Client* _ShapeReader;
-protected:
- SMESH_topo* ExploreMainShape(GEOM::GEOM_Gen_ptr geomEngine,
- CORBA::Long studyId,
- GEOM::GEOM_Shape_ptr aShape);
+ // *****************************************
+ // Internal methods
+ // *****************************************
+public:
+ // Get shape reader
+ GEOM_Client* GetShapeReader();
+
+ // Tags definition
+ static long GetHypothesisRootTag();
+ static long GetAlgorithmsRootTag();
+ static long GetRefOnShapeTag();
+ static long GetRefOnAppliedHypothesisTag();
+ static long GetRefOnAppliedAlgorithmsTag();
+ static long GetSubMeshOnVertexTag();
+ static long GetSubMeshOnEdgeTag();
+ static long GetSubMeshOnFaceTag();
+ static long GetSubMeshOnSolidTag();
+ static long GetSubMeshOnCompoundTag();
+ static long GetNodeGroupsTag();
+ static long GetEdgeGroupsTag();
+ static long GetFaceGroupsTag();
+ static long GetVolumeGroupsTag();
+
+ // Get study context
+ StudyContext* GetCurrentStudyContext();
+
+private:
+ // Create hypothesis of given type
+ SMESH::SMESH_Hypothesis_ptr createHypothesis( const char* theHypName,
+ const char* theLibName)
+ throw ( SALOME::SALOME_Exception );
+
+ // Create empty mesh on shape
+ SMESH::SMESH_Mesh_ptr createMesh()
+ throw ( SALOME::SALOME_Exception );
+
+ static void loadGeomData( SALOMEDS::SComponent_ptr theCompRoot );
private:
- void loadMesh(char * name, HDFfile * hdf_file, char * meshFile,
- SALOMEDS::Study_var study);
- void loadHypothesis(char * name, HDFfile * hdf_file, char * hypothesisFile,
- int studyId);
- void loadAlgorithms(char * name, HDFfile * hdf_file, char * algorithmsFile,
- int studyId);
- void loadAppliedHypothesis(HDFgroup * hdfGroupMeshId, bool _found,
- SALOMEDS::Study_var Study, SMESH::SMESH_Mesh_var myNewMesh,
- GEOM::GEOM_Shape_var aShape);
- GEOM::GEOM_Gen_var getGeomEngine();
- GEOM::GEOM_Shape_var getShape(SALOMEDS::Study_var Study, char * refFromFile);
-
-void loadAppliedAlgorithms(HDFgroup * hdfGroupMeshId,
- bool _found, SALOMEDS::Study_var Study, SMESH::SMESH_Mesh_var myNewMesh,
- GEOM::GEOM_Shape_var aShape);
-void loadSubMeshes(HDFgroup * hdfGroupMeshId, char * msgname,
- SALOMEDS::Study_var Study, SMESH::SMESH_Mesh_var myNewMesh);
-
- SMESH_HypothesisFactory_i _hypothesisFactory_i;
- ::SMESH_Gen _impl; // no namespace here
-
- map<int, StudyContext_iStruct*> _mapStudyContext_i;
- map <string, string> _SMESHCorbaObj;
+
+ static CORBA::ORB_var myOrb; // ORB reference
+ static PortableServer::POA_var myPoa; // POA reference
+ static SALOME_NamingService* myNS; // Naming Service
+ static SALOME_LifeCycleCORBA* myLCC; // Life Cycle CORBA
+
+ ::SMESH_Gen myGen; // SMESH_Gen local implementation
+
+ // hypotheses managing
+ map<string, GenericHypothesisCreator_i*> myHypCreatorMap;
+
+ map<int, StudyContext*> myStudyContextMap; // Map of study context objects
+
+ GEOM_Client* myShapeReader; // Shape reader
+ SALOMEDS::Study_var myCurrentStudy; // Current study
};
#endif
--- /dev/null
+// SMESH SMESH_I : idl implementation based on 'SMESH' unit's classes
+//
+// Copyright (C) 2004 CEA
+//
+// This library 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.
+//
+// This library 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 this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+//
+// See http://www.salome-platform.org or email : webmaster.salome@opencascade.org
+//
+//
+//
+// File : SMESH_Group_i.cxx
+// Author : Sergey ANIKIN, OCC
+// Module : SMESH
+// $Header$
+
+#include "SMESH_Group_i.hxx"
+#include "SMESH_Mesh_i.hxx"
+#include "SMESH_Gen_i.hxx"
+#include <SMESH_Group.hxx>
+#include <SMESHDS_Group.hxx>
+#include <SMDSAbs_ElementType.hxx>
+#include <utilities.h>
+
+//=============================================================================
+/*!
+ *
+ */
+//=============================================================================
+
+SMESH_Group_i::SMESH_Group_i( PortableServer::POA_ptr thePOA, SMESH_Mesh_i* theMeshServant, const int theLocalID )
+: SALOME::GenericObj_i( thePOA ),
+ myMeshServant( theMeshServant ),
+ myLocalID( theLocalID )
+{
+ thePOA->activate_object( this );
+}
+
+
+//=============================================================================
+/*!
+ *
+ */
+//=============================================================================
+
+SMESH_Group_i::~SMESH_Group_i()
+{
+ MESSAGE("~SMESH_Group_i;" );
+ if ( myMeshServant )
+ myMeshServant->removeGroup(myLocalID);
+}
+
+
+//=============================================================================
+/*!
+ *
+ */
+//=============================================================================
+
+void SMESH_Group_i::SetName( const char* theName )
+{
+ if ( myMeshServant ) {
+ ::SMESH_Mesh& aMesh = myMeshServant->GetImpl();
+ ::SMESH_Group* aGroup = aMesh.GetGroup(myLocalID);
+ if (aGroup) {
+ aGroup->SetName(theName);
+
+ // Update group name in a study
+ SALOMEDS::Study_var aStudy = myMeshServant->GetGen()->GetCurrentStudy();
+ if ( !aStudy->_is_nil() ) {
+ SALOMEDS::SObject_var aGroupSO = aStudy->FindObjectIOR( SMESH_Gen_i::GetORB()->object_to_string( _this() ) );
+ if ( !aGroupSO->_is_nil() ) {
+ SALOMEDS::StudyBuilder_var aBuilder = aStudy->NewBuilder();
+ aBuilder->SetName( aGroupSO, theName );
+ }
+ }
+ return;
+ }
+ }
+ MESSAGE("can't set name of a vague group");
+}
+
+
+//=============================================================================
+/*!
+ *
+ */
+//=============================================================================
+
+char* SMESH_Group_i::GetName()
+{
+ if ( myMeshServant ) {
+ ::SMESH_Mesh& aMesh = myMeshServant->GetImpl();
+ ::SMESH_Group* aGroup = aMesh.GetGroup(myLocalID);
+ if (aGroup)
+ return CORBA::string_dup (aGroup->GetName());
+ }
+ MESSAGE("get name of a vague group");
+ return CORBA::string_dup( "NO_NAME" );
+}
+
+
+//=============================================================================
+/*!
+ *
+ */
+//=============================================================================
+
+SMESH::ElementType SMESH_Group_i::GetType()
+{
+ if ( myMeshServant ) {
+ ::SMESH_Mesh& aMesh = myMeshServant->GetImpl();
+ ::SMESH_Group* aGroup = aMesh.GetGroup(myLocalID);
+ if (aGroup) {
+ SMDSAbs_ElementType aSMDSType = aGroup->GetGroupDS()->GetType();
+ SMESH::ElementType aType;
+ switch (aSMDSType) {
+ case SMDSAbs_Node: aType = SMESH::NODE; break;
+ case SMDSAbs_Edge: aType = SMESH::EDGE; break;
+ case SMDSAbs_Face: aType = SMESH::FACE; break;
+ case SMDSAbs_Volume: aType = SMESH::VOLUME; break;
+ default: aType = SMESH::ALL; break;
+ }
+ return aType;
+ }
+ }
+ MESSAGE("get type of a vague group");
+ return SMESH::ALL;
+}
+
+
+//=============================================================================
+/*!
+ *
+ */
+//=============================================================================
+
+CORBA::Long SMESH_Group_i::Size()
+{
+ if ( myMeshServant ) {
+ ::SMESH_Mesh& aMesh = myMeshServant->GetImpl();
+ ::SMESH_Group* aGroup = aMesh.GetGroup(myLocalID);
+ if (aGroup) {
+ int aSize = aGroup->GetGroupDS()->Extent();
+ return aSize;
+ }
+ }
+ MESSAGE("get size of a vague group");
+ return 0;
+}
+
+
+//=============================================================================
+/*!
+ *
+ */
+//=============================================================================
+
+CORBA::Boolean SMESH_Group_i::IsEmpty()
+{
+ if ( myMeshServant ) {
+ ::SMESH_Mesh& aMesh = myMeshServant->GetImpl();
+ ::SMESH_Group* aGroup = aMesh.GetGroup(myLocalID);
+ if (aGroup) {
+ bool isEmpty = aGroup->GetGroupDS()->IsEmpty();
+ return isEmpty;
+ }
+ }
+ MESSAGE("checking IsEmpty of a vague group");
+ return true;
+}
+
+
+//=============================================================================
+/*!
+ *
+ */
+//=============================================================================
+
+void SMESH_Group_i::Clear()
+{
+ if ( myMeshServant ) {
+ ::SMESH_Mesh& aMesh = myMeshServant->GetImpl();
+ ::SMESH_Group* aGroup = aMesh.GetGroup(myLocalID);
+ if (aGroup) {
+ // a SMDS group forgets its type after clearing, so we must re-set it
+ SMDSAbs_ElementType aSMDSType = aGroup->GetGroupDS()->GetType();
+ aGroup->GetGroupDS()->Clear();
+ aGroup->GetGroupDS()->SetType(aSMDSType);
+ return;
+ }
+ }
+ MESSAGE("attempt to clear a vague group");
+}
+
+
+//=============================================================================
+/*!
+ *
+ */
+//=============================================================================
+
+CORBA::Boolean SMESH_Group_i::Contains( CORBA::Long theID )
+{
+ if ( myMeshServant ) {
+ ::SMESH_Mesh& aMesh = myMeshServant->GetImpl();
+ ::SMESH_Group* aGroup = aMesh.GetGroup(myLocalID);
+ if (aGroup) {
+ bool res = aGroup->GetGroupDS()->Contains(theID);
+ return res;
+ }
+ }
+ MESSAGE("attempt to check contents of a vague group");
+ return false;
+}
+
+
+//=============================================================================
+/*!
+ *
+ */
+//=============================================================================
+
+CORBA::Long SMESH_Group_i::Add( const SMESH::long_array& theIDs )
+{
+ if ( myMeshServant ) {
+ ::SMESH_Mesh& aMesh = myMeshServant->GetImpl();
+ ::SMESH_Group* aGroup = aMesh.GetGroup(myLocalID);
+ if (aGroup) {
+ SMESHDS_Group* aGroupDS = aGroup->GetGroupDS();
+ int nbAdd = 0;
+ for (int i = 0; i < theIDs.length(); i++) {
+ int anID = (int) theIDs[i];
+ if (aGroupDS->Add(anID))
+ nbAdd++;
+ }
+ return nbAdd;
+ }
+ }
+ MESSAGE("attempt to add elements to a vague group");
+ return 0;
+}
+
+
+//=============================================================================
+/*!
+ *
+ */
+//=============================================================================
+
+CORBA::Long SMESH_Group_i::GetID( CORBA::Long theIndex )
+{
+ if ( myMeshServant ) {
+ ::SMESH_Mesh& aMesh = myMeshServant->GetImpl();
+ ::SMESH_Group* aGroup = aMesh.GetGroup(myLocalID);
+ if (aGroup) {
+ int anID = aGroup->GetGroupDS()->GetID(theIndex);
+ return anID;
+ }
+ }
+ MESSAGE("attempt to iterate on a vague group");
+ return -1;
+}
+
+
+//=============================================================================
+/*!
+ *
+ */
+//=============================================================================
+
+SMESH::long_array* SMESH_Group_i::GetListOfID()
+{
+ SMESH::long_array_var aRes = new SMESH::long_array();
+ if ( myMeshServant ) {
+ ::SMESH_Mesh& aMesh = myMeshServant->GetImpl();
+ ::SMESH_Group* aGroup = aMesh.GetGroup(myLocalID);
+ if (aGroup) {
+ SMESHDS_Group* aGroupDS = aGroup->GetGroupDS();
+ int aSize = aGroupDS->Extent();
+ aRes->length(aSize);
+ for (int i = 0; i < aSize; i++)
+ aRes[i] = aGroupDS->GetID(i+1);
+ return aRes._retn();
+ }
+ }
+ MESSAGE("get list of IDs of a vague group");
+ return aRes._retn();
+}
+
+
+//=============================================================================
+/*!
+ *
+ */
+//=============================================================================
+
+CORBA::Long SMESH_Group_i::Remove( const SMESH::long_array& theIDs )
+{
+ if ( myMeshServant ) {
+ ::SMESH_Mesh& aMesh = myMeshServant->GetImpl();
+ ::SMESH_Group* aGroup = aMesh.GetGroup(myLocalID);
+ if (aGroup) {
+ // a SMDS group forgets its type after clearing, so we must re-set it
+ // if the group becomes empty
+ SMDSAbs_ElementType aSMDSType = aGroup->GetGroupDS()->GetType();
+ SMESHDS_Group* aGroupDS = aGroup->GetGroupDS();
+ int nbDel = 0;
+ for (int i = 0; i < theIDs.length(); i++) {
+ int anID = (int) theIDs[i];
+ if (aGroupDS->Remove(anID))
+ nbDel++;
+ }
+ if (aGroupDS->IsEmpty())
+ aGroupDS->SetType(aSMDSType);
+ return nbDel;
+ }
+ }
+ MESSAGE("attempt to remove elements from a vague group");
+ return 0;
+}
+
+
+//=============================================================================
+/*!
+ *
+ */
+//=============================================================================
+SMESH::SMESH_Mesh_ptr SMESH_Group_i::GetMesh()
+{
+ MESSAGE("SMESH_Group_i::GetMesh(): mesh servant = " << myMeshServant );
+ SMESH::SMESH_Mesh_var aMesh;
+ if ( myMeshServant )
+ aMesh = SMESH::SMESH_Mesh::_narrow( myMeshServant->_this() );
+ return aMesh._retn();
+}
+
+
+//=============================================================================
+/*!
+ *
+ */
+//=============================================================================
+int SMESH_Group_i::GetLocalID()
+{
+ return myLocalID;
+}
--- /dev/null
+// SMESH SMESH_I : idl implementation based on 'SMESH' unit's classes
+//
+// Copyright (C) 2004 CEA
+//
+// This library 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.
+//
+// This library 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 this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+//
+// See http://www.salome-platform.org or email : webmaster.salome@opencascade.org
+//
+//
+//
+// File : SMESH_Group_i.hxx
+// Author : Sergey ANIKIN, OCC
+// Module : SMESH
+// $Header$
+
+#ifndef SMESH_Group_i_HeaderFile
+#define SMESH_Group_i_HeaderFile
+
+#include <SALOMEconfig.h>
+#include CORBA_SERVER_HEADER(SMESH_Group)
+#include CORBA_SERVER_HEADER(SMESH_Mesh)
+
+#include "SALOME_GenericObj_i.hh"
+
+class SMESH_Mesh_i;
+
+class SMESH_Group_i:
+ public virtual POA_SMESH::SMESH_Group,
+ public virtual SALOME::GenericObj_i
+{
+public:
+ SMESH_Group_i( PortableServer::POA_ptr thePOA, SMESH_Mesh_i* theMeshServant, const int theLocalID );
+ virtual ~SMESH_Group_i();
+
+ // CORBA interface implementation
+ void SetName( const char* theName );
+
+ char* GetName();
+
+ SMESH::ElementType GetType();
+
+ CORBA::Long Size();
+
+ CORBA::Boolean IsEmpty();
+
+ void Clear();
+
+ CORBA::Boolean Contains( CORBA::Long theID );
+
+ CORBA::Long Add( const SMESH::long_array& theIDs );
+
+ CORBA::Long GetID( CORBA::Long theIndex );
+
+ SMESH::long_array* GetListOfID();
+
+ CORBA::Long Remove( const SMESH::long_array& theIDs );
+
+ SMESH::SMESH_Mesh_ptr GetMesh();
+
+ // Internal C++ interface
+ int GetLocalID();
+
+ SMESH_Mesh_i* GetMeshServant() { return myMeshServant; }
+
+private:
+ SMESH_Mesh_i* myMeshServant;
+ int myLocalID;
+};
+
+#endif
+++ /dev/null
-// SMESH SMESH_I : idl implementation based on 'SMESH' unit's calsses
-//
-// Copyright (C) 2003 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
-// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
-//
-// This library 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.
-//
-// This library 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 this library; if not, write to the Free Software
-// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
-//
-// See http://www.opencascade.org/SALOME/ or email : webmaster.salome@opencascade.org
-//
-//
-//
-// File : SMESH_Hexa_3D_i.cxx
-// Author : Paul RASCLE, EDF
-// Module : SMESH
-// $Header$
-
-using namespace std;
-using namespace std;
-#include "SMESH_Hexa_3D_i.hxx"
-#include "SMESH_Gen.hxx"
-#include "SMESH_HypothesisFactory.hxx"
-
-#include "Utils_CorbaException.hxx"
-#include "utilities.h"
-
-//=============================================================================
-/*!
- *
- */
-//=============================================================================
-
-SMESH_Hexa_3D_i::SMESH_Hexa_3D_i(const char* anHyp,
- int studyId,
- ::SMESH_Gen* genImpl)
-{
- MESSAGE("SMESH_Hexa_3D_i::SMESH_Hexa_3D_i");
- _genImpl = genImpl;
- ::SMESH_Hexa_3D* impl
- = new ::SMESH_Hexa_3D(_genImpl->_hypothesisFactory.GetANewId(),
- studyId,
- genImpl);
- SetImpl(impl);
- _baseImpl = _impl;
-}
-
-//=============================================================================
-/*!
- *
- */
-//=============================================================================
-
-SMESH_Hexa_3D_i::~SMESH_Hexa_3D_i()
-{
- MESSAGE("SMESH_Hexa_3D_i::~SMESH_Hexa_3D_i");
-}
-
-//=============================================================================
-/*!
- *
- */
-//=============================================================================
-
-void SMESH_Hexa_3D_i::SetImpl(::SMESH_Hexa_3D* impl)
-{
- MESSAGE("SMESH_Hexa_3D_i::SetImpl");
- SMESH_3D_Algo_i::SetImpl(impl);
- _impl = impl;
-}
+++ /dev/null
-// SMESH SMESH_I : idl implementation based on 'SMESH' unit's calsses
-//
-// Copyright (C) 2003 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
-// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
-//
-// This library 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.
-//
-// This library 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 this library; if not, write to the Free Software
-// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
-//
-// See http://www.opencascade.org/SALOME/ or email : webmaster.salome@opencascade.org
-//
-//
-//
-// File : SMESH_Hexa_3D_i.hxx
-// Author : Paul RASCLE, EDF
-// Module : SMESH
-// $Header$
-
-#ifndef _SMESH_HEXA_3D_I_HXX_
-#define _SMESH_HEXA_3D_I_HXX_
-
-#include <SALOMEconfig.h>
-#include CORBA_SERVER_HEADER(SMESH_BasicHypothesis)
-
-#include "SMESH_3D_Algo_i.hxx"
-
-#include "SMESH_Hexa_3D.hxx"
-
-class SMESH_Hexa_3D_i:
- public POA_SMESH::SMESH_Hexa_3D,
- public SMESH_3D_Algo_i
-{
-public:
- SMESH_Hexa_3D_i(const char* anHyp,
- int studyId,
- ::SMESH_Gen* genImpl);
-
- virtual ~SMESH_Hexa_3D_i();
-
-protected:
- virtual void SetImpl(::SMESH_Hexa_3D* impl);
-
- ::SMESH_Hexa_3D* _impl;
-};
-
-#endif
+++ /dev/null
-// SMESH SMESH_I : idl implementation based on 'SMESH' unit's calsses
-//
-// Copyright (C) 2003 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
-// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
-//
-// This library 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.
-//
-// This library 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 this library; if not, write to the Free Software
-// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
-//
-// See http://www.opencascade.org/SALOME/ or email : webmaster.salome@opencascade.org
-//
-//
-//
-// File : SMESH_HypothesisFactory_i.cxx
-// Author : Paul RASCLE, EDF
-// Module : SMESH
-// $Header$
-
-using namespace std;
-#include "SMESH_HypothesisFactory_i.hxx"
-#include "SMESH_Hypothesis_i.hxx"
-
-#include "Utils_CorbaException.hxx"
-#include "utilities.h"
-
-// Add new hypothesis here (include file)
-//---------------------------------------
-#include "SMESH_LocalLength_i.hxx"
-#include "SMESH_NumberOfSegments_i.hxx"
-#include "SMESH_LengthFromEdges_i.hxx"
-#include "SMESH_MaxElementArea_i.hxx"
-#include "SMESH_MaxElementVolume_i.hxx"
-#include "SMESH_Regular_1D_i.hxx"
-#include "SMESH_MEFISTO_2D_i.hxx"
-#include "SMESH_Quadrangle_2D_i.hxx"
-#include "SMESH_Hexa_3D_i.hxx"
-#ifdef HAVE_NETGEN
-#include "SMESH_NETGEN_3D_i.hxx"
-#endif
-//---------------------------------------
-
-//=============================================================================
-/*!
- * Specific Hypothesis Creators are generated with a template which inherits a
- * generic hypothesis creator. Each creator returns an hypothesis of the type
- * given in the template.
- */
-//=============================================================================
-
-template <class T> class HypothesisCreator_i: public GenericHypothesisCreator_i
-{
-public:
- virtual SMESH_Hypothesis_i* Create (const char* anHyp,
- int studyId,
- ::SMESH_Gen* genImpl)
- {
- return new T(anHyp, studyId, genImpl);
- };
-};
-
-//=============================================================================
-/*!
- * Constructor: instanciate specific hypothesis creators, fill a private map
- * indexed by hypothesis names. THIS METHOD MUST BE COMPLETED WHEN A NEW
- * HYPOTHESIS IS ADDED.
- * Specific hypothesis creator are defined with the above template.
- * Hypothesis names are related to the corresponding class names:
- * prefix = SMESH_ ; suffix = _i .
- */
-//=============================================================================
-
-SMESH_HypothesisFactory_i::SMESH_HypothesisFactory_i()
-{
-// Add new hypothesis here (creators)
-//---------------------------------------
-_creatorMap["LocalLength"] = new HypothesisCreator_i<SMESH_LocalLength_i>;
-_creatorMap["NumberOfSegments"] = new HypothesisCreator_i<SMESH_NumberOfSegments_i>;
-_creatorMap["LengthFromEdges"] = new HypothesisCreator_i<SMESH_LengthFromEdges_i>;
-_creatorMap["MaxElementArea"] = new HypothesisCreator_i<SMESH_MaxElementArea_i>;
-_creatorMap["MaxElementVolume"] = new HypothesisCreator_i<SMESH_MaxElementVolume_i>;
-_creatorMap["Regular_1D"] = new HypothesisCreator_i<SMESH_Regular_1D_i>;
-_creatorMap["MEFISTO_2D"] = new HypothesisCreator_i<SMESH_MEFISTO_2D_i>;
-_creatorMap["Quadrangle_2D"] = new HypothesisCreator_i<SMESH_Quadrangle_2D_i>;
-_creatorMap["Hexa_3D"] = new HypothesisCreator_i<SMESH_Hexa_3D_i>;
-#ifdef HAVE_NETGEN
-_creatorMap["NETGEN_3D"] = new HypothesisCreator_i<SMESH_NETGEN_3D_i>;
-#endif
-//---------------------------------------
-}
-
-//=============================================================================
-/*!
- * Destructor: deletes specific hypothesis creators instanciated in the
- * constructor.
- */
-//=============================================================================
-
-SMESH_HypothesisFactory_i::~SMESH_HypothesisFactory_i()
-{
- map<string, GenericHypothesisCreator_i*>::iterator it;
- for (it = _creatorMap.begin(); it != _creatorMap.end(); it++)
- {
- delete (*it).second;
- }
- _creatorMap.clear();
-}
-
-//=============================================================================
-/*!
- *
- */
-//=============================================================================
-
-SMESH_Hypothesis_i* SMESH_HypothesisFactory_i::Create(const char* anHyp,
- CORBA::Long studyId,
- ::SMESH_Gen* genImpl)
- throw (SALOME::SALOME_Exception)
-{
- MESSAGE("SMESH_HypothesisFactory::Create " << anHyp);
- if (_creatorMap.find(anHyp) == _creatorMap.end())
- {
- MESSAGE("levee exception CORBA");
- THROW_SALOME_CORBA_EXCEPTION("bad hypothesis type name", \
- SALOME::BAD_PARAM);
- }
- SMESH_Hypothesis_i* myHyp = _creatorMap[anHyp]->Create(anHyp,
- studyId,
- genImpl);
- return myHyp;
-}
-
-
+++ /dev/null
-// SMESH SMESH_I : idl implementation based on 'SMESH' unit's calsses
-//
-// Copyright (C) 2003 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
-// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
-//
-// This library 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.
-//
-// This library 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 this library; if not, write to the Free Software
-// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
-//
-// See http://www.opencascade.org/SALOME/ or email : webmaster.salome@opencascade.org
-//
-//
-//
-// File : SMESH_HypothesisFactory_i.hxx
-// Author : Paul RASCLE, EDF
-// Module : SMESH
-// $Header$
-
-#ifndef _SMESH_HYPOTHESISFACTORY_I_HXX_
-#define _SMESH_HYPOTHESISFACTORY_I_HXX_
-
-#include "SMESH_Hypothesis_i.hxx"
-#include <map>
-#include <string>
-using namespace std;
-
-class GenericHypothesisCreator_i
-{
-public:
- virtual SMESH_Hypothesis_i* Create(const char* anHyp,
- int studyId,
- ::SMESH_Gen* genImpl) = 0;
-};
-
-class SMESH_HypothesisFactory_i
-{
-public:
- SMESH_HypothesisFactory_i();
- virtual ~SMESH_HypothesisFactory_i();
-
- SMESH_Hypothesis_i* Create(const char* anHyp,
- CORBA::Long studyId,
- ::SMESH_Gen* genImpl)
- throw (SALOME::SALOME_Exception);
-
-private:
- map<string, GenericHypothesisCreator_i*> _creatorMap;
-};
-
-#endif
// $Header$
using namespace std;
-using namespace std;
+#include <iostream>
+#include <sstream>
#include "SMESH_Hypothesis_i.hxx"
-#include "SMESH_Hypothesis.hxx"
-#include "SMESH_Gen.hxx"
#include "utilities.h"
//=============================================================================
/*!
- *
+ * SMESH_Hypothesis_i::SMESH_Hypothesis_i
+ *
+ * Constructor
*/
//=============================================================================
-SMESH_Hypothesis_i::SMESH_Hypothesis_i()
+SMESH_Hypothesis_i::SMESH_Hypothesis_i( PortableServer::POA_ptr thePOA )
+ : SALOME::GenericObj_i( thePOA )
{
- MESSAGE("SMESH_Hypothesis_i");
+ MESSAGE( "SMESH_Hypothesis_i::SMESH_Hypothesis_i" );
+ myBaseImpl = 0;
+ thePOA->activate_object( this );
};
//=============================================================================
/*!
- *
+ * SMESH_Hypothesis_i::~SMESH_Hypothesis_i
+ *
+ * Destructor
*/
//=============================================================================
SMESH_Hypothesis_i::~SMESH_Hypothesis_i()
{
- MESSAGE("~SMESH_Hypothesis_i");
+ MESSAGE( "SMESH_Hypothesis_i::~SMESH_Hypothesis_i" );
+ if ( myBaseImpl )
+ delete myBaseImpl;
};
//=============================================================================
/*!
- *
+ * SMESH_Hypothesis_i::GetName
+ *
+ * Get type name of hypothesis
*/
//=============================================================================
char* SMESH_Hypothesis_i::GetName()
{
- MESSAGE("GetName");
- return CORBA::string_dup(_baseImpl->GetName());
-// const char* name = _baseImpl->GetName();
-// SCRUTE(name);
-// return CORBA::string_dup(name);
+ MESSAGE( "SMESH_Hypothesis_i::GetName" );
+ return CORBA::string_dup( myBaseImpl->GetName() );
+};
+
+//=============================================================================
+/*!
+ * SMESH_Hypothesis_i::GetLibName
+ *
+ * Get plugin library name of hypothesis (required by persistency mechanism)
+ */
+//=============================================================================
+
+char* SMESH_Hypothesis_i::GetLibName()
+{
+ MESSAGE( "SMESH_Hypothesis_i::GetLibName" );
+ return CORBA::string_dup( myBaseImpl->GetLibName() );
};
//=============================================================================
/*!
- *
+ * SMESH_Hypothesis_i::SetLibName
+ *
+ * Set plugin library name of hypothesis (required by persistency mechanism)
+ */
+//=============================================================================
+
+void SMESH_Hypothesis_i::SetLibName(const char* theLibName)
+{
+ MESSAGE( "SMESH_Hypothesis_i::SetLibName" );
+ myBaseImpl->SetLibName( theLibName );
+};
+
+//=============================================================================
+/*!
+ * SMESH_Hypothesis_i::GetId
+ *
+ * Get unique id of hypothesis
*/
//=============================================================================
CORBA::Long SMESH_Hypothesis_i::GetId()
{
- MESSAGE("GetId");
- return _baseImpl->GetID();
+ MESSAGE( "SMESH_Hypothesis_i::GetId" );
+ return myBaseImpl->GetID();
+}
+
+//=============================================================================
+/*!
+ * SMESH_Hypothesis_i::GetImpl
+ *
+ * Get implementation
+ */
+//=============================================================================
+
+::SMESH_Hypothesis* SMESH_Hypothesis_i::GetImpl()
+{
+ MESSAGE( "SMESH_Hypothesis_i::GetImpl" );
+ return myBaseImpl;
}
-::SMESH_Hypothesis* SMESH_Hypothesis_i::getImpl()
+//=============================================================================
+/*!
+ * SMESH_Hypothesis_i::SaveTo
+ *
+ * Persistence: Dumps parameters to the string stream
+ */
+//=============================================================================
+
+char* SMESH_Hypothesis_i::SaveTo()
{
- return _baseImpl;
-}
\ No newline at end of file
+ MESSAGE( "SMESH_Hypothesis_i::SaveTo" );
+ std::ostringstream os;
+ myBaseImpl->SaveTo( os );
+ return CORBA::string_dup( os.str().c_str() );
+}
+
+//=============================================================================
+/*!
+* SMESH_Hypothesis_i::LoadFrom
+*
+* Persistence: Restores parameters from string
+*/
+//=============================================================================
+
+void SMESH_Hypothesis_i::LoadFrom( const char* theStream )
+{
+ MESSAGE( "SMESH_Hypothesis_i::LoadFrom" );
+ std::istringstream is( theStream );
+ myBaseImpl->LoadFrom( is );
+}
#include <SALOMEconfig.h>
#include CORBA_SERVER_HEADER(SMESH_Hypothesis)
-class SMESH_Gen;
-class SMESH_Hypothesis;
+#include "SMESH_Hypothesis.hxx"
+#include "SALOME_GenericObj_i.hh"
+#include "SMESH_Gen.hxx"
+
+// ======================================================
+// Generic hypothesis
+// ======================================================
class SMESH_Hypothesis_i:
- public POA_SMESH::SMESH_Hypothesis
+ public virtual POA_SMESH::SMESH_Hypothesis,
+ public virtual SALOME::GenericObj_i
{
public:
- SMESH_Hypothesis_i();
+ // Constructor : placed in protected section to prohibit creation of generic class instance
+ SMESH_Hypothesis_i( PortableServer::POA_ptr thePOA );
+
+public:
+ // Destructor
virtual ~SMESH_Hypothesis_i();
+ // Get type name of hypothesis
char* GetName();
+
+ // Get plugin library name of hypothesis
+ char* GetLibName();
+
+ // Set plugin library name of hypothesis
+ void SetLibName( const char* theLibName );
+
+ // Get unique id of hypothesis
CORBA::Long GetId();
- ::SMESH_Hypothesis* getImpl();
+
+ // Get implementation
+ ::SMESH_Hypothesis* GetImpl();
+
+ // Persistence
+ virtual char* SaveTo();
+ virtual void LoadFrom( const char* theStream );
protected:
- ::SMESH_Hypothesis* _baseImpl;
- ::SMESH_Gen* _genImpl;
- int _id;
+ ::SMESH_Hypothesis* myBaseImpl; // base hypothesis implementation
+};
+
+// ======================================================
+// Generic hypothesis creator
+// ======================================================
+class GenericHypothesisCreator_i
+{
+public:
+ // Create a hypothesis
+ virtual SMESH_Hypothesis_i* Create(PortableServer::POA_ptr thePOA,
+ int theStudyId,
+ ::SMESH_Gen* theGenImpl) = 0;
+};
+
+//=============================================================================
+//
+// Specific Hypothesis Creators are generated with a template which inherits a
+// generic hypothesis creator. Each creator returns an hypothesis of the type
+// given in the template.
+//
+//=============================================================================
+template <class T> class HypothesisCreator_i: public GenericHypothesisCreator_i
+{
+public:
+ virtual SMESH_Hypothesis_i* Create (PortableServer::POA_ptr thePOA,
+ int theStudyId,
+ ::SMESH_Gen* theGenImpl)
+ {
+ return new T (thePOA, theStudyId, theGenImpl);
+ };
};
#endif
+++ /dev/null
-// SMESH SMESH_I : idl implementation based on 'SMESH' unit's calsses
-//
-// Copyright (C) 2003 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
-// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
-//
-// This library 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.
-//
-// This library 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 this library; if not, write to the Free Software
-// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
-//
-// See http://www.opencascade.org/SALOME/ or email : webmaster.salome@opencascade.org
-//
-//
-//
-// File : SMESH_LengthFromEdges_i.cxx
-// Author : Nadir BOUHAMOU CEA/DEN, Paul RASCLE, EDF
-// Module : SMESH
-// $Header$
-
-using namespace std;
-using namespace std;
-#include "SMESH_LengthFromEdges_i.hxx"
-#include "SMESH_Gen.hxx"
-#include "SMESH_HypothesisFactory.hxx"
-
-#include "Utils_CorbaException.hxx"
-#include "utilities.h"
-
-//=============================================================================
-/*!
- * Constructor:
- * _name is related to the class name: prefix = SMESH_ ; suffix = _i .
- */
-//=============================================================================
-
-SMESH_LengthFromEdges_i::SMESH_LengthFromEdges_i(const char* anHyp,
- int studyId,
- ::SMESH_Gen* genImpl)
-{
- MESSAGE("SMESH_LengthFromEdges_i::SMESH_LengthFromEdges_i");
- _impl = new ::SMESH_LengthFromEdges(genImpl->_hypothesisFactory.GetANewId(),
- studyId,
- genImpl);
- _baseImpl = _impl;
-}
-
-//=============================================================================
-/*!
- *
- */
-//=============================================================================
-
-SMESH_LengthFromEdges_i::~SMESH_LengthFromEdges_i()
-{
-}
-
-//=============================================================================
-/*!
- *
- */
-//=============================================================================
-
-void SMESH_LengthFromEdges_i::SetMode(CORBA::Long mode)
- throw (SALOME::SALOME_Exception)
-{
- ASSERT(_impl);
- try
- {
- _impl->SetMode(mode);
- }
- catch (SALOME_Exception& S_ex)
- {
- THROW_SALOME_CORBA_EXCEPTION(S_ex.what(), \
- SALOME::BAD_PARAM);
- }
-}
-
-//=============================================================================
-/*!
- *
- */
-//=============================================================================
-
-CORBA::Long SMESH_LengthFromEdges_i::GetMode()
-{
- ASSERT(_impl);
- return _impl->GetMode();
-}
-
+++ /dev/null
-// SMESH SMESH_I : idl implementation based on 'SMESH' unit's calsses
-//
-// Copyright (C) 2003 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
-// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
-//
-// This library 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.
-//
-// This library 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 this library; if not, write to the Free Software
-// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
-//
-// See http://www.opencascade.org/SALOME/ or email : webmaster.salome@opencascade.org
-//
-//
-//
-// File : SMESH_LengthFromEdges_i.hxx
-// Author : Nadir BOUHAMOU CEA/DEN, Paul RASCLE, EDF
-// Module : SMESH
-// $Header$
-
-#ifndef _SMESH_LENGTHFROMEDGES_I_HXX_
-#define _SMESH_LENGTHFROMEDGES_I_HXX_
-
-#include <SALOMEconfig.h>
-#include CORBA_SERVER_HEADER(SMESH_BasicHypothesis)
-
-#include "SMESH_Hypothesis_i.hxx"
-
-#include "SMESH_LengthFromEdges.hxx"
-
-class SMESH_LengthFromEdges_i:
- public POA_SMESH::SMESH_LengthFromEdges,
- public SMESH_Hypothesis_i
-{
-public:
- SMESH_LengthFromEdges_i(const char* anHyp,
- int studyId,
- ::SMESH_Gen* genImpl);
- virtual ~SMESH_LengthFromEdges_i();
-
- void SetMode(CORBA::Long mode)
- throw (SALOME::SALOME_Exception);
-
- CORBA::Long GetMode();
-
-protected:
- ::SMESH_LengthFromEdges* _impl;
-};
-
-#endif
-
+++ /dev/null
-// SMESH SMESH_I : idl implementation based on 'SMESH' unit's calsses
-//
-// Copyright (C) 2003 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
-// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
-//
-// This library 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.
-//
-// This library 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 this library; if not, write to the Free Software
-// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
-//
-// See http://www.opencascade.org/SALOME/ or email : webmaster.salome@opencascade.org
-//
-//
-//
-// File : SMESH_LocalLength_i.cxx
-// Author : Paul RASCLE, EDF
-// Module : SMESH
-// $Header$
-
-using namespace std;
-using namespace std;
-#include "SMESH_LocalLength_i.hxx"
-#include "SMESH_Gen.hxx"
-#include "SMESH_HypothesisFactory.hxx"
-
-#include "Utils_CorbaException.hxx"
-#include "utilities.h"
-
-//=============================================================================
-/*!
- * Constructor:
- * _name is related to the class name: prefix = SMESH_ ; suffix = _i .
- */
-//=============================================================================
-
-SMESH_LocalLength_i::SMESH_LocalLength_i(const char* anHyp,
- int studyId,
- ::SMESH_Gen* genImpl)
-{
- MESSAGE("SMESH_LocalLength_i::SMESH_LocalLength_i");
- _impl = new ::SMESH_LocalLength(genImpl->_hypothesisFactory.GetANewId(),
- studyId,
- genImpl);
- _baseImpl = _impl;
-}
-
-//=============================================================================
-/*!
- *
- */
-//=============================================================================
-
-SMESH_LocalLength_i::~SMESH_LocalLength_i()
-{
-}
-
-//=============================================================================
-/*!
- *
- */
-//=============================================================================
-
-void SMESH_LocalLength_i::SetLength(CORBA::Double length)
- throw (SALOME::SALOME_Exception)
-{
- ASSERT(_impl);
- try
- {
- _impl->SetLength(length);
- }
- catch (SALOME_Exception& S_ex)
- {
- THROW_SALOME_CORBA_EXCEPTION(S_ex.what(), \
- SALOME::BAD_PARAM);
- }
-}
-
-//=============================================================================
-/*!
- *
- */
-//=============================================================================
-
-CORBA::Double SMESH_LocalLength_i::GetLength()
-{
- ASSERT(_impl);
- return _impl->GetLength();
-}
-
+++ /dev/null
-// SMESH SMESH_I : idl implementation based on 'SMESH' unit's calsses
-//
-// Copyright (C) 2003 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
-// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
-//
-// This library 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.
-//
-// This library 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 this library; if not, write to the Free Software
-// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
-//
-// See http://www.opencascade.org/SALOME/ or email : webmaster.salome@opencascade.org
-//
-//
-//
-// File : SMESH_LocalLength_i.hxx
-// Author : Paul RASCLE, EDF
-// Module : SMESH
-// $Header$
-
-#ifndef _SMESH_LOCALLENGTH_I_HXX_
-#define _SMESH_LOCALLENGTH_I_HXX_
-
-#include <SALOMEconfig.h>
-#include CORBA_SERVER_HEADER(SMESH_BasicHypothesis)
-
-#include "SMESH_Hypothesis_i.hxx"
-
-#include "SMESH_LocalLength.hxx"
-
-class SMESH_LocalLength_i:
- public POA_SMESH::SMESH_LocalLength,
- public SMESH_Hypothesis_i
-{
-public:
- SMESH_LocalLength_i(const char* anHyp,
- int studyId,
- ::SMESH_Gen* genImpl);
- virtual ~SMESH_LocalLength_i();
-
- void SetLength(CORBA::Double length)
- throw (SALOME::SALOME_Exception);
-
- CORBA::Double GetLength();
-
-protected:
- ::SMESH_LocalLength* _impl;
-};
-
-#endif
-
# include "Utils_ORB_INIT.hxx"
# include "Utils_SINGLETON.hxx"
+# include "Utils_ExceptHandlers.hxx"
+
extern "C"
{
#include <stdio.h>
myseq->length(nbNodes * spaceDimension);
int i = 0;
- SMDS_Iterator<const SMDS_MeshNode *> * itNodes=_meshDS->nodesIterator();
+ SMDS_NodeIteratorPtr itNodes=_meshDS->nodesIterator();
while(itNodes->more())
{
const SMDS_MeshNode* node = itNodes->next();
}
i++;
}
- delete itNodes;
}
catch(...)
{
int trouveSeg3 = 0;
SALOME_MED::medGeometryElement medElement;
- SMDS_Iterator<const SMDS_MeshEdge*> * itEdges=_meshDS->edgesIterator();
+ SMDS_EdgeIteratorPtr itEdges=_meshDS->edgesIterator();
while(itEdges->more())
{
const SMDS_MeshEdge* elem = itEdges->next();
int longueur = _seq_elemId[index]->length();
_seq_elemId[index]->length(longueur + nb_of_nodes);
- SMDS_Iterator<const SMDS_MeshNode*> * itn=_meshDS->nodesIterator();
+ SMDS_NodeIteratorPtr itn=_meshDS->nodesIterator();
for(int k=0; itn->more(); k++)
_seq_elemId[index][longueur + k] = itn->next()->GetID()+1;
- delete itn;
}
- delete itEdges;
_mapNbTypes[SALOME_MED::MED_EDGE] = trouveSeg2 + trouveSeg3;
_mapIndToSeqElts[SALOME_MED::MED_QUAD4] = _indexElts++;
_mapIndToVectTypes[SALOME_MED::MED_FACE] = _indexEnts++;
- SMDS_Iterator<const SMDS_MeshFace*> * itFaces=_meshDS->facesIterator();
+ SMDS_FaceIteratorPtr itFaces=_meshDS->facesIterator();
while(itFaces->more())
{
const SMDS_MeshFace * elem = itFaces->next();
int longueur = _seq_elemId[index]->length();
_seq_elemId[index]->length(longueur + nb_of_nodes);
- SMDS_Iterator<const SMDS_MeshNode*> * itn=_meshDS->nodesIterator();
+ SMDS_NodeIteratorPtr itn=_meshDS->nodesIterator();
for(int k=0; itn->more(); k++)
_seq_elemId[index][longueur + k] = itn->next()->GetID()+1;
- delete itn;
} //itFaces
- delete itFaces;
_mapNbTypes[SALOME_MED::MED_FACE] =
trouveTria3 + trouveTria6 + trouveQuad4;
int trouveHexa8 = 0;
- SMDS_Iterator<const SMDS_MeshVolume*> * itVolumes=_meshDS->volumesIterator();
+ SMDS_VolumeIteratorPtr itVolumes=_meshDS->volumesIterator();
while(itVolumes->more())
{
const SMDS_MeshVolume * elem = itVolumes->next();
int longueur = _seq_elemId[index]->length();
_seq_elemId[index]->length(longueur + nb_of_nodes);
- SMDS_Iterator<const SMDS_MeshNode*> * itn=_meshDS->nodesIterator();
+ SMDS_NodeIteratorPtr itn=_meshDS->nodesIterator();
for(int k=0; itn->more(); k++)
_seq_elemId[index][longueur + k] = itn->next()->GetID()+1;
- delete itn;
}
- delete itVolumes;
_mapNbTypes[SALOME_MED::MED_CELL] = trouveHexa8;
_mapNbTypes[SALOME_MED::MED_ALL_ENTITIES]
//=============================================================================
void SMESH_MEDMesh_i::createFamilies() throw(SALOME::SALOME_Exception)
{
+ Unexpect aCatch(SALOME_SalomeException);
string famDes = ("Je ne sais pas");
string famName0 = "Famille_";
string famName;
#include "SMESH_MEDSupport_i.hxx"
#include "utilities.h"
#include "Utils_CorbaException.hxx"
+#include "Utils_ExceptHandlers.hxx"
#include <TopoDS_Iterator.hxx>
#include "SMESHDS_Mesh.hxx"
#include "SMESH_Mesh_i.hxx"
#include "SMESH_subMesh_i.hxx"
+
//=============================================================================
/*!
* Default constructor
SALOME_MED::long_array * SMESH_MEDSupport_i::getNumber(
SALOME_MED::medGeometryElement geomElement) throw(SALOME::SALOME_Exception)
{
+ Unexpect aCatch(SALOME_SalomeException);
if (_subMeshDS==NULL)
THROW_SALOME_CORBA_EXCEPTION("No associated Support",
SALOME::INTERNAL_ERROR);
int i = 0;
myseq->length(_subMeshDS->NbNodes());
- SMDS_Iterator<const SMDS_MeshNode*> * it = _subMeshDS->GetNodes();
+ SMDS_NodeIteratorPtr it = _subMeshDS->GetNodes();
while(it->more())
{
myseq[i] = it->next()->GetID();
i++;
};
- delete it;
SCRUTE(myseq->length());
MESSAGE("End of SMESH_MEDSupport_i::getNumber");
+++ /dev/null
-// SMESH SMESH_I : idl implementation based on 'SMESH' unit's calsses
-//
-// Copyright (C) 2003 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
-// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
-//
-// This library 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.
-//
-// This library 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 this library; if not, write to the Free Software
-// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
-//
-// See http://www.opencascade.org/SALOME/ or email : webmaster.salome@opencascade.org
-//
-//
-//
-// File : SMESH_MEFISTO_2D_i.cxx
-// Author : Paul RASCLE, EDF
-// Module : SMESH
-// $Header$
-
-using namespace std;
-using namespace std;
-#include "SMESH_MEFISTO_2D_i.hxx"
-#include "SMESH_Gen.hxx"
-#include "SMESH_HypothesisFactory.hxx"
-
-#include "Utils_CorbaException.hxx"
-#include "utilities.h"
-
-//=============================================================================
-/*!
- *
- */
-//=============================================================================
-
-SMESH_MEFISTO_2D_i::SMESH_MEFISTO_2D_i(const char* anHyp,
- int studyId,
- ::SMESH_Gen* genImpl)
-{
- MESSAGE("SMESH_MEFISTO_2D_i::SMESH_MEFISTO_2D_i");
- _genImpl = genImpl;
- ::SMESH_MEFISTO_2D* impl
- = new ::SMESH_MEFISTO_2D(_genImpl->_hypothesisFactory.GetANewId(),
- studyId,
- genImpl);
- SetImpl(impl);
- _baseImpl = _impl;
-}
-
-//=============================================================================
-/*!
- *
- */
-//=============================================================================
-
-SMESH_MEFISTO_2D_i::~SMESH_MEFISTO_2D_i()
-{
- MESSAGE("SMESH_MEFISTO_2D_i::~SMESH_MEFISTO_2D_i");
-}
-
-//=============================================================================
-/*!
- *
- */
-//=============================================================================
-
-void SMESH_MEFISTO_2D_i::SetImpl(::SMESH_MEFISTO_2D* impl)
-{
- MESSAGE("SMESH_MEFISTO_2D_i::SetImpl");
- SMESH_2D_Algo_i::SetImpl(impl);
- _impl = impl;
-}
+++ /dev/null
-// SMESH SMESH_I : idl implementation based on 'SMESH' unit's calsses
-//
-// Copyright (C) 2003 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
-// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
-//
-// This library 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.
-//
-// This library 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 this library; if not, write to the Free Software
-// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
-//
-// See http://www.opencascade.org/SALOME/ or email : webmaster.salome@opencascade.org
-//
-//
-//
-// File : SMESH_MEFISTO_2D_i.hxx
-// Author : Paul RASCLE, EDF
-// Module : SMESH
-// $Header$
-
-#ifndef _SMESH_MEFISTO_2D_I_HXX_
-#define _SMESH_MEFISTO_2D_I_HXX_
-
-#include <SALOMEconfig.h>
-#include CORBA_SERVER_HEADER(SMESH_BasicHypothesis)
-
-#include "SMESH_2D_Algo_i.hxx"
-
-#include "SMESH_MEFISTO_2D.hxx"
-
-class SMESH_MEFISTO_2D_i:
- public POA_SMESH::SMESH_MEFISTO_2D,
- public SMESH_2D_Algo_i
-{
-public:
- SMESH_MEFISTO_2D_i(const char* anHyp,
- int studyId,
- ::SMESH_Gen* genImpl);
-
- virtual ~SMESH_MEFISTO_2D_i();
-
-protected:
- virtual void SetImpl(::SMESH_MEFISTO_2D* impl);
-
- ::SMESH_MEFISTO_2D* _impl;
-};
-
-#endif
+++ /dev/null
-// SMESH SMESH_I : idl implementation based on 'SMESH' unit's calsses
-//
-// Copyright (C) 2003 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
-// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
-//
-// This library 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.
-//
-// This library 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 this library; if not, write to the Free Software
-// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
-//
-// See http://www.opencascade.org/SALOME/ or email : webmaster.salome@opencascade.org
-//
-//
-//
-// File : SMESH_MaxElementArea_i.cxx
-// Author : Paul RASCLE, EDF
-// Module : SMESH
-// $Header$
-
-using namespace std;
-using namespace std;
-#include "SMESH_MaxElementArea_i.hxx"
-#include "SMESH_Gen.hxx"
-#include "SMESH_HypothesisFactory.hxx"
-
-#include "Utils_CorbaException.hxx"
-#include "utilities.h"
-
-//=============================================================================
-/*!
- * Constructor:
- * _name is related to the class name: prefix = SMESH_ ; suffix = _i .
- */
-//=============================================================================
-
-SMESH_MaxElementArea_i::SMESH_MaxElementArea_i(const char* anHyp,
- int studyId,
- ::SMESH_Gen* genImpl)
-{
- MESSAGE("SMESH_MaxElementArea_i::SMESH_MaxElementArea_i");
- _impl = new ::SMESH_MaxElementArea(genImpl->_hypothesisFactory.GetANewId(),
- studyId,
- genImpl);
- _baseImpl = _impl;
-}
-
-//=============================================================================
-/*!
- *
- */
-//=============================================================================
-
-SMESH_MaxElementArea_i::~SMESH_MaxElementArea_i()
-{
-}
-
-//=============================================================================
-/*!
- *
- */
-//=============================================================================
-
-void SMESH_MaxElementArea_i::SetMaxElementArea(CORBA::Double area)
- throw (SALOME::SALOME_Exception)
-{
- ASSERT(_impl);
- try
- {
- _impl->SetMaxArea(area);
- }
- catch (SALOME_Exception& S_ex)
- {
- THROW_SALOME_CORBA_EXCEPTION(S_ex.what(), \
- SALOME::BAD_PARAM);
- }
-}
-
-//=============================================================================
-/*!
- *
- */
-//=============================================================================
-
-CORBA::Double SMESH_MaxElementArea_i::GetMaxElementArea()
-{
- ASSERT(_impl);
- return _impl->GetMaxArea();
-}
-
+++ /dev/null
-// SMESH SMESH_I : idl implementation based on 'SMESH' unit's calsses
-//
-// Copyright (C) 2003 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
-// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
-//
-// This library 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.
-//
-// This library 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 this library; if not, write to the Free Software
-// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
-//
-// See http://www.opencascade.org/SALOME/ or email : webmaster.salome@opencascade.org
-//
-//
-//
-// File : SMESH_MaxElementArea_i.hxx
-// Author : Paul RASCLE, EDF
-// Module : SMESH
-// $Header$
-
-#ifndef _SMESH_MAXELEMENTAREA_I_HXX_
-#define _SMESH_MAXELEMENTAREA_I_HXX_
-
-#include <SALOMEconfig.h>
-#include CORBA_SERVER_HEADER(SMESH_BasicHypothesis)
-
-#include "SMESH_Hypothesis_i.hxx"
-
-#include "SMESH_MaxElementArea.hxx"
-
-class SMESH_MaxElementArea_i:
- public POA_SMESH::SMESH_MaxElementArea,
- public SMESH_Hypothesis_i
-{
-public:
- SMESH_MaxElementArea_i(const char* anHyp,
- int studyId,
- ::SMESH_Gen* genImpl);
- virtual ~SMESH_MaxElementArea_i();
-
- void SetMaxElementArea(CORBA::Double area)
- throw (SALOME::SALOME_Exception);
-
- CORBA::Double GetMaxElementArea();
-
-protected:
- ::SMESH_MaxElementArea* _impl;
-};
-
-#endif
+++ /dev/null
-// SMESH SMESH_I : idl implementation based on 'SMESH' unit's calsses
-//
-// Copyright (C) 2003 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
-// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
-//
-// This library 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.
-//
-// This library 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 this library; if not, write to the Free Software
-// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
-//
-// See http://www.opencascade.org/SALOME/ or email : webmaster.salome@opencascade.org
-//
-//
-//
-// File : SMESH_MaxElementVolume_i.cxx
-// Author : Paul RASCLE, EDF
-// Module : SMESH
-// $Header$
-
-using namespace std;
-
-#include "SMESH_MaxElementVolume_i.hxx"
-#include "SMESH_Gen.hxx"
-#include "SMESH_HypothesisFactory.hxx"
-
-#include "Utils_CorbaException.hxx"
-#include "utilities.h"
-
-//=============================================================================
-/*!
- * Constructor:
- * _name is related to the class name: prefix = SMESH_ ; suffix = _i .
- */
-//=============================================================================
-
-SMESH_MaxElementVolume_i::SMESH_MaxElementVolume_i(const char* anHyp,
- int studyId,
- ::SMESH_Gen* genImpl)
-{
- MESSAGE("SMESH_MaxElementVolume_i::SMESH_MaxElementVolume_i");
- _impl = new ::SMESH_MaxElementVolume(genImpl->_hypothesisFactory.GetANewId(),
- studyId,
- genImpl);
- _baseImpl = _impl;
-}
-
-//=============================================================================
-/*!
- *
- */
-//=============================================================================
-
-SMESH_MaxElementVolume_i::~SMESH_MaxElementVolume_i()
-{
- MESSAGE("SMESH_MaxElementVolume_i::~SMESH_MaxElementVolume_i()");
-}
-
-//=============================================================================
-/*!
- *
- */
-//=============================================================================
-
-void SMESH_MaxElementVolume_i::SetMaxElementVolume(CORBA::Double volume)
- throw (SALOME::SALOME_Exception)
-{
- ASSERT(_impl);
- try
- {
- _impl->SetMaxVolume(volume);
- }
- catch (SALOME_Exception& S_ex)
- {
- THROW_SALOME_CORBA_EXCEPTION(S_ex.what(), \
- SALOME::BAD_PARAM);
- }
-}
-
-//=============================================================================
-/*!
- *
- */
-//=============================================================================
-
-CORBA::Double SMESH_MaxElementVolume_i::GetMaxElementVolume()
-{
- ASSERT(_impl);
- return _impl->GetMaxVolume();
-}
-
+++ /dev/null
-// SMESH SMESH_I : idl implementation based on 'SMESH' unit's calsses
-//
-// Copyright (C) 2003 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
-// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
-//
-// This library 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.
-//
-// This library 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 this library; if not, write to the Free Software
-// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
-//
-// See http://www.opencascade.org/SALOME/ or email : webmaster.salome@opencascade.org
-//
-//
-//
-// File : SMESH_MaxElementVolume_i.hxx
-// Author : Paul RASCLE, EDF
-// Module : SMESH
-// $Header$
-
-#ifndef _SMESH_MAXELEMENTVOLUME_I_HXX_
-#define _SMESH_MAXELEMENTVOLUME_I_HXX_
-
-#include <SALOMEconfig.h>
-#include CORBA_SERVER_HEADER(SMESH_BasicHypothesis)
-
-#include "SMESH_Hypothesis_i.hxx"
-
-#include "SMESH_MaxElementVolume.hxx"
-
-class SMESH_MaxElementVolume_i:
- public POA_SMESH::SMESH_MaxElementVolume,
- public SMESH_Hypothesis_i
-{
-public:
- SMESH_MaxElementVolume_i(const char* anHyp,
- int studyId,
- ::SMESH_Gen* genImpl);
- virtual ~SMESH_MaxElementVolume_i();
-
- void SetMaxElementVolume(CORBA::Double volume)
- throw (SALOME::SALOME_Exception);
-
- CORBA::Double GetMaxElementVolume();
-
-protected:
- ::SMESH_MaxElementVolume* _impl;
-};
-
-#endif
for (int i = 0; i < IDsOfElements.length(); i++)
{
CORBA::Long index = IDsOfElements[i];
- _myMeshDS->RemoveElement(_myMeshDS->FindElement(index));
- MESSAGE("Element " << index << " was removed")
+ const SMDS_MeshElement * elem = _myMeshDS->FindElement(index);
+ // an element may be removed as a result of preceding
+ // loop removal
+ if ( elem )
+ {
+ _myMeshDS->RemoveElement( elem );
+ MESSAGE("Element " << index << " was removed");
+ }
}
return true;
};
// Module : SMESH
// $Header$
+using namespace std;
#include "SMESH_Mesh_i.hxx"
#include "SMESH_subMesh_i.hxx"
#include "SMESH_MEDMesh_i.hxx"
+#include "SMESH_Group_i.hxx"
#include "Utils_CorbaException.hxx"
+#include "Utils_ExceptHandlers.hxx"
#include "utilities.h"
#include "SALOME_NamingService.hxx"
#include "SMESHDS_Command.hxx"
#include "SMESHDS_CommandType.hxx"
#include "SMESH_MeshEditor_i.hxx"
+#include "SMESH_Gen_i.hxx"
+#include "DriverMED_R_SMESHDS_Mesh.h"
#include <string>
#include <iostream>
-using namespace std;
+
+
+//**** SMESHDS en champ
+
+int SMESH_Mesh_i::myIdGenerator = 0;
//=============================================================================
/*!
- * Constructor
+ *
*/
//=============================================================================
-SMESH_Mesh_i::SMESH_Mesh_i(SMESH_Gen_i * gen_i,
- GEOM::GEOM_Gen_ptr geomEngine, CORBA::Long studyId, ::SMESH_Mesh * impl)
+SMESH_Mesh_i::SMESH_Mesh_i()
+ : SALOME::GenericObj_i( PortableServer::POA::_nil() )
{
- MESSAGE("SMESH_Mesh_i");
- _gen_i = gen_i;
- _geom = GEOM::GEOM_Gen::_narrow(geomEngine);
- _impl=impl;
- _studyId=studyId;
+ MESSAGE("SMESH_Mesh_i: default constructor, not for use");
+ ASSERT(0);
}
+//=============================================================================
+/*!
+ * Constructor
+ */
+//=============================================================================
+
+SMESH_Mesh_i::SMESH_Mesh_i( PortableServer::POA_ptr thePOA,
+ SMESH_Gen_i* gen_i,
+ CORBA::Long studyId )
+: SALOME::GenericObj_i( thePOA )
+{
+ MESSAGE("SMESH_Mesh_i");
+ _gen_i = gen_i;
+ _id = myIdGenerator++;
+ _studyId = studyId;
+ thePOA->activate_object( this );
+}
+/*
+SMESH_Mesh_i::SMESH_Mesh_i(SMESH_Gen_i* gen_i,
+ CORBA::Long studyId,
+ int localId)
+{
+ MESSAGE("SMESH_Mesh_i");
+ _gen_i = gen_i;
+ _id = localId;
+ _studyId = studyId;
+}
+*/
//=============================================================================
/*!
* Destructor
SMESH_Mesh_i::~SMESH_Mesh_i()
{
- MESSAGE("~SMESH_Mesh_i");
- // ****
-};
+ MESSAGE("~SMESH_Mesh_i");
+ map<int, SMESH::SMESH_Group_ptr>::iterator it;
+ for ( it = _mapGroups.begin(); it != _mapGroups.end(); it++ ) {
+ SMESH_Group_i* aGroup = dynamic_cast<SMESH_Group_i*>( SMESH_Gen_i::GetServant( it->second ).in() );
+ if ( aGroup ) {
+ _impl->RemoveGroup( aGroup->GetLocalID() );
+ aGroup->Destroy();
+ }
+ }
+ _mapGroups.clear();
+}
+
+//=============================================================================
+/*!
+ * SetShape
+ *
+ * Associates <this> mesh with <theShape> and puts a reference
+ * to <theShape> into the current study;
+ * the previous shape is substituted by the new one.
+ */
+//=============================================================================
+
+void SMESH_Mesh_i::SetShape( GEOM::GEOM_Shape_ptr theShape )
+ throw (SALOME::SALOME_Exception)
+{
+ Unexpect aCatch(SALOME_SalomeException);
+ try {
+ setShape( theShape );
+ }
+ catch(SALOME_Exception & S_ex) {
+ THROW_SALOME_CORBA_EXCEPTION(S_ex.what(), SALOME::BAD_PARAM);
+ }
+
+ SALOMEDS::Study_ptr aStudy = _gen_i->GetCurrentStudy();
+ if ( aStudy->_is_nil() )
+ return;
+
+ // Create a reference to <theShape>
+ SALOMEDS::SObject_var aMeshSO = SALOMEDS::SObject::_narrow( aStudy->FindObjectIOR( ( SMESH_Gen_i::GetORB()->object_to_string( _this() ) ) ) );
+ SALOMEDS::SObject_var aShapeSO = aStudy->FindObjectIOR( SMESH_Gen_i::GetORB()->object_to_string( theShape ) );
+
+ SALOMEDS::SObject_var anObj, aRef;
+ SALOMEDS::GenericAttribute_var anAttr;
+ SALOMEDS::AttributeIOR_var anIOR;
+ SALOMEDS::StudyBuilder_var aBuilder = aStudy->NewBuilder();
+ long aTag = SMESH_Gen_i::GetRefOnShapeTag();
+
+ if ( aMeshSO->FindSubObject( aTag, anObj ) ) {
+ if ( anObj->ReferencedObject( aRef ) ) {
+ if ( strcmp( aRef->GetID(), aShapeSO->GetID() ) == 0 ) {
+ // Setting the same shape twice forbidden
+ return;
+ }
+ }
+ }
+ else {
+ anObj = aBuilder->NewObjectToTag( aMeshSO, aTag );
+ }
+ aBuilder->Addreference( anObj, aShapeSO );
+}
+
+//=============================================================================
+/*!
+ * setShape
+ *
+ * Sets shape to the mesh implementation
+ */
+//=============================================================================
+
+bool SMESH_Mesh_i::setShape( GEOM::GEOM_Shape_ptr theShape )
+{
+ TopoDS_Shape aLocShape = _gen_i->GetShapeReader()->GetShape( SMESH_Gen_i::GetGeomEngine(), theShape );
+ _impl->ShapeToMesh( aLocShape );
+ return true;
+}
//=============================================================================
/*!
*/
//=============================================================================
-CORBA::Boolean SMESH_Mesh_i::AddHypothesis(GEOM::GEOM_Shape_ptr aSubShape,
- SMESH::SMESH_Hypothesis_ptr anHyp) throw(SALOME::SALOME_Exception)
+static SMESH::DriverMED_ReadStatus ConvertDriverMEDReadStatus (int theStatus)
{
- MESSAGE("AddHypothesis");
+ SMESH::DriverMED_ReadStatus res;
+ switch (theStatus)
+ {
+ case DriverMED_R_SMESHDS_Mesh::DRS_OK:
+ res = SMESH::DRS_OK; break;
+ case DriverMED_R_SMESHDS_Mesh::DRS_EMPTY:
+ res = SMESH::DRS_EMPTY; break;
+ case DriverMED_R_SMESHDS_Mesh::DRS_WARN_RENUMBER:
+ res = SMESH::DRS_WARN_RENUMBER; break;
+ case DriverMED_R_SMESHDS_Mesh::DRS_WARN_SKIP_ELEM:
+ res = SMESH::DRS_WARN_SKIP_ELEM; break;
+ case DriverMED_R_SMESHDS_Mesh::DRS_FAIL:
+ default:
+ res = SMESH::DRS_FAIL; break;
+ }
+ return res;
+}
+
+//=============================================================================
+/*!
+ * ImportMEDFile
+ *
+ * Imports mesh data from MED file
+ */
+//=============================================================================
+
+SMESH::DriverMED_ReadStatus
+ SMESH_Mesh_i::ImportMEDFile( const char* theFileName, const char* theMeshName )
+ throw ( SALOME::SALOME_Exception )
+{
+ Unexpect aCatch(SALOME_SalomeException);
+ int status;
+ try {
+ status = importMEDFile( theFileName, theMeshName );
+ }
+ catch( SALOME_Exception& S_ex ) {
+ THROW_SALOME_CORBA_EXCEPTION(S_ex.what(), SALOME::BAD_PARAM);
+ }
+ catch ( ... ) {
+ THROW_SALOME_CORBA_EXCEPTION("ImportMEDFile(): unknown exception", SALOME::BAD_PARAM);
+ }
+
+ SALOMEDS::Study_ptr aStudy = _gen_i->GetCurrentStudy();
+ if ( aStudy->_is_nil() )
+ return ConvertDriverMEDReadStatus(status);
+
+ // publishing of the groups in the study (sub-meshes are out of scope of MED import)
+ map<int, SMESH::SMESH_Group_ptr>::iterator it = _mapGroups.begin();
+ for (; it != _mapGroups.end(); it++ ) {
+ SMESH::SMESH_Group_var aGroup = SMESH::SMESH_Group::_duplicate( it->second );
+ if ( _gen_i->CanPublishInStudy( aGroup ) )
+ _gen_i->PublishInStudy( aStudy,
+ SALOMEDS::SObject::_nil(),
+ aGroup,
+ aGroup->GetName() );
+ }
+ return ConvertDriverMEDReadStatus(status);
+}
+
+//=============================================================================
+/*!
+ * importMEDFile
+ *
+ * Imports mesh data from MED file
+ */
+//=============================================================================
+
+int SMESH_Mesh_i::importMEDFile( const char* theFileName, const char* theMeshName )
+{
+ // Read mesh with name = <theMeshName> and all its groups into SMESH_Mesh
+ int status = _impl->MEDToMesh( theFileName, theMeshName );
+
+ // Create group servants, if any groups were imported
+ list<int> aGroupIds = _impl->GetGroupIds();
+ for ( list<int>::iterator it = aGroupIds.begin(); it != aGroupIds.end(); it++ ) {
+ SMESH_Group_i* aGroupImpl = new SMESH_Group_i( SMESH_Gen_i::GetPOA(), this, *it );
+ SMESH::SMESH_Group_var aGroup = SMESH::SMESH_Group::_narrow( aGroupImpl->_this() );
+ _mapGroups[*it] = SMESH::SMESH_Group::_duplicate( aGroup );
+
+ // register CORBA object for persistence
+ StudyContext* myStudyContext = _gen_i->GetCurrentStudyContext();
+ string iorString = SMESH_Gen_i::GetORB()->object_to_string( aGroup );
+ int nextId = myStudyContext->addObject( iorString );
+ MESSAGE( "Add group to map with id = "<< nextId << " and IOR = " << iorString.c_str() );
+ }
+
+ return status;
+}
+
+//=============================================================================
+/*!
+ *
+ */
+//=============================================================================
+
+static SMESH::Hypothesis_Status ConvertHypothesisStatus
+ (SMESH_Hypothesis::Hypothesis_Status theStatus)
+{
+ SMESH::Hypothesis_Status res;
+ switch (theStatus)
+ {
+ case SMESH_Hypothesis::HYP_OK:
+ res = SMESH::HYP_OK; break;
+ case SMESH_Hypothesis::HYP_MISSING:
+ res = SMESH::HYP_MISSING; break;
+ case SMESH_Hypothesis::HYP_CONCURENT:
+ res = SMESH::HYP_CONCURENT; break;
+ case SMESH_Hypothesis::HYP_BAD_PARAMETER:
+ res = SMESH::HYP_BAD_PARAMETER; break;
+ case SMESH_Hypothesis::HYP_INCOMPATIBLE:
+ res = SMESH::HYP_INCOMPATIBLE; break;
+ case SMESH_Hypothesis::HYP_NOTCONFORM:
+ res = SMESH::HYP_NOTCONFORM; break;
+ case SMESH_Hypothesis::HYP_ALREADY_EXIST:
+ res = SMESH::HYP_ALREADY_EXIST; break;
+ case SMESH_Hypothesis::HYP_BAD_DIM:
+ res = SMESH::HYP_BAD_DIM; break;
+ default:
+ res = SMESH::HYP_UNKNOWN_FATAL;
+ }
+ return res;
+}
+
+//=============================================================================
+/*!
+ * AddHypothesis
+ *
+ * calls internal addHypothesis() and then adds a reference to <anHyp> under
+ * the SObject actually having a reference to <aSubShape>.
+ * NB: For this method to work, it is necessary to add a reference to sub-shape first.
+ */
+//=============================================================================
+
+SMESH::Hypothesis_Status SMESH_Mesh_i::AddHypothesis(GEOM::GEOM_Shape_ptr aSubShape,
+ SMESH::SMESH_Hypothesis_ptr anHyp)
+ throw(SALOME::SALOME_Exception)
+{
+ Unexpect aCatch(SALOME_SalomeException);
+ SMESH_Hypothesis::Hypothesis_Status status = addHypothesis( aSubShape, anHyp );
+
+ if ( !SMESH_Hypothesis::IsStatusFatal(status) ) {
+ SALOMEDS::Study_ptr aStudy = _gen_i->GetCurrentStudy();
+
+ if ( !aStudy->_is_nil() ) {
+ // Detect whether <aSubShape> refers to this mesh or its sub-mesh
+ SALOMEDS::GenericAttribute_var anAttr;
+ SALOMEDS::AttributeIOR_var anIOR;
+ SALOMEDS::SObject_var aMeshSO = SALOMEDS::SObject::_narrow( aStudy->FindObjectIOR( ( SMESH_Gen_i::GetORB()->object_to_string( _this() ) ) ) );
+ SALOMEDS::SObject_var aMorSM, aRef;
+ CORBA::String_var aShapeIOR = CORBA::string_dup( SMESH_Gen_i::GetORB()->object_to_string( aSubShape ) );
+ SALOMEDS::ChildIterator_var it = aStudy->NewChildIterator( aMeshSO );
+
+ for ( it->InitEx( true ); it->More(); it->Next() ) {
+ SALOMEDS::SObject_var anObj = it->Value();
+ if ( anObj->ReferencedObject( aRef ) ) {
+ if ( aRef->FindAttribute( anAttr, "AttributeIOR" ) ) {
+ anIOR = SALOMEDS::AttributeIOR::_narrow( anAttr );
+ if ( strcmp( anIOR->Value(), aShapeIOR ) == 0 ) {
+ aMorSM = anObj->GetFather();
+ break;
+ }
+ }
+ }
+ }
+
+ bool aIsAlgo = !SMESH::SMESH_Algo::_narrow( anHyp )->_is_nil();
+ SALOMEDS::SObject_var aHypSO = SALOMEDS::SObject::_narrow( aStudy->FindObjectIOR( ( SMESH_Gen_i::GetORB()->object_to_string( anHyp ) ) ) );
+ if ( !aMorSM->_is_nil() && !aHypSO->_is_nil() ) {
+ //Find or Create Applied Hypothesis root
+ SALOMEDS::SObject_var AHR;
+ SALOMEDS::AttributeName_var aName;
+ SALOMEDS::AttributeSelectable_var aSelAttr;
+ SALOMEDS::AttributePixMap_var aPixmap;
+ SALOMEDS::StudyBuilder_var aBuilder = aStudy->NewBuilder();
+ long aTag = aIsAlgo ? SMESH_Gen_i::GetRefOnAppliedAlgorithmsTag() : SMESH_Gen_i::GetRefOnAppliedHypothesisTag();
+
+ if ( !aMorSM->FindSubObject( aTag, AHR ) ) {
+ AHR = aBuilder->NewObjectToTag( aMorSM, aTag );
+ anAttr = aBuilder->FindOrCreateAttribute( AHR, "AttributeName" );
+ aName = SALOMEDS::AttributeName::_narrow( anAttr );
+ aName ->SetValue( aIsAlgo ? "Applied algorithms" : "Applied hypotheses" );
+ anAttr = aBuilder->FindOrCreateAttribute( AHR, "AttributeSelectable" );
+ aSelAttr = SALOMEDS::AttributeSelectable::_narrow( anAttr );
+ aSelAttr ->SetSelectable( false );
+ anAttr = aBuilder->FindOrCreateAttribute( AHR, "AttributePixMap" );
+ aPixmap = SALOMEDS::AttributePixMap::_narrow( anAttr );
+ aPixmap ->SetPixMap( aIsAlgo ? "ICON_SMESH_TREE_ALGO" : "ICON_SMESH_TREE_HYPO" );
+ }
+
+ SALOMEDS::SObject_var SO = aBuilder->NewObject( AHR );
+ aBuilder->Addreference( SO, aHypSO );
+ }
+ }
+ }
+
+ return ConvertHypothesisStatus(status);
+}
+
+//=============================================================================
+/*!
+ *
+ */
+//=============================================================================
+
+SMESH_Hypothesis::Hypothesis_Status
+ SMESH_Mesh_i::addHypothesis(GEOM::GEOM_Shape_ptr aSubShape,
+ SMESH::SMESH_Hypothesis_ptr anHyp)
+{
+ MESSAGE("addHypothesis");
// **** proposer liste de subShape (selection multiple)
GEOM::GEOM_Shape_var mySubShape = GEOM::GEOM_Shape::_narrow(aSubShape);
if (CORBA::is_nil(myHyp))
THROW_SALOME_CORBA_EXCEPTION("bad hypothesis reference",
SALOME::BAD_PARAM);
- bool ret = false;
+
+ SMESH_Hypothesis::Hypothesis_Status status = SMESH_Hypothesis::HYP_OK;
try
{
TopoDS_Shape myLocSubShape =
- _gen_i->_ShapeReader->GetShape(_geom, mySubShape);
+ _gen_i->GetShapeReader()->GetShape(SMESH_Gen_i::GetGeomEngine(), mySubShape);
int hypId = myHyp->GetId();
- ret = _impl->AddHypothesis(myLocSubShape, hypId);
+ status = _impl->AddHypothesis(myLocSubShape, hypId);
+ if ( !SMESH_Hypothesis::IsStatusFatal(status) )
+ _mapHypo[hypId] = myHyp;
}
catch(SALOME_Exception & S_ex)
{
THROW_SALOME_CORBA_EXCEPTION(S_ex.what(), SALOME::BAD_PARAM);
}
- return ret;
-};
+ return status;
+}
+
+//=============================================================================
+/*!
+ *
+ */
+//=============================================================================
+
+SMESH::Hypothesis_Status SMESH_Mesh_i::RemoveHypothesis(GEOM::GEOM_Shape_ptr aSubShape,
+ SMESH::SMESH_Hypothesis_ptr anHyp)
+ throw(SALOME::SALOME_Exception)
+{
+ Unexpect aCatch(SALOME_SalomeException);
+ SMESH_Hypothesis::Hypothesis_Status status = removeHypothesis( aSubShape, anHyp );
+
+ if ( !SMESH_Hypothesis::IsStatusFatal(status) ) {
+ SALOMEDS::Study_ptr aStudy = _gen_i->GetCurrentStudy();
+
+ if ( !aStudy->_is_nil() ) {
+ // Detect whether <aSubShape> refers to this mesh or its sub-mesh
+ SALOMEDS::GenericAttribute_var anAttr;
+ SALOMEDS::AttributeIOR_var anIOR;
+ SALOMEDS::SObject_var aMeshSO = SALOMEDS::SObject::_narrow( aStudy->FindObjectIOR( ( SMESH_Gen_i::GetORB()->object_to_string( _this() ) ) ) );
+ if ( aMeshSO->_is_nil() )
+ return SMESH::HYP_UNKNOWN_FATAL;
+
+ SALOMEDS::SObject_var aMorSM, aRef;
+ CORBA::String_var aShapeIOR = CORBA::string_dup( SMESH_Gen_i::GetORB()->object_to_string( aSubShape ) );
+ SALOMEDS::ChildIterator_var it = aStudy->NewChildIterator( aMeshSO );
+
+ for ( it->InitEx( true ); it->More(); it->Next() ) {
+ SALOMEDS::SObject_var anObj = it->Value();
+ if ( anObj->ReferencedObject( aRef ) ) {
+ if ( aRef->FindAttribute( anAttr, "AttributeIOR" ) ) {
+ anIOR = SALOMEDS::AttributeIOR::_narrow( anAttr );
+ if ( strcmp( anIOR->Value(), aShapeIOR ) == 0 ) {
+ aMorSM = anObj->GetFather();
+ break;
+ }
+ }
+ }
+ }
+
+ bool aIsAlgo = !SMESH::SMESH_Algo::_narrow( anHyp )->_is_nil();
+ SALOMEDS::SObject_var aHypSO = SALOMEDS::SObject::_narrow( aStudy->FindObjectIOR( ( SMESH_Gen_i::GetORB()->object_to_string( anHyp ) ) ) );
+ if ( !aMorSM->_is_nil() && !aHypSO->_is_nil() ) {
+ // Remove a refernce to hypothesis or algorithm
+ SALOMEDS::SObject_var AHR;
+ SALOMEDS::AttributeName_var aName;
+ SALOMEDS::AttributeSelectable_var aSelAttr;
+ SALOMEDS::AttributePixMap_var aPixmap;
+ SALOMEDS::StudyBuilder_var aBuilder = aStudy->NewBuilder();
+ CORBA::String_var aHypIOR = CORBA::string_dup( SMESH_Gen_i::GetORB()->object_to_string( anHyp ) );
+ long aTag = aIsAlgo ? SMESH_Gen_i::GetRefOnAppliedAlgorithmsTag() : SMESH_Gen_i::GetRefOnAppliedHypothesisTag();
+
+ if ( aMorSM->FindSubObject( aTag, AHR ) ) {
+ SALOMEDS::ChildIterator_var it = aStudy->NewChildIterator( AHR );
+ for ( ; it->More(); it->Next() ) {
+ SALOMEDS::SObject_var anObj = it->Value();
+ if ( anObj->ReferencedObject( aRef ) ) {
+ if ( aRef->FindAttribute( anAttr, "AttributeIOR" ) ) {
+ anIOR = SALOMEDS::AttributeIOR::_narrow(anAttr);
+ if ( strcmp( anIOR->Value(), aHypIOR ) == 0 ) {
+ aBuilder->RemoveObject( anObj );
+ break;
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+
+ return ConvertHypothesisStatus(status);
+}
+
//=============================================================================
/*!
*/
//=============================================================================
-CORBA::Boolean
- SMESH_Mesh_i::RemoveHypothesis(GEOM::GEOM_Shape_ptr aSubShape,
- SMESH::SMESH_Hypothesis_ptr anHyp) throw(SALOME::SALOME_Exception)
+SMESH_Hypothesis::Hypothesis_Status
+ SMESH_Mesh_i::removeHypothesis(GEOM::GEOM_Shape_ptr aSubShape,
+ SMESH::SMESH_Hypothesis_ptr anHyp)
{
- MESSAGE("RemoveHypothesis");
+ MESSAGE("removeHypothesis()");
// **** proposer liste de subShape (selection multiple)
GEOM::GEOM_Shape_var mySubShape = GEOM::GEOM_Shape::_narrow(aSubShape);
SMESH::SMESH_Hypothesis_var myHyp = SMESH::SMESH_Hypothesis::_narrow(anHyp);
if (CORBA::is_nil(myHyp))
- THROW_SALOME_CORBA_EXCEPTION("bad hypothesis reference",
+ THROW_SALOME_CORBA_EXCEPTION("bad hypothesis reference",
SALOME::BAD_PARAM);
- bool ret = false;
+ SMESH_Hypothesis::Hypothesis_Status status = SMESH_Hypothesis::HYP_OK;
try
{
TopoDS_Shape myLocSubShape =
- _gen_i->_ShapeReader->GetShape(_geom, mySubShape);
+ _gen_i->GetShapeReader()->GetShape(SMESH_Gen_i::GetGeomEngine(), mySubShape);
int hypId = myHyp->GetId();
- ret = _impl->RemoveHypothesis(myLocSubShape, hypId);
+ status = _impl->RemoveHypothesis(myLocSubShape, hypId);
+ if ( !SMESH_Hypothesis::IsStatusFatal(status) )
+ _mapHypo.erase( hypId );
}
catch(SALOME_Exception & S_ex)
{
THROW_SALOME_CORBA_EXCEPTION(S_ex.what(), SALOME::BAD_PARAM);
}
- return ret;
-};
+ return status;
+}
-/**
- *@TODO Not implemented
+//=============================================================================
+/*!
+ *
*/
+//=============================================================================
+
SMESH::ListOfHypothesis *
SMESH_Mesh_i::GetHypothesisList(GEOM::GEOM_Shape_ptr aSubShape)
throw(SALOME::SALOME_Exception)
{
- MESSAGE("GetHypothesisList: Not implemented");
- return NULL;
-};
+ Unexpect aCatch(SALOME_SalomeException);
+ MESSAGE("GetHypothesisList");
+ GEOM::GEOM_Shape_var mySubShape = GEOM::GEOM_Shape::_narrow(aSubShape);
+ if (CORBA::is_nil(mySubShape))
+ THROW_SALOME_CORBA_EXCEPTION("bad subShape reference",
+ SALOME::BAD_PARAM);
+
+ SMESH::ListOfHypothesis_var aList = new SMESH::ListOfHypothesis();
+
+ try {
+ TopoDS_Shape myLocSubShape
+ = _gen_i->GetShapeReader()->GetShape(SMESH_Gen_i::GetGeomEngine(), mySubShape);
+
+ const list<const SMESHDS_Hypothesis*>& aLocalList = _impl->GetHypothesisList( myLocSubShape );
+ int i = 0, n = aLocalList.size();
+ aList->length( n );
+
+ for ( list<const SMESHDS_Hypothesis*>::const_iterator anIt = aLocalList.begin(); i < n && anIt != aLocalList.end(); anIt++ ) {
+ SMESHDS_Hypothesis* aHyp = (SMESHDS_Hypothesis*)(*anIt);
+ if ( _mapHypo.find( aHyp->GetID() ) != _mapHypo.end() )
+ aList[i++] = SMESH::SMESH_Hypothesis::_narrow( _mapHypo[aHyp->GetID()] );
+ }
+
+ aList->length( i );
+ }
+ catch(SALOME_Exception & S_ex) {
+ THROW_SALOME_CORBA_EXCEPTION(S_ex.what(), SALOME::BAD_PARAM);
+ }
+
+ return aList._retn();
+}
//=============================================================================
/*!
*
*/
//=============================================================================
-SMESH::SMESH_subMesh_ptr SMESH_Mesh_i::GetElementsOnShape(GEOM::
- GEOM_Shape_ptr aSubShape) throw(SALOME::SALOME_Exception)
+SMESH::SMESH_subMesh_ptr SMESH_Mesh_i::GetSubMesh(GEOM::GEOM_Shape_ptr aSubShape,
+ const char* theName )
+ throw(SALOME::SALOME_Exception)
{
- MESSAGE("SMESH_Mesh_i::GetElementsOnShape");
- GEOM::GEOM_Shape_var mySubShape = GEOM::GEOM_Shape::_narrow(aSubShape);
- if (CORBA::is_nil(mySubShape))
- THROW_SALOME_CORBA_EXCEPTION("bad subShape reference",
- SALOME::BAD_PARAM);
+ Unexpect aCatch(SALOME_SalomeException);
+ MESSAGE("SMESH_Mesh_i::GetElementsOnShape");
+ GEOM::GEOM_Shape_var mySubShape = GEOM::GEOM_Shape::_narrow(aSubShape);
+ if (CORBA::is_nil(mySubShape))
+ THROW_SALOME_CORBA_EXCEPTION("bad subShape reference",
+ SALOME::BAD_PARAM);
+
+ int subMeshId = 0;
+ try {
+ TopoDS_Shape myLocSubShape
+ = _gen_i->GetShapeReader()->GetShape(SMESH_Gen_i::GetGeomEngine(), mySubShape);
+
+ //Get or Create the SMESH_subMesh object implementation
+
+ ::SMESH_subMesh * mySubMesh = _impl->GetSubMesh(myLocSubShape);
+ subMeshId = mySubMesh->GetId();
+
+ // create a new subMesh object servant if there is none for the shape
+
+ if (_mapSubMesh.find(subMeshId) == _mapSubMesh.end()) {
+ SMESH::SMESH_subMesh_var subMesh = createSubMesh( aSubShape );
+ if ( _gen_i->CanPublishInStudy( subMesh ) ) {
+ SALOMEDS::SObject_var aSubmeshSO = _gen_i->PublishInStudy( _gen_i->GetCurrentStudy(),
+ SALOMEDS::SObject::_nil(),
+ subMesh,
+ theName );
+
+ // Add reference to <aSubShape> to the study
+ SALOMEDS::Study_var aStudy = _gen_i->GetCurrentStudy();
+ SALOMEDS::SObject_var aShapeSO = aStudy->FindObjectIOR( SMESH_Gen_i::GetORB()->object_to_string( aSubShape ) );
+ if ( !aSubmeshSO->_is_nil() && !aShapeSO->_is_nil() ) {
+ MESSAGE( "********** SMESH_Mesh_i::GetSubMesh(): adding shape reference..." )
+ SALOMEDS::StudyBuilder_var aBuilder = aStudy->NewBuilder();
+ SALOMEDS::SObject_var SO = aBuilder->NewObjectToTag( aSubmeshSO, SMESH_Gen_i::GetRefOnShapeTag() );
+ aBuilder->Addreference( SO, aShapeSO );
+ MESSAGE( "********** SMESH_Mesh_i::GetSubMesh(): shape reference added" )
+ }
+ }
+ }
+ }
+ catch(SALOME_Exception & S_ex) {
+ THROW_SALOME_CORBA_EXCEPTION(S_ex.what(), SALOME::BAD_PARAM);
+ }
+
+ ASSERT(_mapSubMeshIor.find(subMeshId) != _mapSubMeshIor.end());
+ return SMESH::SMESH_subMesh::_duplicate(_mapSubMeshIor[subMeshId]);
+}
- int subMeshId = 0;
- try
- {
- SMESH_subMesh_i *subMeshServant;
- TopoDS_Shape myLocSubShape
- = _gen_i->_ShapeReader->GetShape(_geom, mySubShape);
- //Get or Create the SMESH_subMesh object implementation
+//=============================================================================
+/*!
+ *
+ */
+//=============================================================================
+
+void SMESH_Mesh_i::RemoveSubMesh( SMESH::SMESH_subMesh_ptr theSubMesh )
+ throw (SALOME::SALOME_Exception)
+{
+ MESSAGE("SMESH_Mesh_i::RemoveSubMesh");
+ if ( theSubMesh->_is_nil() )
+ return;
+
+ GEOM::GEOM_Shape_var aSubShape;
+ SALOMEDS::Study_ptr aStudy = _gen_i->GetCurrentStudy();
+ if ( !aStudy->_is_nil() ) {
+ // Remove submesh's SObject
+ SALOMEDS::SObject_var anSO = SALOMEDS::SObject::_narrow( aStudy->FindObjectIOR( ( SMESH_Gen_i::GetORB()->object_to_string( theSubMesh ) ) ) );
+ if ( !anSO->_is_nil() ) {
+ long aTag = SMESH_Gen_i::GetRefOnShapeTag();
+ SALOMEDS::SObject_var anObj, aRef;
+ if ( anSO->FindSubObject( aTag, anObj ) && anObj->ReferencedObject( aRef ) )
+ aSubShape = GEOM::GEOM_Shape::_narrow( aRef->GetObject() );
+
+ aStudy->NewBuilder()->RemoveObjectWithChildren( anSO );
+ }
+ }
+
+ removeSubMesh( theSubMesh, aSubShape.in() );
+}
- ::SMESH_subMesh * mySubMesh = _impl->GetSubMesh(myLocSubShape);
- subMeshId = mySubMesh->GetId();
- // create a new subMesh object servant if there is none for the shape
+//=============================================================================
+/*!
+ *
+ */
+//=============================================================================
- if (_mapSubMesh.find(subMeshId) != _mapSubMesh.end())
- {
- ASSERT(_mapSubMesh_i.find(subMeshId) != _mapSubMesh_i.end());
- subMeshServant = _mapSubMesh_i[subMeshId];
- }
- else
- {
- // create and activate the CORBA servant of Mesh
- subMeshServant = new SMESH_subMesh_i(_gen_i, this, subMeshId);
- SMESH::SMESH_subMesh_var subMesh
- = SMESH::SMESH_subMesh::_narrow(subMeshServant->_this());
- _mapSubMesh[subMeshId] = mySubMesh;
- _mapSubMesh_i[subMeshId] = subMeshServant;
- _mapSubMeshIor[subMeshId]
- = SMESH::SMESH_subMesh::_duplicate(subMesh);
- }
- }
- catch(SALOME_Exception & S_ex)
- {
- THROW_SALOME_CORBA_EXCEPTION(S_ex.what(), SALOME::BAD_PARAM);
- }
+SMESH::SMESH_Group_ptr SMESH_Mesh_i::CreateGroup( SMESH::ElementType theElemType,
+ const char* theName )
+ throw(SALOME::SALOME_Exception)
+{
+ Unexpect aCatch(SALOME_SalomeException);
+ SMESH::SMESH_Group_var aNewGroup = createGroup( theElemType, theName );
+
+ // Groups should be put under separate roots according to their type (nodes, edges, faces, volumes)
+ if ( _gen_i->CanPublishInStudy( aNewGroup ) ) {
+ SALOMEDS::SObject_var aGroupSO = _gen_i->PublishInStudy( _gen_i->GetCurrentStudy(),
+ SALOMEDS::SObject::_nil(),
+ aNewGroup,
+ theName );
+ }
+
+ return aNewGroup._retn();
+}
- ASSERT(_mapSubMeshIor.find(subMeshId) != _mapSubMeshIor.end());
- return SMESH::SMESH_subMesh::_duplicate(_mapSubMeshIor[subMeshId]);
-}
-
-/**
- * Translate the UpdateAll SMESHDS_Command to a set of SMESH::log_command.
- * As the input log need to be resized, it is realocated.
- * @param logBlock The log where to insert created commands
- * @param index The place where to insert created commands in log. It is updated
- * with the place to put new elements.
- * @return The realocated and resized log.
- * @TODO Add support for other type of elements
- */
-SMESH::log_array_var SMESH_Mesh_i::
- createUpdateAllCommand(SMESH::log_array_var log, int * index)
-{
- MESSAGE("SMESH_Mesh_i::createUpdateAllCommand");
- SMESH::log_array_var aLog=new SMESH::log_array(log->length()+3);
- aLog->length(log->length()+3);
-
- for(int i=0;i<*index;i++)
- {
- aLog[i]=log[i];
- }
-
- log->length(0);
- int id=*index;
-
- //Remove all elements
- aLog[id].commandType=SMESH::REMOVE_ALL;
- id++;
-
- //Export nodes
- aLog[id].commandType=SMESH::ADD_NODE;
- aLog[id].number=_impl->GetMeshDS()->NbNodes();
-
- double * nodesCoordinates=_impl->GetMeshDS()->getNodesCoordinates();
- aLog[id].coords=SMESH::double_array(
- aLog[id].number*3,
- aLog[id].number*3,
- nodesCoordinates);
-
- long * nodesID=_impl->GetMeshDS()->getNodesID();
- aLog[id].indexes=SMESH::long_array(
- aLog[id].number,
- aLog[id].number,
- nodesID);
-
- id++;
-
- MESSAGE("Export edges");
- //Export edges
- aLog[id].commandType=SMESH::ADD_EDGE;
- aLog[id].number=_impl->GetMeshDS()->NbEdges();
- aLog[id].coords.length(0);
-
- long * edgesIndices=_impl->GetMeshDS()->getEdgesIndices();
- aLog[id].indexes=SMESH::long_array(
- aLog[id].number*3,
- aLog[id].number*3,
- edgesIndices);
-
- id++;
-
- MESSAGE("Export triangles");
- //Export triangles
- aLog[id].commandType=SMESH::ADD_TRIANGLE;
- aLog[id].number=_impl->GetMeshDS()->NbTriangles();
- aLog[id].coords.length(0);
-
- long * triasIndices=_impl->GetMeshDS()->getTrianglesIndices();
- aLog[id].indexes=SMESH::long_array(
- aLog[id].number*4,
- aLog[id].number*4,
- triasIndices);
-
- (*index)=id;
- return aLog;
-}
-
-/**
- * Return the log of the current mesh. CORBA wrap of the SMESH::GetLog method
- * with a special treatment for SMESHDS_UpdateAll commands
- * @param clearAfterGet Tell if the log must be cleared after being returned
- * @return the log
+
+//=============================================================================
+/*!
+ *
*/
+//=============================================================================
+
+void SMESH_Mesh_i::RemoveGroup( SMESH::SMESH_Group_ptr theGroup )
+ throw (SALOME::SALOME_Exception)
+{
+ if ( theGroup->_is_nil() )
+ return;
+
+ SMESH_Group_i* aGroup = dynamic_cast<SMESH_Group_i*>( SMESH_Gen_i::GetServant( theGroup ).in() );
+ if ( !aGroup )
+ return;
+
+ SALOMEDS::Study_ptr aStudy = _gen_i->GetCurrentStudy();
+ if ( !aStudy->_is_nil() ) {
+ // Remove group's SObject
+ SALOMEDS::SObject_var aGroupSO = SALOMEDS::SObject::_narrow( aStudy->FindObjectIOR( ( SMESH_Gen_i::GetORB()->object_to_string( theGroup ) ) ) );
+ if ( !aGroupSO->_is_nil() )
+ aStudy->NewBuilder()->RemoveObject( aGroupSO );
+ }
+
+ // Remove the group from SMESH data structures
+ removeGroup( aGroup->GetLocalID() );
+}
+
+
+//=============================================================================
+/*!
+ *
+ */
+//=============================================================================
+
+SMESH::SMESH_subMesh_ptr SMESH_Mesh_i::createSubMesh( GEOM::GEOM_Shape_ptr theSubShape ) {
+
+ TopoDS_Shape myLocSubShape = _gen_i->GetShapeReader()->GetShape(SMESH_Gen_i::GetGeomEngine(), theSubShape);
+
+ ::SMESH_subMesh * mySubMesh = _impl->GetSubMesh(myLocSubShape);
+ int subMeshId = mySubMesh->GetId();
+ SMESH_subMesh_i *subMeshServant = new SMESH_subMesh_i(myPOA, _gen_i, this, subMeshId);
+ SMESH::SMESH_subMesh_var subMesh
+ = SMESH::SMESH_subMesh::_narrow(subMeshServant->_this());
+
+ _mapSubMesh[subMeshId] = mySubMesh;
+ _mapSubMesh_i[subMeshId] = subMeshServant;
+ _mapSubMeshIor[subMeshId]
+ = SMESH::SMESH_subMesh::_duplicate(subMesh);
+
+ // register CORBA object for persistence
+ StudyContext* myStudyContext = _gen_i->GetCurrentStudyContext();
+ string iorString = SMESH_Gen_i::GetORB()->object_to_string( subMesh );
+ int nextId = myStudyContext->addObject( iorString );
+ MESSAGE( "Add submesh to map with id = "<< nextId << " and IOR = " << iorString.c_str() );
+
+ return subMesh._retn();
+}
+
+
+//=============================================================================
+/*!
+ *
+ */
+//=============================================================================
+
+void SMESH_Mesh_i::removeSubMesh( SMESH::SMESH_subMesh_ptr theSubMesh, GEOM::GEOM_Shape_ptr theSubShape )
+{
+ MESSAGE("SMESH_Mesh_i::removeSubMesh()");
+ if ( theSubMesh->_is_nil() || theSubShape->_is_nil() )
+ return;
+
+ try {
+ SMESH::ListOfHypothesis_var aHypList = GetHypothesisList( theSubShape );
+ for ( int i = 0, n = aHypList->length(); i < n; i++ ) {
+ removeHypothesis( theSubShape, aHypList[i] );
+ }
+ }
+ catch( const SALOME::SALOME_Exception& ) {
+ MESSAGE("SMESH_Mesh_i::removeSubMesh(): exception caught!");
+ }
+
+ int subMeshId = theSubMesh->GetId();
+
+ _mapSubMesh.erase(subMeshId);
+ _mapSubMesh_i.erase(subMeshId);
+ _mapSubMeshIor.erase(subMeshId);
+ MESSAGE("SMESH_Mesh_i::removeSubMesh() completed");
+}
+
+//=============================================================================
+/*!
+ *
+ */
+//=============================================================================
+
+SMESH::SMESH_Group_ptr SMESH_Mesh_i::createGroup( SMESH::ElementType theElemType, const char* theName )
+{
+ int anId;
+ SMESH::SMESH_Group_var aGroup;
+ if ( _impl->AddGroup( (SMDSAbs_ElementType)theElemType, theName, anId ) ) {
+ SMESH_Group_i* aGroupImpl = new SMESH_Group_i( SMESH_Gen_i::GetPOA(), this, anId );
+ aGroup = SMESH::SMESH_Group::_narrow( aGroupImpl->_this() );
+ _mapGroups[anId] = SMESH::SMESH_Group::_duplicate( aGroup );
+
+ // register CORBA object for persistence
+ StudyContext* myStudyContext = _gen_i->GetCurrentStudyContext();
+ string iorString = SMESH_Gen_i::GetORB()->object_to_string( aGroup );
+ int nextId = myStudyContext->addObject( iorString );
+ MESSAGE( "Add group to map with id = "<< nextId << " and IOR = " << iorString.c_str() );
+ }
+ return aGroup._retn();
+}
+
+
+//=============================================================================
+/*!
+ * SMESH_Mesh_i::removeGroup
+ *
+ * Should be called by ~SMESH_Group_i()
+ */
+//=============================================================================
+
+void SMESH_Mesh_i::removeGroup( const int theId )
+{
+ MESSAGE("SMESH_Mesh_i::removeGroup()" );
+ if ( _mapGroups.find( theId ) != _mapGroups.end() ) {
+ _mapGroups.erase( theId );
+ _impl->RemoveGroup( theId );
+ }
+}
+
+
+//=============================================================================
+/*!
+ *
+ */
+//=============================================================================
+
SMESH::log_array * SMESH_Mesh_i::GetLog(CORBA::Boolean clearAfterGet)
- throw(SALOME::SALOME_Exception)
+throw(SALOME::SALOME_Exception)
{
MESSAGE("SMESH_Mesh_i::GetLog");
SMESH::log_array_var aLog;
- /*try
- {*/
+ try
+ {
list < SMESHDS_Command * >logDS = _impl->GetLog();
aLog = new SMESH::log_array;
int indexLog = 0;
int lg = logDS.size();
- MESSAGE("Number of command in the log: "<<lg);
+ SCRUTE(lg);
aLog->length(lg);
list < SMESHDS_Command * >::iterator its = logDS.begin();
while (its != logDS.end())
//SCRUTE(rnum);
list < double >::const_iterator ir = coordList.begin();
aLog[indexLog].commandType = comType;
- if(comType==SMESHDS_UpdateAll)
+ aLog[indexLog].number = lgcom;
+ aLog[indexLog].coords.length(rnum);
+ aLog[indexLog].indexes.length(inum);
+ for (int i = 0; i < rnum; i++)
{
- aLog=createUpdateAllCommand(aLog, &indexLog);
+ aLog[indexLog].coords[i] = *ir;
+ //MESSAGE(" "<<i<<" "<<ir.Value());
+ ir++;
}
- else
+ for (int i = 0; i < inum; i++)
{
- aLog[indexLog].number = lgcom;
- aLog[indexLog].coords.length(rnum);
- aLog[indexLog].indexes.length(inum);
- for (int i = 0; i < rnum; i++)
- {
- aLog[indexLog].coords[i] = *ir;
- //MESSAGE(" "<<i<<" "<<ir.Value());
- ir++;
- }
- for (int i = 0; i < inum; i++)
- {
- aLog[indexLog].indexes[i] = *ii;
- //MESSAGE(" "<<i<<" "<<ii.Value());
- ii++;
- }
- indexLog++;
+ aLog[indexLog].indexes[i] = *ii;
+ //MESSAGE(" "<<i<<" "<<ii.Value());
+ ii++;
}
+ indexLog++;
its++;
}
- if (clearAfterGet) _impl->ClearLog();
- return aLog._retn();
- /*}
+ if (clearAfterGet)
+ _impl->ClearLog();
+ }
catch(SALOME_Exception & S_ex)
{
THROW_SALOME_CORBA_EXCEPTION(S_ex.what(), SALOME::BAD_PARAM);
- }*/
+ }
+ return aLog._retn();
}
// SMESH::string_array* SMESH_Mesh_i::GetLog(CORBA::Boolean clearAfterGet)
CORBA::Long SMESH_Mesh_i::GetId()throw(SALOME::SALOME_Exception)
{
- return _impl->GetId();
+ MESSAGE("SMESH_Mesh_i::GetId");
+ return _id;
}
//=============================================================================
*/
//=============================================================================
-::SMESH_Mesh & SMESH_Mesh_i::GetImpl()
+void SMESH_Mesh_i::SetImpl(::SMESH_Mesh * impl)
{
- MESSAGE("SMESH_Mesh_i::GetImpl()");
- return *_impl;
+ MESSAGE("SMESH_Mesh_i::SetImpl");
+ _impl = impl;
}
//=============================================================================
*/
//=============================================================================
-GEOM::GEOM_Gen_ptr SMESH_Mesh_i::GetGeomEngine()
+::SMESH_Mesh & SMESH_Mesh_i::GetImpl()
{
- MESSAGE("SMESH_Mesh_i::GetGeomEngine");
- return GEOM::GEOM_Gen::_duplicate(_geom);
+ MESSAGE("SMESH_Mesh_i::GetImpl()");
+ return *_impl;
}
+
//=============================================================================
/*!
*
*/
//=============================================================================
-void SMESH_Mesh_i::SetIor(SMESH::SMESH_Mesh_ptr myIor)
+SMESH::SMESH_MeshEditor_ptr SMESH_Mesh_i::GetMeshEditor()
{
- MESSAGE("SMESH_Mesh_i::SetIor");
- _myIor = SMESH::SMESH_Mesh::_duplicate(myIor);
- ASSERT(!CORBA::is_nil(_myIor));
+ SMESH_MeshEditor_i *aMeshEditor =
+ new SMESH_MeshEditor_i(_impl->GetMeshDS());
+ SMESH::SMESH_MeshEditor_var aMesh = aMeshEditor->_this();
+ return aMesh._retn();
}
//=============================================================================
*/
//=============================================================================
-SMESH::SMESH_Mesh_ptr SMESH_Mesh_i::GetIor()
+void SMESH_Mesh_i::ExportMED(const char *file, CORBA::Boolean auto_groups) throw(SALOME::SALOME_Exception)
{
- MESSAGE("SMESH_Mesh_i::GetIor");
- ASSERT(!CORBA::is_nil(_myIor));
- return SMESH::SMESH_Mesh::_duplicate(_myIor);
+ Unexpect aCatch(SALOME_SalomeException);
+ SALOMEDS::Study_ptr aStudy = _gen_i->GetCurrentStudy();
+ if ( aStudy->_is_nil() )
+ return;
+
+ char* aMeshName = NULL;
+ SALOMEDS::SObject_var aMeshSO = SALOMEDS::SObject::_narrow( aStudy->FindObjectIOR( ( SMESH_Gen_i::GetORB()->object_to_string( _this() ) ) ) );
+ if ( !aMeshSO->_is_nil() )
+ {
+ aMeshName = aMeshSO->GetName();
+ //SCRUTE(file);
+ //SCRUTE(aMeshName);
+ //SCRUTE(aMeshSO->GetID());
+ SALOMEDS::GenericAttribute_var anAttr;
+ SALOMEDS::StudyBuilder_var aStudyBuilder = aStudy->NewBuilder();
+ SALOMEDS::AttributeExternalFileDef_var aFileName;
+ anAttr=aStudyBuilder->FindOrCreateAttribute(aMeshSO, "AttributeExternalFileDef");
+ aFileName = SALOMEDS::AttributeExternalFileDef::_narrow(anAttr);
+ ASSERT(!aFileName->_is_nil());
+ aFileName->SetValue(file);
+ SALOMEDS::AttributeFileType_var aFileType;
+ anAttr=aStudyBuilder->FindOrCreateAttribute(aMeshSO, "AttributeFileType");
+ aFileType = SALOMEDS::AttributeFileType::_narrow(anAttr);
+ ASSERT(!aFileType->_is_nil());
+ aFileType->SetValue("FICHIERMED");
+ }
+ _impl->ExportMED( file, aMeshName, auto_groups );
}
-//=============================================================================
-/*!
- *
- */
-//=============================================================================
-
-SMESH::SMESH_MeshEditor_ptr SMESH_Mesh_i::GetMeshEditor()
+void SMESH_Mesh_i::ExportDAT(const char *file) throw(SALOME::SALOME_Exception)
{
- SMESH_MeshEditor_i *aMeshEditor =
- new SMESH_MeshEditor_i(_impl->GetMeshDS());
- SMESH::SMESH_MeshEditor_var aMesh = aMeshEditor->_this();
- return aMesh._retn();
+ Unexpect aCatch(SALOME_SalomeException);
+ _impl->ExportDAT(file);
+}
+void SMESH_Mesh_i::ExportUNV(const char *file) throw(SALOME::SALOME_Exception)
+{
+ Unexpect aCatch(SALOME_SalomeException);
+ _impl->ExportUNV(file);
}
//=============================================================================
SALOME_MED::MESH_ptr SMESH_Mesh_i::GetMEDMesh()throw(SALOME::SALOME_Exception)
{
+ Unexpect aCatch(SALOME_SalomeException);
SMESH_MEDMesh_i *aMedMesh = new SMESH_MEDMesh_i(this);
SALOME_MED::MESH_var aMesh = aMedMesh->_this();
return aMesh._retn();
//=============================================================================
CORBA::Long SMESH_Mesh_i::NbNodes()throw(SALOME::SALOME_Exception)
{
+ Unexpect aCatch(SALOME_SalomeException);
return _impl->NbNodes();
}
//=============================================================================
CORBA::Long SMESH_Mesh_i::NbEdges()throw(SALOME::SALOME_Exception)
{
+ Unexpect aCatch(SALOME_SalomeException);
return _impl->NbEdges();
}
//=============================================================================
CORBA::Long SMESH_Mesh_i::NbFaces()throw(SALOME::SALOME_Exception)
{
+ Unexpect aCatch(SALOME_SalomeException);
return _impl->NbFaces();
}
CORBA::Long SMESH_Mesh_i::NbTriangles()throw(SALOME::SALOME_Exception)
{
+ Unexpect aCatch(SALOME_SalomeException);
return _impl->NbTriangles();
}
CORBA::Long SMESH_Mesh_i::NbQuadrangles()throw(SALOME::SALOME_Exception)
{
+ Unexpect aCatch(SALOME_SalomeException);
return _impl->NbQuadrangles();
}
//=============================================================================
CORBA::Long SMESH_Mesh_i::NbVolumes()throw(SALOME::SALOME_Exception)
{
+ Unexpect aCatch(SALOME_SalomeException);
return _impl->NbVolumes();
}
CORBA::Long SMESH_Mesh_i::NbTetras()throw(SALOME::SALOME_Exception)
{
+ Unexpect aCatch(SALOME_SalomeException);
return _impl->NbTetras();
}
CORBA::Long SMESH_Mesh_i::NbHexas()throw(SALOME::SALOME_Exception)
{
+ Unexpect aCatch(SALOME_SalomeException);
return _impl->NbHexas();
}
+CORBA::Long SMESH_Mesh_i::NbPyramids()throw(SALOME::SALOME_Exception)
+{
+ Unexpect aCatch(SALOME_SalomeException);
+ return _impl->NbPyramids();
+}
+
+CORBA::Long SMESH_Mesh_i::NbPrisms()throw(SALOME::SALOME_Exception)
+{
+ Unexpect aCatch(SALOME_SalomeException);
+ return _impl->NbPrisms();
+}
+
//=============================================================================
/*!
*
//=============================================================================
CORBA::Long SMESH_Mesh_i::NbSubMesh()throw(SALOME::SALOME_Exception)
{
+ Unexpect aCatch(SALOME_SalomeException);
return _impl->NbSubMesh();
}
+//=============================================================================
/*!
- * Export mesh to a file
- * @param fileName file name where to export the file
- * @param fileType Currently it could be either "DAT", "UNV" or "MED".
+ *
*/
-void SMESH_Mesh_i::Export(const char* fileName, const char* fileType)
- throw (SALOME::SALOME_Exception)
+//=============================================================================
+char* SMESH_Mesh_i::Dump()
{
- _impl->Export(fileName, fileType);
+ std::ostringstream os;
+ _impl->Dump( os );
+ return CORBA::string_dup( os.str().c_str() );
}
#include <SALOMEconfig.h>
#include CORBA_SERVER_HEADER(SMESH_Mesh)
+#include CORBA_SERVER_HEADER(SMESH_Group)
#include CORBA_SERVER_HEADER(SMESH_Hypothesis)
#include CORBA_CLIENT_HEADER(GEOM_Gen)
#include CORBA_CLIENT_HEADER(GEOM_Shape)
#include CORBA_CLIENT_HEADER(MED)
class SMESH_Gen_i;
+class SMESH_Group_i;
+#include "SMESH_Hypothesis.hxx"
#include "SMESH_Mesh.hxx"
-#include "SMESH_Gen_i.hxx"
#include "SMESH_subMesh_i.hxx"
#include "SMESH_subMesh.hxx"
#include "SMESH_topo.hxx"
#include <map>
+#include "SALOME_GenericObj_i.hh"
+
class SMESH_Mesh_i:
- public POA_SMESH::SMESH_Mesh
+ public virtual POA_SMESH::SMESH_Mesh,
+ public virtual SALOME::GenericObj_i
{
public:
- SMESH_Mesh_i(SMESH_Gen_i* myGen_i,
- GEOM::GEOM_Gen_ptr geomEngine,
- CORBA::Long studyId,
- ::SMESH_Mesh * impl);
+ SMESH_Mesh_i();
+ SMESH_Mesh_i( PortableServer::POA_ptr thePOA,
+ SMESH_Gen_i* myGen_i,
+ CORBA::Long studyId );
virtual ~SMESH_Mesh_i();
// --- CORBA
+ void SetShape( GEOM::GEOM_Shape_ptr theShape )
+ throw (SALOME::SALOME_Exception);
- CORBA::Boolean AddHypothesis(GEOM::GEOM_Shape_ptr aSubShape,
- SMESH::SMESH_Hypothesis_ptr anHyp)
+ SMESH::Hypothesis_Status AddHypothesis(GEOM::GEOM_Shape_ptr aSubShape,
+ SMESH::SMESH_Hypothesis_ptr anHyp)
throw (SALOME::SALOME_Exception);
- CORBA::Boolean RemoveHypothesis(GEOM::GEOM_Shape_ptr aSubShape,
- SMESH::SMESH_Hypothesis_ptr anHyp)
+ SMESH::Hypothesis_Status RemoveHypothesis(GEOM::GEOM_Shape_ptr aSubShape,
+ SMESH::SMESH_Hypothesis_ptr anHyp)
throw (SALOME::SALOME_Exception);
SMESH::ListOfHypothesis* GetHypothesisList(GEOM::GEOM_Shape_ptr aSubShape)
throw (SALOME::SALOME_Exception);
- SMESH::SMESH_subMesh_ptr GetElementsOnShape(GEOM::GEOM_Shape_ptr aSubShape)
+ SMESH::SMESH_subMesh_ptr GetSubMesh(GEOM::GEOM_Shape_ptr aSubShape, const char* theName)
+ throw (SALOME::SALOME_Exception);
+
+ void RemoveSubMesh( SMESH::SMESH_subMesh_ptr theSubMesh )
+ throw (SALOME::SALOME_Exception);
+
+ SMESH::SMESH_Group_ptr CreateGroup( SMESH::ElementType theElemType, const char* theName )
+ throw (SALOME::SALOME_Exception);
+
+ void RemoveGroup( SMESH::SMESH_Group_ptr theGroup )
throw (SALOME::SALOME_Exception);
// SMESH::string_array* GetLog(CORBA::Boolean clearAfterGet)
CORBA::Long GetStudyId()
throw (SALOME::SALOME_Exception);
- void Export(const char* fileName, const char* fileType)
- throw (SALOME::SALOME_Exception);
-
// --- C++ interface
void SetImpl(::SMESH_Mesh* impl);
-
::SMESH_Mesh& GetImpl(); // :: force no namespace here
- GEOM::GEOM_Gen_ptr GetGeomEngine();
- void SetIor(SMESH::SMESH_Mesh_ptr myIor);
- SMESH::SMESH_Mesh_ptr GetIor();
+
+ SMESH_Gen_i* GetGen() { return _gen_i; }
+
+ /*!
+ * consult DriverMED_R_SMESHDS_Mesh::ReadStatus for returned value
+ */
+ SMESH::DriverMED_ReadStatus ImportMEDFile( const char* theFileName, const char* theMeshName )
+ throw (SALOME::SALOME_Exception);
+
+ void ExportMED( const char* file, CORBA::Boolean auto_groups )
+ throw (SALOME::SALOME_Exception);
+ void ExportDAT( const char* file )
+ throw (SALOME::SALOME_Exception);
+ void ExportUNV( const char* file )
+ throw (SALOME::SALOME_Exception);
SALOME_MED::MESH_ptr GetMEDMesh()
throw (SALOME::SALOME_Exception);
CORBA::Long NbHexas()
throw (SALOME::SALOME_Exception);
+ CORBA::Long NbPyramids()
+ throw (SALOME::SALOME_Exception);
+
+ CORBA::Long NbPrisms()
+ throw (SALOME::SALOME_Exception);
+
CORBA::Long NbSubMesh()
throw (SALOME::SALOME_Exception);
+
+ char* Dump();
+ // Internal methods not available through CORBA
+ // They are called by corresponding interface methods
+ SMESH_Hypothesis::Hypothesis_Status addHypothesis(GEOM::GEOM_Shape_ptr aSubShape,
+ SMESH::SMESH_Hypothesis_ptr anHyp);
+
+ SMESH_Hypothesis::Hypothesis_Status removeHypothesis(GEOM::GEOM_Shape_ptr aSubShape,
+ SMESH::SMESH_Hypothesis_ptr anHyp);
+
+ bool setShape( GEOM::GEOM_Shape_ptr theShape );
+
+ int importMEDFile( const char* theFileName, const char* theMeshName );
+
+ SMESH::SMESH_subMesh_ptr createSubMesh( GEOM::GEOM_Shape_ptr theSubShape );
+
+ void removeSubMesh( SMESH::SMESH_subMesh_ptr theSubMesh, GEOM::GEOM_Shape_ptr theSubShape );
+
+ SMESH::SMESH_Group_ptr createGroup( SMESH::ElementType theElemType, const char* theName );
+
+ void removeGroup( const int theId );
map<int, SMESH_subMesh_i*> _mapSubMesh_i; //NRI
map<int, ::SMESH_subMesh*> _mapSubMesh; //NRI
private:
- SMESH::log_array_var createUpdateAllCommand(SMESH::log_array_var log, int * index);
+ static int myIdGenerator;
::SMESH_Mesh* _impl; // :: force no namespace here
SMESH_Gen_i* _gen_i;
- // CORBA::ORB_ptr _orb;
-// SMESH_topo* _topo; // all local TopoDS_Shape of subShapes
- GEOM::GEOM_Gen_var _geom;
- CORBA::Long _studyId;
- map<int, SMESH::SMESH_subMesh_ptr> _mapSubMeshIor;
- SMESH::SMESH_Mesh_var _myIor;
+ int _id; // id given by creator (unique within the creator instance)
+ int _studyId;
+ map<int, SMESH::SMESH_subMesh_ptr> _mapSubMeshIor;
+ map<int, SMESH::SMESH_Group_ptr> _mapGroups;
+ map<int, SMESH::SMESH_Hypothesis_ptr> _mapHypo;
};
#endif
+++ /dev/null
-//=============================================================================
-// File : SMESH_NETGEN_3D_i.cxx
-// Created : Jeudi 31 Janvier 2003
-// Author : Nadir Bouhamou CEA
-// Project : SALOME
-// Copyright : CEA 2003
-// $Header$
-//=============================================================================
-using namespace std;
-
-#include "SMESH_NETGEN_3D_i.hxx"
-#include "SMESH_Gen.hxx"
-#include "SMESH_HypothesisFactory.hxx"
-
-#include "Utils_CorbaException.hxx"
-#include "utilities.h"
-
-//=============================================================================
-/*!
- *
- */
-//=============================================================================
-
-SMESH_NETGEN_3D_i::SMESH_NETGEN_3D_i(const char* anHyp,
- int studyId,
- ::SMESH_Gen* genImpl)
-{
- MESSAGE("SMESH_NETGEN_3D_i::SMESH_NETGEN_3D_i");
- _genImpl = genImpl;
- ::SMESH_NETGEN_3D* impl
- = new ::SMESH_NETGEN_3D(_genImpl->_hypothesisFactory.GetANewId(),
- studyId,
- genImpl);
- SetImpl(impl);
- _baseImpl = _impl;
-}
-
-//=============================================================================
-/*!
- *
- */
-//=============================================================================
-
-SMESH_NETGEN_3D_i::~SMESH_NETGEN_3D_i()
-{
- MESSAGE("SMESH_NETGEN_3D_i::~SMESH_NETGEN_3D_i");
-}
-
-//=============================================================================
-/*!
- *
- */
-//=============================================================================
-
-void SMESH_NETGEN_3D_i::SetImpl(::SMESH_NETGEN_3D* impl)
-{
- MESSAGE("SMESH_NETGEN_3D_i::SetImpl");
- SMESH_3D_Algo_i::SetImpl(impl);
- _impl = impl;
-}
+++ /dev/null
-//=============================================================================
-// File : SMESH_NETGEN_3D_i.hxx
-// Created : Jeudi 31 Janvier 2003
-// Author : Nadir Bouhamou CEA
-// Project : SALOME
-// Copyright : CEA 2003
-// $Header$
-//=============================================================================
-#ifndef _SMESH_NETGEN_3D_I_HXX_
-#define _SMESH_NETGEN_3D_I_HXX_
-
-#include <SALOMEconfig.h>
-#include CORBA_SERVER_HEADER(SMESH_BasicHypothesis)
-
-#include "SMESH_3D_Algo_i.hxx"
-
-#include "SMESH_NETGEN_3D.hxx"
-
-class SMESH_NETGEN_3D_i:
- public POA_SMESH::SMESH_NETGEN_3D,
- public SMESH_3D_Algo_i
-{
-public:
- SMESH_NETGEN_3D_i(const char* anHyp,
- int studyId,
- ::SMESH_Gen* genImpl);
-
- virtual ~SMESH_NETGEN_3D_i();
-
-protected:
- virtual void SetImpl(::SMESH_NETGEN_3D* impl);
-
- ::SMESH_NETGEN_3D* _impl;
-};
-
-#endif
+++ /dev/null
-// SMESH SMESH_I : idl implementation based on 'SMESH' unit's calsses
-//
-// Copyright (C) 2003 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
-// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
-//
-// This library 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.
-//
-// This library 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 this library; if not, write to the Free Software
-// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
-//
-// See http://www.opencascade.org/SALOME/ or email : webmaster.salome@opencascade.org
-//
-//
-//
-// File : SMESH_NumberOfSegments_i.cxx
-// Author : Paul RASCLE, EDF
-// Module : SMESH
-// $Header$
-
-using namespace std;
-using namespace std;
-#include "SMESH_NumberOfSegments_i.hxx"
-#include "SMESH_Gen.hxx"
-#include "SMESH_HypothesisFactory.hxx"
-
-#include "Utils_CorbaException.hxx"
-#include "utilities.h"
-
-//=============================================================================
-/*!
- * Constructor:
- * _name is related to the class name: prefix = SMESH_ ; suffix = _i .
- */
-//=============================================================================
-
-SMESH_NumberOfSegments_i::SMESH_NumberOfSegments_i(const char* anHyp,
- int studyId,
- ::SMESH_Gen* genImpl)
-{
- MESSAGE("SMESH_NumberOfSegments_i::SMESH_NumberOfSegments_i");
- _impl= new ::SMESH_NumberOfSegments(genImpl->_hypothesisFactory.GetANewId(),
- studyId,
- genImpl);
- _baseImpl = _impl;
-}
-
-//=============================================================================
-/*!
- *
- */
-//=============================================================================
-
-SMESH_NumberOfSegments_i::~SMESH_NumberOfSegments_i()
-{
-}
-
-//=============================================================================
-/*!
- *
- */
-//=============================================================================
-
-void
-SMESH_NumberOfSegments_i::SetNumberOfSegments(CORBA::Long segmentsNumber)
- throw (SALOME::SALOME_Exception)
-{
- ASSERT(_impl);
- try
- {
- _impl->SetNumberOfSegments(segmentsNumber);
- }
- catch (SALOME_Exception& S_ex)
- {
- THROW_SALOME_CORBA_EXCEPTION(S_ex.what(), \
- SALOME::BAD_PARAM);
- }
-}
-
-//=============================================================================
-/*!
- *
- */
-//=============================================================================
-
-CORBA::Long SMESH_NumberOfSegments_i::GetNumberOfSegments()
-{
- ASSERT(_impl);
- return _impl->GetNumberOfSegments();
-}
-
-//=============================================================================
-/*!
- *
- */
-//=============================================================================
-
-void
-SMESH_NumberOfSegments_i::SetScaleFactor(CORBA::Double scaleFactor)
- throw (SALOME::SALOME_Exception)
-{
- ASSERT(_impl);
- try
- {
- _impl->SetScaleFactor(scaleFactor);
- }
- catch (SALOME_Exception& S_ex)
- {
- THROW_SALOME_CORBA_EXCEPTION(S_ex.what(), \
- SALOME::BAD_PARAM);
- }
-}
-
-//=============================================================================
-/*!
- *
- */
-//=============================================================================
-
-CORBA::Double SMESH_NumberOfSegments_i::GetScaleFactor()
-{
- ASSERT(_impl);
- return _impl->GetScaleFactor();
-}
-
+++ /dev/null
-// SMESH SMESH_I : idl implementation based on 'SMESH' unit's calsses
-//
-// Copyright (C) 2003 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
-// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
-//
-// This library 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.
-//
-// This library 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 this library; if not, write to the Free Software
-// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
-//
-// See http://www.opencascade.org/SALOME/ or email : webmaster.salome@opencascade.org
-//
-//
-//
-// File : SMESH_NumberOfSegments_i.hxx
-// Author : Paul RASCLE, EDF
-// Module : SMESH
-// $Header$
-
-#ifndef _SMESH_NUMBEROFSEGMENTS_I_HXX_
-#define _SMESH_NUMBEROFSEGMENTS_I_HXX_
-
-#include <SALOMEconfig.h>
-#include CORBA_SERVER_HEADER(SMESH_BasicHypothesis)
-
-#include "SMESH_Hypothesis_i.hxx"
-
-#include "SMESH_NumberOfSegments.hxx"
-
-class SMESH_NumberOfSegments_i:
- public POA_SMESH::SMESH_NumberOfSegments,
- public SMESH_Hypothesis_i
-{
-public:
- SMESH_NumberOfSegments_i(const char* anHyp,
- int studyId,
- ::SMESH_Gen* genImpl);
- virtual ~SMESH_NumberOfSegments_i();
-
- void SetNumberOfSegments(CORBA::Long segmentsNumber)
- throw (SALOME::SALOME_Exception);
-
- CORBA::Long GetNumberOfSegments();
-
- void SetScaleFactor(CORBA::Double scaleFactor)
- throw (SALOME::SALOME_Exception);
-
- CORBA::Double GetScaleFactor();
-
-protected:
- ::SMESH_NumberOfSegments* _impl;
-};
-
-#endif
+++ /dev/null
-// SMESH SMESH_I : idl implementation based on 'SMESH' unit's calsses
-//
-// Copyright (C) 2003 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
-// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
-//
-// This library 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.
-//
-// This library 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 this library; if not, write to the Free Software
-// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
-//
-// See http://www.opencascade.org/SALOME/ or email : webmaster.salome@opencascade.org
-//
-//
-//
-// File : SMESH_Quadrangle_2D_i.cxx
-// Author : Paul RASCLE, EDF
-// Module : SMESH
-// $Header$
-
-using namespace std;
-using namespace std;
-#include "SMESH_Quadrangle_2D_i.hxx"
-#include "SMESH_Gen.hxx"
-#include "SMESH_HypothesisFactory.hxx"
-
-#include "Utils_CorbaException.hxx"
-#include "utilities.h"
-
-//=============================================================================
-/*!
- *
- */
-//=============================================================================
-
-SMESH_Quadrangle_2D_i::SMESH_Quadrangle_2D_i(const char* anHyp,
- int studyId,
- ::SMESH_Gen* genImpl)
-{
- MESSAGE("SMESH_Quadrangle_2D_i::SMESH_Quadrangle_2D_i");
- _genImpl = genImpl;
- ::SMESH_Quadrangle_2D* impl
- = new ::SMESH_Quadrangle_2D(_genImpl->_hypothesisFactory.GetANewId(),
- studyId,
- genImpl);
- SetImpl(impl);
- _baseImpl = _impl;
-}
-
-//=============================================================================
-/*!
- *
- */
-//=============================================================================
-
-SMESH_Quadrangle_2D_i::~SMESH_Quadrangle_2D_i()
-{
- MESSAGE("SMESH_Quadrangle_2D_i::~SMESH_Quadrangle_2D_i");
-}
-
-//=============================================================================
-/*!
- *
- */
-//=============================================================================
-
-void SMESH_Quadrangle_2D_i::SetImpl(::SMESH_Quadrangle_2D* impl)
-{
- MESSAGE("SMESH_Quadrangle_2D_i::SetImpl");
- SMESH_2D_Algo_i::SetImpl(impl);
- _impl = impl;
-}
+++ /dev/null
-// SMESH SMESH_I : idl implementation based on 'SMESH' unit's calsses
-//
-// Copyright (C) 2003 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
-// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
-//
-// This library 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.
-//
-// This library 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 this library; if not, write to the Free Software
-// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
-//
-// See http://www.opencascade.org/SALOME/ or email : webmaster.salome@opencascade.org
-//
-//
-//
-// File : SMESH_Quadrangle_2D_i.hxx
-// Author : Paul RASCLE, EDF
-// Module : SMESH
-// $Header$
-
-#ifndef _SMESH_QUADRANGLE_2D_I_HXX_
-#define _SMESH_QUADRANGLE_2D_I_HXX_
-
-#include <SALOMEconfig.h>
-#include CORBA_SERVER_HEADER(SMESH_BasicHypothesis)
-
-#include "SMESH_2D_Algo_i.hxx"
-
-#include "SMESH_Quadrangle_2D.hxx"
-
-class SMESH_Quadrangle_2D_i:
- public POA_SMESH::SMESH_Quadrangle_2D,
- public SMESH_2D_Algo_i
-{
-public:
- SMESH_Quadrangle_2D_i(const char* anHyp,
- int studyId,
- ::SMESH_Gen* genImpl);
-
- virtual ~SMESH_Quadrangle_2D_i();
-
-protected:
- virtual void SetImpl(::SMESH_Quadrangle_2D* impl);
-
- ::SMESH_Quadrangle_2D* _impl;
-};
-
-#endif
+++ /dev/null
-// SMESH SMESH_I : idl implementation based on 'SMESH' unit's calsses
-//
-// Copyright (C) 2003 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
-// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
-//
-// This library 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.
-//
-// This library 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 this library; if not, write to the Free Software
-// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
-//
-// See http://www.opencascade.org/SALOME/ or email : webmaster.salome@opencascade.org
-//
-//
-//
-// File : SMESH_Regular_1D_i.cxx
-// Author : Paul RASCLE, EDF
-// Module : SMESH
-// $Header$
-
-using namespace std;
-using namespace std;
-#include "SMESH_Regular_1D_i.hxx"
-#include "SMESH_Gen.hxx"
-#include "SMESH_HypothesisFactory.hxx"
-
-#include "Utils_CorbaException.hxx"
-#include "utilities.h"
-
-//=============================================================================
-/*!
- *
- */
-//=============================================================================
-
-SMESH_Regular_1D_i::SMESH_Regular_1D_i(const char* anHyp,
- int studyId,
- ::SMESH_Gen* genImpl)
-{
- MESSAGE("SMESH_Regular_1D_i::SMESH_Regular_1D_i");
- _genImpl = genImpl;
- ::SMESH_Regular_1D* impl
- = new ::SMESH_Regular_1D(_genImpl->_hypothesisFactory.GetANewId(),
- studyId,
- genImpl);
- SetImpl(impl);
- _baseImpl = _impl;
-}
-
-//=============================================================================
-/*!
- *
- */
-//=============================================================================
-
-SMESH_Regular_1D_i::~SMESH_Regular_1D_i()
-{
- MESSAGE("SMESH_Regular_1D_i::~SMESH_Regular_1D_i");
-}
-
-//=============================================================================
-/*!
- *
- */
-//=============================================================================
-
-void SMESH_Regular_1D_i::SetImpl(::SMESH_Regular_1D* impl)
-{
- MESSAGE("SMESH_Regular_1D_i::SetImpl");
- SMESH_1D_Algo_i::SetImpl(impl);
- _impl = impl;
-}
+++ /dev/null
-// SMESH SMESH_I : idl implementation based on 'SMESH' unit's calsses
-//
-// Copyright (C) 2003 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
-// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
-//
-// This library 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.
-//
-// This library 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 this library; if not, write to the Free Software
-// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
-//
-// See http://www.opencascade.org/SALOME/ or email : webmaster.salome@opencascade.org
-//
-//
-//
-// File : SMESH_Regular_1D_i.hxx
-// Author : Paul RASCLE, EDF
-// Module : SMESH
-// $Header$
-
-#ifndef _SMESH_REGULAR_1D_I_HXX_
-#define _SMESH_REGULAR_1D_I_HXX_
-
-#include <SALOMEconfig.h>
-#include CORBA_SERVER_HEADER(SMESH_BasicHypothesis)
-
-#include "SMESH_1D_Algo_i.hxx"
-
-#include "SMESH_Regular_1D.hxx"
-
-class SMESH_Regular_1D_i:
- public POA_SMESH::SMESH_Regular_1D,
- public SMESH_1D_Algo_i
-{
-public:
- SMESH_Regular_1D_i(const char* anHyp,
- int studyId,
- ::SMESH_Gen* genImpl);
-
- virtual ~SMESH_Regular_1D_i();
-
-protected:
- virtual void SetImpl(::SMESH_Regular_1D* impl);
-
- ::SMESH_Regular_1D* _impl;
-};
-
-#endif
#include "Utils_CorbaException.hxx"
#include "utilities.h"
#include "OpUtil.hxx"
+#include "Utils_ExceptHandlers.hxx"
//=============================================================================
/*!
//=============================================================================
SMESH_subMesh_i::SMESH_subMesh_i()
+ : SALOME::GenericObj_i( PortableServer::POA::_nil() )
{
MESSAGE("SMESH_subMesh_i::SMESH_subMesh_i default, not for use");
ASSERT(0);
*/
//=============================================================================
-SMESH_subMesh_i::SMESH_subMesh_i(SMESH_Gen_i* gen_i,
- SMESH_Mesh_i* mesh_i,
- int localId)
+SMESH_subMesh_i::SMESH_subMesh_i( PortableServer::POA_ptr thePOA,
+ SMESH_Gen_i* gen_i,
+ SMESH_Mesh_i* mesh_i,
+ int localId )
+ : SALOME::GenericObj_i( thePOA )
{
MESSAGE("SMESH_subMesh_i::SMESH_subMesh_i");
_gen_i = gen_i;
_mesh_i = mesh_i;
_localId = localId;
+ thePOA->activate_object( this );
// ****
}
//=============================================================================
CORBA::Long SMESH_subMesh_i::GetNumberOfElements()
throw (SALOME::SALOME_Exception)
{
+ Unexpect aCatch(SALOME_SalomeException);
MESSAGE("SMESH_subMesh_i::GetNumberOfElements");
- // ****
+ if ( _mesh_i->_mapSubMesh.find( _localId ) == _mesh_i->_mapSubMesh.end() )
+ return 0;
+
+ SMESHDS_SubMesh* aSubMeshDS = _mesh_i->_mapSubMesh[_localId]->GetSubMeshDS();
+ if ( aSubMeshDS == NULL )
+ return 0;
+
+ return aSubMeshDS->NbElements();
}
//=============================================================================
CORBA::Long SMESH_subMesh_i::GetNumberOfNodes()
throw (SALOME::SALOME_Exception)
{
+ Unexpect aCatch(SALOME_SalomeException);
MESSAGE("SMESH_subMesh_i::GetNumberOfNodes");
- // ****
+ if ( _mesh_i->_mapSubMesh.find( _localId ) == _mesh_i->_mapSubMesh.end() )
+ return 0;
+
+ SMESHDS_SubMesh* aSubMeshDS = _mesh_i->_mapSubMesh[_localId]->GetSubMeshDS();
+ if ( aSubMeshDS == NULL )
+ return 0;
+
+ return aSubMeshDS->NbNodes();
}
//=============================================================================
SMESH::long_array* SMESH_subMesh_i::GetElementsId()
throw (SALOME::SALOME_Exception)
{
+ Unexpect aCatch(SALOME_SalomeException);
MESSAGE("SMESH_subMesh_i::GetElementsId");
- // ****
+ SMESH::long_array_var aResult = new SMESH::long_array();
+
+ if ( _mesh_i->_mapSubMesh.find( _localId ) == _mesh_i->_mapSubMesh.end() )
+ return aResult._retn();
+
+ SMESHDS_SubMesh* aSubMeshDS = _mesh_i->_mapSubMesh[_localId]->GetSubMeshDS();
+ if ( aSubMeshDS == NULL )
+ return aResult._retn();
+
+ aResult->length( aSubMeshDS->NbElements() );
+ SMDS_ElemIteratorPtr anIt = aSubMeshDS->GetElements();
+ for ( int i = 0, n = aSubMeshDS->NbElements(); i < n && anIt->more(); i++ )
+ aResult[i] = anIt->next()->GetID();
+
+ return aResult._retn();
+}
+
+
+//=============================================================================
+/*!
+ *
+ */
+//=============================================================================
+
+SMESH::long_array* SMESH_subMesh_i::GetElementsByType( SMESH::ElementType theElemType )
+ throw (SALOME::SALOME_Exception)
+{
+ Unexpect aCatch(SALOME_SalomeException);
+ MESSAGE("SMESH_subMesh_i::GetElementsByType");
+ SMESH::long_array_var aResult = new SMESH::long_array();
+
+ if ( _mesh_i->_mapSubMesh.find( _localId ) == _mesh_i->_mapSubMesh.end() )
+ return aResult._retn();
+
+ SMESHDS_SubMesh* aSubMeshDS = _mesh_i->_mapSubMesh[_localId]->GetSubMeshDS();
+ if ( aSubMeshDS == NULL )
+ return aResult._retn();
+
+ int i = 0;
+ if ( theElemType == SMESH::ALL )
+ aResult->length( aSubMeshDS->NbElements() + aSubMeshDS->NbNodes() );
+ else if ( theElemType == SMESH::NODE )
+ aResult->length( aSubMeshDS->NbNodes() );
+ else
+ aResult->length( aSubMeshDS->NbElements() );
+
+ int n = aResult->length();
+
+ if ( theElemType == SMESH::ALL || theElemType == SMESH::NODE ) {
+ SMDS_NodeIteratorPtr anIt = aSubMeshDS->GetNodes();
+ while ( i < n && anIt->more() )
+ aResult[i++] = anIt->next()->GetID();
+ }
+
+ if ( theElemType == SMESH::ALL || theElemType != SMESH::NODE ) {
+ SMDS_ElemIteratorPtr anIt = aSubMeshDS->GetElements();
+ while ( i < n && anIt->more() ) {
+ const SMDS_MeshElement* anElem = anIt->next();
+ if ( theElemType == SMESH::ALL || anElem->GetType() == (SMDSAbs_ElementType)theElemType )
+ aResult[i++] = anElem->GetID();
+ }
+ }
+
+ aResult->length( i );
+
+ return aResult._retn();
}
//=============================================================================
SMESH::long_array* SMESH_subMesh_i::GetNodesId()
throw (SALOME::SALOME_Exception)
{
+ Unexpect aCatch(SALOME_SalomeException);
MESSAGE("SMESH_subMesh_i::GetNodesId");
- // ****
+ SMESH::long_array_var aResult = new SMESH::long_array();
+
+ if ( _mesh_i->_mapSubMesh.find( _localId ) == _mesh_i->_mapSubMesh.end() )
+ return aResult._retn();
+
+ SMESHDS_SubMesh* aSubMeshDS = _mesh_i->_mapSubMesh[_localId]->GetSubMeshDS();
+ if ( aSubMeshDS == NULL )
+ return aResult._retn();
+
+ aResult->length( aSubMeshDS->NbNodes() );
+ SMDS_NodeIteratorPtr anIt = aSubMeshDS->GetNodes();
+ for ( int i = 0, n = aSubMeshDS->NbNodes(); i < n && anIt->more(); i++ )
+ aResult[i] = anIt->next()->GetID();
+
+ return aResult._retn();
}
//=============================================================================
SMESH::SMESH_Mesh_ptr SMESH_subMesh_i::GetFather()
throw (SALOME::SALOME_Exception)
{
+ Unexpect aCatch(SALOME_SalomeException);
MESSAGE("SMESH_subMesh_i::GetFather");
- SMESH::SMESH_Mesh_var meshIor = _mesh_i->GetIor();
- return SMESH::SMESH_Mesh::_duplicate(meshIor);
+ return _mesh_i->_this();
}
//=============================================================================
SALOME_MED::FAMILY_ptr SMESH_subMesh_i::GetFamily()
throw (SALOME::SALOME_Exception)
{
+ Unexpect aCatch(SALOME_SalomeException);
SALOME_MED::MESH_var MEDMesh = GetFather()->GetMEDMesh();
SALOME_MED::Family_array_var families =
#include CORBA_CLIENT_HEADER(GEOM_Shape)
#include CORBA_CLIENT_HEADER(MED)
+#include "SALOME_GenericObj_i.hh"
+
class SMESH_Gen_i;
class SMESH_Mesh_i;
class SMESH_subMesh_i:
- public POA_SMESH::SMESH_subMesh
+ public virtual POA_SMESH::SMESH_subMesh,
+ public virtual SALOME::GenericObj_i
{
public:
SMESH_subMesh_i();
- SMESH_subMesh_i(SMESH_Gen_i* gen_i,
- SMESH_Mesh_i* mesh_i,
- int localId);
+ SMESH_subMesh_i( PortableServer::POA_ptr thePOA,
+ SMESH_Gen_i* gen_i,
+ SMESH_Mesh_i* mesh_i,
+ int localId );
~SMESH_subMesh_i();
CORBA::Long GetNumberOfElements()
SMESH::long_array* GetElementsId()
throw (SALOME::SALOME_Exception);
+
+ SMESH::long_array* GetElementsByType( SMESH::ElementType theElemType )
+ throw (SALOME::SALOME_Exception);
SMESH::long_array* GetNodesId()
throw (SALOME::SALOME_Exception);
# Module : SMESH
import SMESH
+import StdMeshers
+
import smeshpy
import salome
from salome import sg
# ---- launch SMESH, init a Mesh with the box
gen=smeshpy.smeshpy()
-mesh=gen.Init(idb)
+mesh=gen.CreateMesh(idb)
# ---- create Hypothesis
print "-------------------------- create Hypothesis"
print "-------------------------- LocalLength"
-hyp1=gen.CreateHypothesis("LocalLength")
+hyp1=gen.CreateHypothesis("LocalLength","libStdMeshersEngine.so")
print hyp1.GetName()
print hyp1.GetId()
-hypo1 = hyp1._narrow(SMESH.SMESH_LocalLength)
+hypo1 = hyp1._narrow(StdMeshers.StdMeshers_LocalLength)
print hypo1.GetLength()
hypo1.SetLength(100)
print hypo1.GetLength()
print "-------------------------- bidon"
-hyp3=gen.CreateHypothesis("bidon")
+hyp3=gen.CreateHypothesis("bidon","")
print "-------------------------- NumberOfSegments"
-hyp3=gen.CreateHypothesis("NumberOfSegments")
-hypo3=hyp3._narrow(SMESH.SMESH_NumberOfSegments)
+hyp3=gen.CreateHypothesis("NumberOfSegments","libStdMeshersEngine.so")
+hypo3=hyp3._narrow(StdMeshers.StdMeshers_NumberOfSegments)
hypo3.SetNumberOfSegments(7)
print hypo3.GetName()
print hypo3.GetNumberOfSegments()
print hypo3.GetId()
print "-------------------------- MaxElementArea"
-hyp4=gen.CreateHypothesis("MaxElementArea")
-hypo4=hyp4._narrow(SMESH.SMESH_MaxElementArea)
+hyp4=gen.CreateHypothesis("MaxElementArea","libStdMeshersEngine.so")
+hypo4=hyp4._narrow(StdMeshers.StdMeshers_MaxElementArea)
hypo4.SetMaxElementArea(5000)
print hypo4.GetName()
print hypo4.GetMaxElementArea()
print hypo4.GetId()
print "-------------------------- Regular_1D"
-alg1=gen.CreateHypothesis("Regular_1D")
+alg1=gen.CreateHypothesis("Regular_1D","libStdMeshersEngine.so")
print alg1.GetName()
print alg1.GetId()
algo1=alg1._narrow(SMESH.SMESH_Algo)
for hyp in listHyp:
print hyp
-algo_1=alg1._narrow(SMESH.SMESH_Regular_1D)
+algo_1=alg1._narrow(StdMeshers.StdMeshers_Regular_1D)
print algo_1.GetId()
print "-------------------------- MEFISTO_2D"
-alg2=gen.CreateHypothesis("MEFISTO_2D")
+alg2=gen.CreateHypothesis("MEFISTO_2D","libStdMeshersEngine.so")
print alg2.GetName()
print alg2.GetId()
algo2=alg2._narrow(SMESH.SMESH_Algo)
listHyp=algo2.GetCompatibleHypothesis()
for hyp in listHyp:
print hyp
-algo_2=alg2._narrow(SMESH.SMESH_MEFISTO_2D)
+algo_2=alg2._narrow(StdMeshers.StdMeshers_MEFISTO_2D)
print algo_2.GetId()
# ---- add hypothesis to edge
self._smesh = salome.lcc.FindOrLoadComponent("FactoryServer","SMESH")
except:
MESSAGE( "exception in smeshpy:__init__" )
- self._studyId = salome.myStudyId
+ self._study = salome.myStudy
+ self._smesh.SetCurrentStudy(self._study)
#--------------------------------------------------------------------------
- def Init(self, shapeId):
+ def CreateMesh(self, shapeId):
try:
shape = salome.IDToObject(shapeId)
- aMesh = self._smesh.Init(self._geom, self._studyId, shape)
+ aMesh = self._smesh.CreateMesh(shape)
return aMesh
except:
MESSAGE( "exception in smeshpy:Init" )
#--------------------------------------------------------------------------
- def CreateHypothesis(self, name):
+ def CreateHypothesis(self, name, libname):
try:
- hyp = self._smesh.CreateHypothesis(name,self._studyId)
+ hyp = self._smesh.CreateHypothesis(name, libname)
return hyp
except:
MESSAGE( "exception in smeshpy:CreateHypothesis" )
SMESH_test1.py \
SMESH_test2.py \
SMESH_test3.py \
+ SMESH_test4.py \
SMESH_mechanic.py \
SMESH_mechanic_tetra.py \
SMESH_fixation.py \
SMESH_box2_tetra.py \
SMESH_box3_tetra.py \
SMESH_flight_skin.py \
- SMESH_Partition1_tetra.py \
- SMESH_box_hexa.py \
- SMESH_demo_hexa2.py \
- SMESH_demo_hexa.py \
- SMESH_demo_tetra2.py \
- SMESH_demo_tetra.py
+ SMESH_Partition1_tetra.py\
+ batchmode_mefisto.py \
+ SMESH_controls.py \
+ SMESH_freebord.py
LIB_CLIENT_IDL = SALOMEDS.idl \
SALOME_Exception.idl \
SMESH_Mesh.idl \
SMESH_Hypothesis.idl \
SMESH_BasicHypothesis.idl \
+ SMESH_Group.idl \
SALOME_ModuleCatalog.idl \
SALOME_Component.idl \
+ SALOME_GenericObj.idl \
MED.idl
EXPORT_SHAREDPYSCRIPTS=SMESH_shared_modules.py
CPPFLAGS+=$(QT_INCLUDES) $(PYTHON_INCLUDES) $(OCC_INCLUDES) $(VTK_INCLUDES) $(OGL_INCLUDES) -DHAVE_CONFIG_H
LIBS+= $(PYTHON_LIBS)
-LDFLAGS+= -lSMESHGUI
+LDFLAGS+= -lSMESHGUI -L${KERNEL_ROOT_DIR}/lib/salome -lSalomeGenericObj
@CONCLUDE@
-#\r
-# Tetrahedrization of the geometry generated by the Python script GEOM_Partition1.py\r
-# Hypothesis and algorithms for the mesh generation are global\r
-#\r
-#%Make geometry (like CEA script (A1)) using Partition algorithm% from OCC\r
-# -- Rayon de la bariere\r
-\r
-barier_height = 7.0\r
-barier_radius = 5.6 / 2 # Rayon de la bariere\r
-colis_radius = 1.0 / 2 # Rayon du colis\r
-colis_step = 2.0 # Distance s\89parant deux colis\r
-cc_width = 0.11 # Epaisseur du complement de colisage\r
-\r
-# --\r
-\r
-cc_radius = colis_radius + cc_width\r
-from math import sqrt\r
-colis_center = sqrt(2.0)*colis_step/2\r
-\r
-# --\r
-\r
-import geompy\r
-geom = geompy.geom\r
-\r
-boolean_common = 1\r
-boolean_cut = 2\r
-boolean_fuse = 3\r
-boolean_section = 4\r
-\r
-# --\r
-\r
-barier = geompy.MakeCylinder(\r
- geom.MakePointStruct(0.,0.,0.),\r
- geom.MakeDirection(geom.MakePointStruct(0.,0.,1.)),\r
- barier_radius,\r
- barier_height)\r
-\r
-# --\r
-\r
-colis = geompy.MakeCylinder(\r
- geom.MakePointStruct(0.,0.,0.),\r
- geom.MakeDirection(geom.MakePointStruct(0.,0.,1.)),\r
- colis_radius,\r
- barier_height)\r
-\r
-cc = geompy.MakeCylinder(\r
- geom.MakePointStruct(0.,0.,0.),\r
- geom.MakeDirection(geom.MakePointStruct(0.,0.,1.)),\r
- cc_radius,\r
- barier_height)\r
-\r
-colis_cc = geompy.MakeCompound(\r
- [colis._get_Name(), cc._get_Name()])\r
-\r
-colis_cc = geompy.MakeTranslation(\r
- colis_cc, colis_center, 0.0, 0.0)\r
-\r
-colis_cc_multi = geompy.MakeMultiRotation1D(\r
- colis_cc,\r
- geom.MakeDirection(geom.MakePointStruct(0.,0.,1.)),\r
- geom.MakePointStruct(0.,0.,0.),\r
- 4)\r
-\r
-# --\r
-\r
-alveole = geompy.Partition(\r
- [colis_cc_multi._get_Name(), barier._get_Name()])\r
-\r
-ShapeTypeShell = 3\r
-ShapeTypeFace = 4\r
-ShapeTypeEdge = 6\r
-\r
-print "Analysis of the geometry to mesh (right after the Partition) :"\r
-\r
-subShellList=geompy.SubShapeAll(alveole,ShapeTypeShell)\r
-subFaceList=geompy.SubShapeAll(alveole,ShapeTypeFace)\r
-subEdgeList=geompy.SubShapeAll(alveole,ShapeTypeEdge)\r
-\r
-print "number of Shells in alveole : ",len(subShellList)\r
-print "number of Faces in alveole : ",len(subFaceList)\r
-print "number of Edges in alveole : ",len(subEdgeList)\r
-\r
-subshapes = geompy.SubShapeAll( alveole, geompy.ShapeType["SHAPE"] )\r
-\r
-## there are 9 subshapes\r
-\r
-comp1 = geompy.MakeCompound( [ subshapes[0]._get_Name(), subshapes[1]._get_Name() ] );\r
-comp2 = geompy.MakeCompound( [ subshapes[2]._get_Name(), subshapes[3]._get_Name() ] );\r
-comp3 = geompy.MakeCompound( [ subshapes[4]._get_Name(), subshapes[5]._get_Name() ] );\r
-comp4 = geompy.MakeCompound( [ subshapes[6]._get_Name(), subshapes[7]._get_Name() ] );\r
-\r
-compIORs = []\r
-compIORs.append( comp1._get_Name() );\r
-compIORs.append( comp2._get_Name() );\r
-compIORs.append( comp3._get_Name() );\r
-compIORs.append( comp4._get_Name() );\r
-comp = geompy.MakeCompound( compIORs );\r
-\r
-alveole = geompy.MakeCompound( [ comp._get_Name(), subshapes[8]._get_Name() ]);\r
- \r
-idalveole= geompy.addToStudy(alveole, "alveole")\r
-\r
-print "Analysis of the geometry to mesh (right after the MakeCompound) :"\r
-\r
-subShellList=geompy.SubShapeAll(alveole,ShapeTypeShell)\r
-subFaceList=geompy.SubShapeAll(alveole,ShapeTypeFace)\r
-subEdgeList=geompy.SubShapeAll(alveole,ShapeTypeEdge)\r
-\r
-print "number of Shells in alveole : ",len(subShellList)\r
-print "number of Faces in alveole : ",len(subFaceList)\r
-print "number of Edges in alveole : ",len(subEdgeList)\r
-\r
-status=geompy.CheckShape(alveole)\r
-print " check status ", status\r
-\r
-# ---- launch SMESH\r
-\r
-import salome\r
-from salome import sg\r
-\r
-import SMESH\r
-import smeshpy\r
-\r
-smeshgui = salome.ImportComponentGUI("SMESH")\r
-smeshgui.Init(salome.myStudyId)\r
-\r
-gen=smeshpy.smeshpy()\r
-\r
-# ---- create Hypothesis\r
-\r
-print "-------------------------- create Hypothesis (In this case global hypothesis are used)"\r
-\r
-print "-------------------------- NumberOfSegments"\r
-\r
-numberOfSegments = 10\r
-\r
-hyp1=gen.CreateHypothesis("NumberOfSegments")\r
-hypNbSeg=hyp1._narrow(SMESH.SMESH_NumberOfSegments)\r
-hypNbSeg.SetNumberOfSegments(numberOfSegments)\r
-hypNbSegID = hypNbSeg.GetId()\r
-print hypNbSeg.GetName()\r
-print hypNbSegID\r
-print hypNbSeg.GetNumberOfSegments()\r
-\r
-idseg = smeshgui.AddNewHypothesis( salome.orb.object_to_string(hypNbSeg) )\r
-smeshgui.SetName(idseg, "NumberOfSegments")\r
-\r
-print "-------------------------- MaxElementArea"\r
-\r
-maxElementArea = 0.1\r
-\r
-hyp2=gen.CreateHypothesis("MaxElementArea")\r
-hypArea=hyp2._narrow(SMESH.SMESH_MaxElementArea)\r
-hypArea.SetMaxElementArea(maxElementArea)\r
-print hypArea.GetName()\r
-print hypArea.GetId()\r
-print hypArea.GetMaxElementArea()\r
-\r
-idarea = smeshgui.AddNewHypothesis( salome.orb.object_to_string(hypArea) )\r
-smeshgui.SetName(idarea, "MaxElementArea")\r
-\r
-print "-------------------------- MaxElementVolume"\r
-\r
-maxElementVolume = 0.5\r
-\r
-hyp3=gen.CreateHypothesis("MaxElementVolume")\r
-hypVolume=hyp3._narrow(SMESH.SMESH_MaxElementVolume)\r
-hypVolume.SetMaxElementVolume(maxElementVolume)\r
-print hypVolume.GetName()\r
-print hypVolume.GetId()\r
-print hypVolume.GetMaxElementVolume()\r
-\r
-idvolume = smeshgui.AddNewHypothesis( salome.orb.object_to_string(hypVolume) )\r
-smeshgui.SetName(idvolume, "MaxElementVolume")\r
-\r
-# ---- create Algorithms\r
-\r
-print "-------------------------- create Algorithms"\r
-\r
-print "-------------------------- Regular_1D"\r
-\r
-hypothesis=gen.CreateHypothesis("Regular_1D")\r
-regular1D = hypothesis._narrow(SMESH.SMESH_Regular_1D)\r
-regularID = smeshgui.AddNewAlgorithms( salome.orb.object_to_string(regular1D) )\r
-smeshgui.SetName(regularID, "Wire Discretisation")\r
-\r
-print "-------------------------- MEFISTO_2D"\r
-\r
-hypothesis=gen.CreateHypothesis("MEFISTO_2D")\r
-mefisto2D = hypothesis._narrow(SMESH.SMESH_MEFISTO_2D)\r
-mefistoID = smeshgui.AddNewAlgorithms( salome.orb.object_to_string(mefisto2D) )\r
-smeshgui.SetName(mefistoID, "MEFISTO_2D")\r
-\r
-print "-------------------------- NETGEN_3D"\r
-\r
-hypothesis=gen.CreateHypothesis("NETGEN_3D")\r
-netgen3D = hypothesis._narrow(SMESH.SMESH_NETGEN_3D)\r
-netgenID = smeshgui.AddNewAlgorithms( salome.orb.object_to_string(netgen3D) )\r
-smeshgui.SetName(netgenID, "NETGEN_3D")\r
-\r
-# ---- init a Mesh with the alveole\r
-\r
-mesh=gen.Init(idalveole)\r
-idmesh = smeshgui.AddNewMesh( salome.orb.object_to_string(mesh) )\r
-smeshgui.SetName(idmesh, "MeshAlveole")\r
-smeshgui.SetShape(idalveole, idmesh)\r
-\r
-# ---- add hypothesis to alveole\r
-\r
-print "-------------------------- add hypothesis to alveole"\r
-\r
-ret=mesh.AddHypothesis(alveole,regular1D)\r
-print ret\r
-ret=mesh.AddHypothesis(alveole,hypNbSeg)\r
-print ret\r
-ret=mesh.AddHypothesis(alveole,mefisto2D)\r
-print ret\r
-ret=mesh.AddHypothesis(alveole,hypArea)\r
-print ret\r
-ret=mesh.AddHypothesis(alveole,netgen3D)\r
-print ret\r
-ret=mesh.AddHypothesis(alveole,hypVolume)\r
-print ret\r
-\r
-smeshgui.SetAlgorithms( idmesh, regularID)\r
-smeshgui.SetHypothesis( idmesh, idseg )\r
-smeshgui.SetAlgorithms( idmesh, mefistoID )\r
-smeshgui.SetHypothesis( idmesh, idarea )\r
-smeshgui.SetAlgorithms( idmesh, netgenID )\r
-smeshgui.SetHypothesis( idmesh, idvolume )\r
-\r
-sg.updateObjBrowser(1)\r
-\r
-\r
-print "-------------------------- compute the mesh of alveole "\r
-ret=gen.Compute(mesh,idalveole)\r
-print ret\r
-if ret != 0:\r
- log=mesh.GetLog(0) # no erase trace\r
- for linelog in log:\r
- print linelog\r
-else:\r
- print "problem when computing the mesh"\r
-\r
-sg.updateObjBrowser(1)\r
+#
+# Tetrahedrization of the geometry generated by the Python script GEOM_Partition1.py
+# Hypothesis and algorithms for the mesh generation are global
+#
+#%Make geometry (like CEA script (A1)) using Partition algorithm% from OCC
+# -- Rayon de la bariere
+
+import salome
+import geompy
+
+import StdMeshers
+import NETGENPlugin
+
+geom = salome.lcc.FindOrLoadComponent("FactoryServer", "GEOM")
+smesh = salome.lcc.FindOrLoadComponent("FactoryServer", "SMESH")
+
+geom.GetCurrentStudy(salome.myStudy._get_StudyId())
+smesh.SetCurrentStudy(salome.myStudy)
+
+smeshgui = salome.ImportComponentGUI("SMESH")
+smeshgui.Init(salome.myStudyId);
+
+#---------------------------------------------------------------
+
+barier_height = 7.0
+barier_radius = 5.6 / 2 # Rayon de la bariere
+colis_radius = 1.0 / 2 # Rayon du colis
+colis_step = 2.0 # Distance s\89parant deux colis
+cc_width = 0.11 # Epaisseur du complement de colisage
+
+# --
+
+cc_radius = colis_radius + cc_width
+from math import sqrt
+colis_center = sqrt(2.0)*colis_step/2
+
+# --
+
+boolean_common = 1
+boolean_cut = 2
+boolean_fuse = 3
+boolean_section = 4
+
+# --
+
+barier = geompy.MakeCylinder(
+ geom.MakePointStruct(0.,0.,0.),
+ geom.MakeDirection(geom.MakePointStruct(0.,0.,1.)),
+ barier_radius,
+ barier_height)
+
+# --
+
+colis = geompy.MakeCylinder(
+ geom.MakePointStruct(0.,0.,0.),
+ geom.MakeDirection(geom.MakePointStruct(0.,0.,1.)),
+ colis_radius,
+ barier_height)
+
+cc = geompy.MakeCylinder(
+ geom.MakePointStruct(0.,0.,0.),
+ geom.MakeDirection(geom.MakePointStruct(0.,0.,1.)),
+ cc_radius,
+ barier_height)
+
+colis_cc = geompy.MakeCompound(
+ [colis._get_Name(), cc._get_Name()])
+
+colis_cc = geompy.MakeTranslation(
+ colis_cc, colis_center, 0.0, 0.0)
+
+colis_cc_multi = geompy.MakeMultiRotation1D(
+ colis_cc,
+ geom.MakeDirection(geom.MakePointStruct(0.,0.,1.)),
+ geom.MakePointStruct(0.,0.,0.),
+ 4)
+
+# --
+
+alveole = geompy.Partition(
+ [colis_cc_multi._get_Name(), barier._get_Name()])
+
+ShapeTypeShell = 3
+ShapeTypeFace = 4
+ShapeTypeEdge = 6
+
+print "Analysis of the geometry to mesh (right after the Partition) :"
+
+subShellList=geompy.SubShapeAll(alveole,ShapeTypeShell)
+subFaceList=geompy.SubShapeAll(alveole,ShapeTypeFace)
+subEdgeList=geompy.SubShapeAll(alveole,ShapeTypeEdge)
+
+print "number of Shells in alveole : ",len(subShellList)
+print "number of Faces in alveole : ",len(subFaceList)
+print "number of Edges in alveole : ",len(subEdgeList)
+
+subshapes = geompy.SubShapeAll( alveole, geompy.ShapeType["SHAPE"] )
+
+## there are 9 subshapes
+
+comp1 = geompy.MakeCompound( [ subshapes[0]._get_Name(), subshapes[1]._get_Name() ] );
+comp2 = geompy.MakeCompound( [ subshapes[2]._get_Name(), subshapes[3]._get_Name() ] );
+comp3 = geompy.MakeCompound( [ subshapes[4]._get_Name(), subshapes[5]._get_Name() ] );
+comp4 = geompy.MakeCompound( [ subshapes[6]._get_Name(), subshapes[7]._get_Name() ] );
+
+compIORs = []
+compIORs.append( comp1._get_Name() );
+compIORs.append( comp2._get_Name() );
+compIORs.append( comp3._get_Name() );
+compIORs.append( comp4._get_Name() );
+comp = geompy.MakeCompound( compIORs );
+
+alveole = geompy.MakeCompound( [ comp._get_Name(), subshapes[8]._get_Name() ]);
+
+idalveole= geompy.addToStudy(alveole, "alveole")
+
+print "Analysis of the geometry to mesh (right after the MakeCompound) :"
+
+subShellList=geompy.SubShapeAll(alveole,ShapeTypeShell)
+subFaceList=geompy.SubShapeAll(alveole,ShapeTypeFace)
+subEdgeList=geompy.SubShapeAll(alveole,ShapeTypeEdge)
+
+print "number of Shells in alveole : ",len(subShellList)
+print "number of Faces in alveole : ",len(subFaceList)
+print "number of Edges in alveole : ",len(subEdgeList)
+
+status=geompy.CheckShape(alveole)
+print " check status ", status
+
+# ---- launch SMESH
+
+# ---- create Hypothesis
+
+print "-------------------------- create Hypothesis (In this case global hypothesis are used)"
+
+print "-------------------------- NumberOfSegments"
+
+numberOfSegments = 10
+
+hypNbSeg=smesh.CreateHypothesis("NumberOfSegments", "libStdMeshersEngine.so")
+hypNbSeg.SetNumberOfSegments(numberOfSegments)
+print hypNbSeg.GetName()
+print hypNbSeg.GetId()
+print hypNbSeg.GetNumberOfSegments()
+
+smeshgui.SetName(salome.ObjectToID(hypNbSeg), "NumberOfSegments_10")
+
+print "-------------------------- MaxElementArea"
+
+maxElementArea = 0.1
+
+hypArea=smesh.CreateHypothesis("MaxElementArea", "libStdMeshersEngine.so")
+hypArea.SetMaxElementArea(maxElementArea)
+print hypArea.GetName()
+print hypArea.GetId()
+print hypArea.GetMaxElementArea()
+
+smeshgui.SetName(salome.ObjectToID(hypArea), "MaxElementArea_0.1")
+
+print "-------------------------- MaxElementVolume"
+
+maxElementVolume = 0.5
+
+hypVolume=smesh.CreateHypothesis("MaxElementVolume", "libStdMeshersEngine.so")
+hypVolume.SetMaxElementVolume(maxElementVolume)
+print hypVolume.GetName()
+print hypVolume.GetId()
+print hypVolume.GetMaxElementVolume()
+
+smeshgui.SetName(salome.ObjectToID(hypVolume), "MaxElementVolume_0.5")
+
+# ---- create Algorithms
+
+print "-------------------------- create Algorithms"
+
+print "-------------------------- Regular_1D"
+
+regular1D = smesh.CreateHypothesis("Regular_1D", "libStdMeshersEngine.so")
+smeshgui.SetName(salome.ObjectToID(regular1D), "Wire Discretisation")
+
+print "-------------------------- MEFISTO_2D"
+
+mefisto2D=smesh.CreateHypothesis("MEFISTO_2D", "libStdMeshersEngine.so")
+smeshgui.SetName(salome.ObjectToID(mefisto2D), "MEFISTO_2D")
+
+print "-------------------------- NETGEN_3D"
+
+netgen3D=smesh.CreateHypothesis("NETGEN_3D", "libNETGENEngine.so")
+smeshgui.SetName(salome.ObjectToID(netgen3D), "NETGEN_3D")
+
+# ---- init a Mesh with the alveole
+shape_mesh = salome.IDToObject( idalveole )
+
+mesh=smesh.CreateMesh(shape_mesh)
+smeshgui.SetName(salome.ObjectToID(mesh), "MeshAlveole")
+
+# ---- add hypothesis to alveole
+
+print "-------------------------- add hypothesis to alveole"
+
+mesh.AddHypothesis(shape_mesh,regular1D)
+mesh.AddHypothesis(shape_mesh,hypNbSeg)
+
+mesh.AddHypothesis(shape_mesh,mefisto2D)
+mesh.AddHypothesis(shape_mesh,hypArea)
+
+mesh.AddHypothesis(shape_mesh,netgen3D)
+mesh.AddHypothesis(shape_mesh,hypVolume)
+
+print "-------------------------- compute the mesh of alveole "
+ret=smesh.Compute(mesh,shape_mesh)
+
+if ret != 0:
+ log=mesh.GetLog(0) # no erase trace
+ for linelog in log:
+ print linelog
+ print "Information about the Mesh_mechanic:"
+ print "Number of nodes : ", mesh.NbNodes()
+ print "Number of edges : ", mesh.NbEdges()
+ print "Number of faces : ", mesh.NbFaces()
+ print "Number of triangles : ", mesh.NbTriangles()
+ print "Number of volumes: ", mesh.NbVolumes()
+ print "Number of tetrahedrons: ", mesh.NbTetras()
+else:
+ print "problem when computing the mesh"
+
+salome.sg.updateObjBrowser(1)
#
import salome
-from salome import sg
-
import geompy
-import SMESH
-import smeshpy
+import StdMeshers
+import NETGENPlugin
+
+geom = salome.lcc.FindOrLoadComponent("FactoryServer", "GEOM")
+smesh = salome.lcc.FindOrLoadComponent("FactoryServer", "SMESH")
-geom = geompy.geom
-myBuilder = geompy.myBuilder
+smeshgui = salome.ImportComponentGUI("SMESH")
+smeshgui.Init(salome.myStudyId);
ShapeTypeShell = 3
ShapeTypeFace = 4
print "number of Faces in shell : ",len(subFaceList)
print "number of Edges in shell : ",len(subEdgeList)
-# ---- launch SMESH
-
-smeshgui = salome.ImportComponentGUI("SMESH")
-smeshgui.Init(salome.myStudyId)
-gen=smeshpy.smeshpy()
+### ---------------------------- SMESH --------------------------------------
# ---- create Hypothesis
numberOfSegments = 10
-hyp1=gen.CreateHypothesis("NumberOfSegments")
-hypNbSeg=hyp1._narrow(SMESH.SMESH_NumberOfSegments)
+hypNbSeg=smesh.CreateHypothesis("NumberOfSegments", "libStdMeshersEngine.so")
hypNbSeg.SetNumberOfSegments(numberOfSegments)
-hypNbSegID = hypNbSeg.GetId()
+
print hypNbSeg.GetName()
-print hypNbSegID
+print hypNbSeg.GetId()
print hypNbSeg.GetNumberOfSegments()
-idseg = smeshgui.AddNewHypothesis( salome.orb.object_to_string(hypNbSeg) )
-smeshgui.SetName(idseg, "NumberOfSegments")
+smeshgui.SetName(salome.ObjectToID(hypNbSeg), "NumberOfSegments_10")
print "-------------------------- MaxElementArea"
maxElementArea = 500
-hyp2=gen.CreateHypothesis("MaxElementArea")
-hypArea=hyp2._narrow(SMESH.SMESH_MaxElementArea)
+hypArea=smesh.CreateHypothesis("MaxElementArea", "libStdMeshersEngine.so")
hypArea.SetMaxElementArea(maxElementArea)
+
print hypArea.GetName()
print hypArea.GetId()
print hypArea.GetMaxElementArea()
-idarea = smeshgui.AddNewHypothesis( salome.orb.object_to_string(hypArea) )
-smeshgui.SetName(idarea, "MaxElementArea")
+smeshgui.SetName(salome.ObjectToID(hypArea), "MaxElementArea_500")
print "-------------------------- MaxElementVolume"
maxElementVolume = 500
-hyp3=gen.CreateHypothesis("MaxElementVolume")
-hypVolume=hyp3._narrow(SMESH.SMESH_MaxElementVolume)
+hypVolume=smesh.CreateHypothesis("MaxElementVolume", "libStdMeshersEngine.so")
hypVolume.SetMaxElementVolume(maxElementVolume)
+
print hypVolume.GetName()
print hypVolume.GetId()
print hypVolume.GetMaxElementVolume()
-idvolume = smeshgui.AddNewHypothesis( salome.orb.object_to_string(hypVolume) )
-smeshgui.SetName(idvolume, "MaxElementVolume")
+smeshgui.SetName(salome.ObjectToID(hypVolume), "MaxElementVolume_500")
# ---- create Algorithms
print "-------------------------- Regular_1D"
-hypothesis=gen.CreateHypothesis("Regular_1D")
-regular1D = hypothesis._narrow(SMESH.SMESH_Regular_1D)
-regularID = smeshgui.AddNewAlgorithms( salome.orb.object_to_string(regular1D) )
-smeshgui.SetName(regularID, "Wire Discretisation")
+regular1D=smesh.CreateHypothesis("Regular_1D", "libStdMeshersEngine.so")
+smeshgui.SetName(salome.ObjectToID(regular1D), "Wire Discretisation")
print "-------------------------- MEFISTO_2D"
-hypothesis=gen.CreateHypothesis("MEFISTO_2D")
-mefisto2D = hypothesis._narrow(SMESH.SMESH_MEFISTO_2D)
-mefistoID = smeshgui.AddNewAlgorithms( salome.orb.object_to_string(mefisto2D) )
-smeshgui.SetName(mefistoID, "MEFISTO_2D")
+mefisto2D=smesh.CreateHypothesis("MEFISTO_2D", "libStdMeshersEngine.so")
+smeshgui.SetName(salome.ObjectToID(mefisto2D), "MEFISTO_2D")
print "-------------------------- NETGEN_3D"
-hypothesis=gen.CreateHypothesis("NETGEN_3D")
-netgen3D = hypothesis._narrow(SMESH.SMESH_NETGEN_3D)
-netgenID = smeshgui.AddNewAlgorithms( salome.orb.object_to_string(netgen3D) )
-smeshgui.SetName(netgenID, "NETGEN_3D")
+netgen3D=smesh.CreateHypothesis("NETGEN_3D", "libNETGENEngine.so")
+smeshgui.SetName(salome.ObjectToID(netgen3D), "NETGEN_3D")
# ---- init a Mesh with the shell
-mesh=gen.Init(idshell)
-idmesh = smeshgui.AddNewMesh( salome.orb.object_to_string(mesh) )
-smeshgui.SetName(idmesh, "MeshBox2")
-smeshgui.SetShape(idshell, idmesh)
+mesh = smesh.CreateMesh(shell)
+smeshgui.SetName(salome.ObjectToID(mesh), "MeshBox2")
# ---- add hypothesis to shell
print "-------------------------- add hypothesis to shell"
-ret=mesh.AddHypothesis(shell,regular1D)
-print ret
-ret=mesh.AddHypothesis(shell,hypNbSeg)
-print ret
-ret=mesh.AddHypothesis(shell,mefisto2D)
-print ret
-ret=mesh.AddHypothesis(shell,hypArea)
-print ret
-ret=mesh.AddHypothesis(shell,netgen3D)
-print ret
-ret=mesh.AddHypothesis(shell,hypVolume)
-print ret
+mesh.AddHypothesis(shell,regular1D)
+mesh.AddHypothesis(shell,hypNbSeg)
-smeshgui.SetAlgorithms( idmesh, regularID)
-smeshgui.SetHypothesis( idmesh, idseg )
-smeshgui.SetAlgorithms( idmesh, mefistoID )
-smeshgui.SetHypothesis( idmesh, idarea )
-smeshgui.SetAlgorithms( idmesh, netgenID )
-smeshgui.SetHypothesis( idmesh, idvolume )
+mesh.AddHypothesis(shell,mefisto2D)
+mesh.AddHypothesis(shell,hypArea)
-sg.updateObjBrowser(1)
+mesh.AddHypothesis(shell,netgen3D)
+mesh.AddHypothesis(shell,hypVolume)
+salome.sg.updateObjBrowser(1)
print "-------------------------- compute shell"
-ret=gen.Compute(mesh,idshell)
+ret= smesh.Compute(mesh,shell)
print ret
-log=mesh.GetLog(0) # no erase trace
-for linelog in log:
- print linelog
-
-
-sg.updateObjBrowser(1)
+if ret != 0:
+ log=mesh.GetLog(0) # no erase trace
+ for linelog in log:
+ print linelog
+ print "Information about the MeshBox2:"
+ print "Number of nodes : ", mesh.NbNodes()
+ print "Number of edges : ", mesh.NbEdges()
+ print "Number of faces : ", mesh.NbFaces()
+ print "Number of triangles : ", mesh.NbTriangles()
+ print "Number of volumes : ", mesh.NbVolumes()
+ print "Number of tetrahedrons: ", mesh.NbTetras()
+else:
+ print "probleme when computing the mesh"
#
import salome
-from salome import sg
-
import geompy
-import SMESH
-import smeshpy
+import StdMeshers
+import NETGENPlugin
+
+geom = salome.lcc.FindOrLoadComponent("FactoryServer", "GEOM")
+smesh = salome.lcc.FindOrLoadComponent("FactoryServer", "SMESH")
-geom = geompy.geom
-myBuilder = geompy.myBuilder
+smeshgui = salome.ImportComponentGUI("SMESH")
+smeshgui.Init(salome.myStudyId);
ShapeTypeShell = 3
ShapeTypeFace = 4
print "number of Faces in shell : ",len(subFaceList)
print "number of Edges in shell : ",len(subEdgeList)
-# ---- launch SMESH
-
-smeshgui = salome.ImportComponentGUI("SMESH")
-smeshgui.Init(salome.myStudyId)
-gen=smeshpy.smeshpy()
+### ---------------------------- SMESH --------------------------------------
# ---- create Hypothesis
numberOfSegments = 10
-hyp1=gen.CreateHypothesis("NumberOfSegments")
-hypNbSeg=hyp1._narrow(SMESH.SMESH_NumberOfSegments)
+hypNbSeg=smesh.CreateHypothesis("NumberOfSegments", "libStdMeshersEngine.so")
hypNbSeg.SetNumberOfSegments(numberOfSegments)
-hypNbSegID = hypNbSeg.GetId()
+
print hypNbSeg.GetName()
-print hypNbSegID
+print hypNbSeg.GetId()
print hypNbSeg.GetNumberOfSegments()
-idseg = smeshgui.AddNewHypothesis( salome.orb.object_to_string(hypNbSeg) )
-smeshgui.SetName(idseg, "NumberOfSegments")
+smeshgui.SetName(salome.ObjectToID(hypNbSeg), "NumberOfSegments_10")
print "-------------------------- MaxElementArea"
maxElementArea = 500
-hyp2=gen.CreateHypothesis("MaxElementArea")
-hypArea=hyp2._narrow(SMESH.SMESH_MaxElementArea)
+hypArea=smesh.CreateHypothesis("MaxElementArea", "libStdMeshersEngine.so")
hypArea.SetMaxElementArea(maxElementArea)
+
print hypArea.GetName()
print hypArea.GetId()
print hypArea.GetMaxElementArea()
-idarea = smeshgui.AddNewHypothesis( salome.orb.object_to_string(hypArea) )
-smeshgui.SetName(idarea, "MaxElementArea")
+smeshgui.SetName(salome.ObjectToID(hypArea), "MaxElementArea_500")
print "-------------------------- MaxElementVolume"
maxElementVolume = 500
-hyp3=gen.CreateHypothesis("MaxElementVolume")
-hypVolume=hyp3._narrow(SMESH.SMESH_MaxElementVolume)
+hypVolume=smesh.CreateHypothesis("MaxElementVolume", "libStdMeshersEngine.so")
hypVolume.SetMaxElementVolume(maxElementVolume)
+
print hypVolume.GetName()
print hypVolume.GetId()
print hypVolume.GetMaxElementVolume()
-idvolume = smeshgui.AddNewHypothesis( salome.orb.object_to_string(hypVolume) )
-smeshgui.SetName(idvolume, "MaxElementVolume")
+smeshgui.SetName(salome.ObjectToID(hypVolume), "MaxElementVolume_500")
# ---- create Algorithms
print "-------------------------- Regular_1D"
-hypothesis=gen.CreateHypothesis("Regular_1D")
-regular1D = hypothesis._narrow(SMESH.SMESH_Regular_1D)
-regularID = smeshgui.AddNewAlgorithms( salome.orb.object_to_string(regular1D) )
-smeshgui.SetName(regularID, "Wire Discretisation")
+regular1D=smesh.CreateHypothesis("Regular_1D", "libStdMeshersEngine.so")
+smeshgui.SetName(salome.ObjectToID(regular1D), "Wire Discretisation")
print "-------------------------- MEFISTO_2D"
-hypothesis=gen.CreateHypothesis("MEFISTO_2D")
-mefisto2D = hypothesis._narrow(SMESH.SMESH_MEFISTO_2D)
-mefistoID = smeshgui.AddNewAlgorithms( salome.orb.object_to_string(mefisto2D) )
-smeshgui.SetName(mefistoID, "MEFISTO_2D")
+mefisto2D=smesh.CreateHypothesis("MEFISTO_2D", "libStdMeshersEngine.so")
+smeshgui.SetName(salome.ObjectToID(mefisto2D), "MEFISTO_2D")
print "-------------------------- NETGEN_3D"
-hypothesis=gen.CreateHypothesis("NETGEN_3D")
-netgen3D = hypothesis._narrow(SMESH.SMESH_NETGEN_3D)
-netgenID = smeshgui.AddNewAlgorithms( salome.orb.object_to_string(netgen3D) )
-smeshgui.SetName(netgenID, "NETGEN_3D")
+netgen3D=smesh.CreateHypothesis("NETGEN_3D", "libNETGENEngine.so")
+smeshgui.SetName(salome.ObjectToID(netgen3D), "NETGEN_3D")
# ---- init a Mesh with the shell
-mesh=gen.Init(idshell)
-idmesh = smeshgui.AddNewMesh( salome.orb.object_to_string(mesh) )
-smeshgui.SetName(idmesh, "MeshBox2")
-smeshgui.SetShape(idshell, idmesh)
+mesh = smesh.CreateMesh(shell)
+smeshgui.SetName(salome.ObjectToID(mesh), "MeshBox3")
# ---- add hypothesis to shell
print "-------------------------- add hypothesis to shell"
-ret=mesh.AddHypothesis(shell,regular1D)
-print ret
-ret=mesh.AddHypothesis(shell,hypNbSeg)
-print ret
-ret=mesh.AddHypothesis(shell,mefisto2D)
-print ret
-ret=mesh.AddHypothesis(shell,hypArea)
-print ret
-ret=mesh.AddHypothesis(shell,netgen3D)
-print ret
-ret=mesh.AddHypothesis(shell,hypVolume)
-print ret
+mesh.AddHypothesis(shell,regular1D)
+mesh.AddHypothesis(shell,hypNbSeg)
-smeshgui.SetAlgorithms( idmesh, regularID)
-smeshgui.SetHypothesis( idmesh, idseg )
-smeshgui.SetAlgorithms( idmesh, mefistoID )
-smeshgui.SetHypothesis( idmesh, idarea )
-smeshgui.SetAlgorithms( idmesh, netgenID )
-smeshgui.SetHypothesis( idmesh, idvolume )
+mesh.AddHypothesis(shell,mefisto2D)
+mesh.AddHypothesis(shell,hypArea)
-sg.updateObjBrowser(1)
+mesh.AddHypothesis(shell,netgen3D)
+mesh.AddHypothesis(shell,hypVolume)
+salome.sg.updateObjBrowser(1)
print "-------------------------- compute shell"
-ret=gen.Compute(mesh,idshell)
+ret= smesh.Compute(mesh,shell)
print ret
-log=mesh.GetLog(0) # no erase trace
-for linelog in log:
- print linelog
-
-
-sg.updateObjBrowser(1)
+if ret != 0:
+ log=mesh.GetLog(0) # no erase trace
+ for linelog in log:
+ print linelog
+ print "Information about the MeshBox3:"
+ print "Number of nodes : ", mesh.NbNodes()
+ print "Number of edges : ", mesh.NbEdges()
+ print "Number of faces : ", mesh.NbFaces()
+ print "Number of triangles : ", mesh.NbTriangles()
+ print "Number of volumes : ", mesh.NbVolumes()
+ print "Number of tetrahedrons: ", mesh.NbTetras()
+else:
+ print "probleme when computing the mesh"
#
import salome
-from salome import sg
-
import geompy
-import SMESH
-import smeshpy
-
-# -----------------------------------------------------------------------------
+import StdMeshers
+import NETGENPlugin
-##geom = salome.lcc.FindOrLoadComponent("FactoryServer", "Geometry")
-##myBuilder = salome.myStudy.NewBuilder()
+geom = salome.lcc.FindOrLoadComponent("FactoryServer", "GEOM")
+smesh = salome.lcc.FindOrLoadComponent("FactoryServer", "SMESH")
-geom = geompy.geom
-myBuilder = geompy.myBuilder
+smeshgui = salome.ImportComponentGUI("SMESH")
+smeshgui.Init(salome.myStudyId);
+# -----------------------------------------------------------------------------
ShapeTypeShell = 3
ShapeTypeFace = 4
ShapeTypeEdge = 6
print "number of Faces in box : ",len(subFaceList)
print "number of Edges in box : ",len(subEdgeList)
-# ---- launch SMESH
-smeshgui = salome.ImportComponentGUI("SMESH")
-smeshgui.Init(salome.myStudyId)
-
-gen=smeshpy.smeshpy()
+### ---------------------------- SMESH --------------------------------------
# ---- create Hypothesis
numberOfSegments = 10
-hyp1=gen.CreateHypothesis("NumberOfSegments")
-hypNbSeg=hyp1._narrow(SMESH.SMESH_NumberOfSegments)
+hypNbSeg=smesh.CreateHypothesis("NumberOfSegments", "libStdMeshersEngine.so")
hypNbSeg.SetNumberOfSegments(numberOfSegments)
-hypNbSegID = hypNbSeg.GetId()
+
print hypNbSeg.GetName()
-print hypNbSegID
+print hypNbSeg.GetId()
print hypNbSeg.GetNumberOfSegments()
-idseg = smeshgui.AddNewHypothesis( salome.orb.object_to_string(hypNbSeg) )
-smeshgui.SetName(idseg, "NumberOfSegments")
+smeshgui.SetName(salome.ObjectToID(hypNbSeg), "NumberOfSegments_10")
print "-------------------------- MaxElementArea"
maxElementArea = 500
-hyp2=gen.CreateHypothesis("MaxElementArea")
-hypArea=hyp2._narrow(SMESH.SMESH_MaxElementArea)
+hypArea=smesh.CreateHypothesis("MaxElementArea", "libStdMeshersEngine.so")
hypArea.SetMaxElementArea(maxElementArea)
+
print hypArea.GetName()
print hypArea.GetId()
print hypArea.GetMaxElementArea()
-idarea = smeshgui.AddNewHypothesis( salome.orb.object_to_string(hypArea) )
-smeshgui.SetName(idarea, "MaxElementArea")
+smeshgui.SetName(salome.ObjectToID(hypArea), "MaxElementArea_500")
print "-------------------------- MaxElementVolume"
maxElementVolume = 500
-hyp3=gen.CreateHypothesis("MaxElementVolume")
-hypVolume=hyp3._narrow(SMESH.SMESH_MaxElementVolume)
+hypVolume=smesh.CreateHypothesis("MaxElementVolume", "libStdMeshersEngine.so")
hypVolume.SetMaxElementVolume(maxElementVolume)
+
print hypVolume.GetName()
print hypVolume.GetId()
print hypVolume.GetMaxElementVolume()
-idvolume = smeshgui.AddNewHypothesis( salome.orb.object_to_string(hypVolume) )
-smeshgui.SetName(idvolume, "MaxElementVolume")
+smeshgui.SetName(salome.ObjectToID(hypVolume), "MaxElementVolume_500")
# ---- create Algorithms
print "-------------------------- Regular_1D"
-hypothesis=gen.CreateHypothesis("Regular_1D")
-regular1D = hypothesis._narrow(SMESH.SMESH_Regular_1D)
-regularID = smeshgui.AddNewAlgorithms( salome.orb.object_to_string(regular1D) )
-smeshgui.SetName(regularID, "Wire Discretisation")
+regular1D=smesh.CreateHypothesis("Regular_1D", "libStdMeshersEngine.so")
+smeshgui.SetName(salome.ObjectToID(regular1D), "Wire Discretisation")
print "-------------------------- MEFISTO_2D"
-hypothesis=gen.CreateHypothesis("MEFISTO_2D")
-mefisto2D = hypothesis._narrow(SMESH.SMESH_MEFISTO_2D)
-mefistoID = smeshgui.AddNewAlgorithms( salome.orb.object_to_string(mefisto2D) )
-smeshgui.SetName(mefistoID, "MEFISTO_2D")
+mefisto2D=smesh.CreateHypothesis("MEFISTO_2D", "libStdMeshersEngine.so")
+smeshgui.SetName(salome.ObjectToID(mefisto2D), "MEFISTO_2D")
print "-------------------------- NETGEN_3D"
-hypothesis=gen.CreateHypothesis("NETGEN_3D")
-netgen3D = hypothesis._narrow(SMESH.SMESH_NETGEN_3D)
-netgenID = smeshgui.AddNewAlgorithms( salome.orb.object_to_string(netgen3D) )
-smeshgui.SetName(netgenID, "NETGEN_3D")
+netgen3D=smesh.CreateHypothesis("NETGEN_3D", "libNETGENEngine.so")
+smeshgui.SetName(salome.ObjectToID(netgen3D), "NETGEN_3D")
# ---- init a Mesh with the boxe
-mesh=gen.Init(idbox)
-idmesh = smeshgui.AddNewMesh( salome.orb.object_to_string(mesh) )
-smeshgui.SetName(idmesh, "MeshBox")
-smeshgui.SetShape(idbox, idmesh)
+mesh = smesh.CreateMesh(box)
+smeshgui.SetName(salome.ObjectToID(mesh), "MeshBox")
# ---- add hypothesis to the boxe
-print "-------------------------- add hypothesis to the boxe"
+print "-------------------------- add hypothesis to the box"
-ret=mesh.AddHypothesis(box,regular1D)
-print ret
-ret=mesh.AddHypothesis(box,hypNbSeg)
-print ret
-ret=mesh.AddHypothesis(box,mefisto2D)
-print ret
-ret=mesh.AddHypothesis(box,hypArea)
-print ret
-ret=mesh.AddHypothesis(box,netgen3D)
-print ret
-ret=mesh.AddHypothesis(box,hypVolume)
-print ret
+mesh.AddHypothesis(box,regular1D)
+mesh.AddHypothesis(box,hypNbSeg)
-smeshgui.SetAlgorithms( idmesh, regularID)
-smeshgui.SetHypothesis( idmesh, idseg )
-smeshgui.SetAlgorithms( idmesh, mefistoID )
-smeshgui.SetHypothesis( idmesh, idarea )
-smeshgui.SetAlgorithms( idmesh, netgenID )
-smeshgui.SetHypothesis( idmesh, idvolume )
+mesh.AddHypothesis(box,mefisto2D)
+mesh.AddHypothesis(box,hypArea)
-sg.updateObjBrowser(1)
+mesh.AddHypothesis(box,netgen3D)
+mesh.AddHypothesis(box,hypVolume)
+salome.sg.updateObjBrowser(1)
print "-------------------------- compute the mesh of the boxe"
-ret=gen.Compute(mesh,idbox)
+ret=smesh.Compute(mesh,box)
print ret
-log=mesh.GetLog(0) # no erase trace
-for linelog in log:
- print linelog
-
-
-sg.updateObjBrowser(1)
+if ret != 0:
+ log=mesh.GetLog(0) # no erase trace
+ for linelog in log:
+ print linelog
+ print "Information about the MeshBox:"
+ print "Number of nodes : ", mesh.NbNodes()
+ print "Number of edges : ", mesh.NbEdges()
+ print "Number of faces : ", mesh.NbFaces()
+ print "Number of triangles : ", mesh.NbTriangles()
+ print "Number of volumes : ", mesh.NbVolumes()
+ print "Number of tetrahedrons: ", mesh.NbTetras()
+else:
+ print "probleme when computing the mesh"
--- /dev/null
+# Copyright (C) 2004 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
+# CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
+#
+# This library 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.
+#
+# This library 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 this library; if not, write to the Free Software
+# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+#
+# See http://www.opencascade.org/SALOME/ or email : webmaster.salome@opencascade.org
+#
+#
+#
+# File : SMESH_control.py
+# Author : Sergey LITONIN
+# Module : SMESH
+
+
+import SMESH
+import SMESH_mechanic
+
+smesh = SMESH_mechanic.smesh
+mesh = SMESH_mechanic.mesh
+salome = SMESH_mechanic.salome
+
+
+aFilterMgr = smesh.CreateFilterManager()
+
+# Criterion : AREA > 100
+
+aFunctor = aFilterMgr.CreateArea()
+aPredicate = aFilterMgr.CreateMoreThan()
+aPredicate.SetNumFunctor( aFunctor )
+aPredicate.SetMargin( 100 )
+
+aFilter = aFilterMgr.CreateFilter()
+aFilter.SetPredicate( aPredicate )
+
+anIds = aFilter.GetElementsId( mesh )
+
+# print result
+print "Criterion: Area > 100 Nb = ", len( anIds )
+#for i in range( len( anIds ) ):
+ #print anIds[ i ]
+
+# create group
+aGroup = mesh.CreateGroup( SMESH.FACE, "Area > 100" )
+aGroup.Add( anIds )
+
+
+# Criterion : Taper > 3e-15
+
+aFunctor = aFilterMgr.CreateTaper()
+aPredicate = aFilterMgr.CreateMoreThan()
+aPredicate.SetNumFunctor( aFunctor )
+aPredicate.SetMargin( 3e-15 )
+
+aFilter = aFilterMgr.CreateFilter()
+aFilter.SetPredicate( aPredicate )
+
+anIds = aFilter.GetElementsId( mesh )
+
+# print result
+print "Criterion: Taper > 3e-15 Nb = ", len( anIds )
+#for i in range( len( anIds ) ):
+ #print anIds[ i ]
+
+# create group
+aGroup = mesh.CreateGroup( SMESH.FACE, "Taper > 3e-15" )
+aGroup.Add( anIds )
+
+
+# Criterion : ASPECT RATIO > 1.3
+
+aFunctor = aFilterMgr.CreateAspectRatio()
+aPredicate = aFilterMgr.CreateMoreThan()
+aPredicate.SetNumFunctor( aFunctor )
+aPredicate.SetMargin( 1.3 )
+
+aFilter = aFilterMgr.CreateFilter()
+aFilter.SetPredicate( aPredicate )
+
+anIds = aFilter.GetElementsId( mesh )
+
+# print result
+print "Criterion: Aspect Ratio > 1.3 Nb = ", len( anIds )
+#for i in range( len( anIds ) ):
+ #print anIds[ i ]
+
+# create group
+aGroup = mesh.CreateGroup( SMESH.FACE, "Aspect Ratio > 1.3" )
+aGroup.Add( anIds )
+
+
+# Criterion : MINIMUM ANGLE < 30
+
+aFunctor = aFilterMgr.CreateMinimumAngle()
+aPredicate = aFilterMgr.CreateLessThan()
+aPredicate.SetNumFunctor( aFunctor )
+aPredicate.SetMargin( 30 )
+
+aFilter = aFilterMgr.CreateFilter()
+aFilter.SetPredicate( aPredicate )
+
+anIds = aFilter.GetElementsId( mesh )
+
+# print result
+print "Criterion: Minimum Angle < 30 Nb = ", len( anIds )
+#for i in range( len( anIds ) ):
+ #print anIds[ i ]
+
+# create group
+aGroup = mesh.CreateGroup( SMESH.FACE, "Minimum Angle < 30" )
+aGroup.Add( anIds )
+
+# Criterion : Warp > 2e-13
+
+aFunctor = aFilterMgr.CreateWarping()
+aPredicate = aFilterMgr.CreateMoreThan()
+aPredicate.SetNumFunctor( aFunctor )
+aPredicate.SetMargin( 2e-13 )
+
+aFilter = aFilterMgr.CreateFilter()
+aFilter.SetPredicate( aPredicate )
+
+anIds = aFilter.GetElementsId( mesh )
+
+# print result
+print "Criterion: Warp > 2e-13 Nb = ", len( anIds )
+#for i in range( len( anIds ) ):
+ #print anIds[ i ]
+
+# create group
+aGroup = mesh.CreateGroup( SMESH.FACE, "Warp > 2e-13" )
+aGroup.Add( anIds )
+
+# Criterion : Skew > 18
+
+aFunctor = aFilterMgr.CreateSkew()
+aPredicate = aFilterMgr.CreateMoreThan()
+aPredicate.SetNumFunctor( aFunctor )
+aPredicate.SetMargin( 18 )
+
+aFilter = aFilterMgr.CreateFilter()
+aFilter.SetPredicate( aPredicate )
+
+anIds = aFilter.GetElementsId( mesh )
+
+# print result
+print "Criterion: Skew > 18 Nb = ", len( anIds )
+#for i in range( len( anIds ) ):
+ #print anIds[ i ]
+
+# create group
+aGroup = mesh.CreateGroup( SMESH.FACE, "Skew > 18" )
+aGroup.Add( anIds )
+
+# Criterion : Length > 10
+
+aFunctor = aFilterMgr.CreateLength()
+aPredicate = aFilterMgr.CreateMoreThan()
+aPredicate.SetNumFunctor( aFunctor )
+aPredicate.SetMargin( 10 )
+
+aFilter = aFilterMgr.CreateFilter()
+aFilter.SetPredicate( aPredicate )
+
+anIds = aFilter.GetElementsId( mesh )
+
+# print result
+print "Criterion: Length > 10 Nb = ", len( anIds )
+#for i in range( len( anIds ) ):
+ #print anIds[ i ]
+
+# create group
+aGroup = mesh.CreateGroup( SMESH.EDGE, "Length > 10" )
+aGroup.Add( anIds )
+
+# Criterion : Borders at multi-connections = 2
+
+aFunctor = aFilterMgr.CreateMultiConnection()
+aPredicate = aFilterMgr.CreateEqualTo()
+aPredicate.SetNumFunctor( aFunctor )
+aPredicate.SetMargin( 2 )
+
+aFilter = aFilterMgr.CreateFilter()
+aFilter.SetPredicate( aPredicate )
+
+anIds = aFilter.GetElementsId( mesh )
+
+# print result
+print "Criterion: Borders at multi-connections = 2 Nb = ", len( anIds )
+#for i in range( len( anIds ) ):
+ #print anIds[ i ]
+
+# create group
+aGroup = mesh.CreateGroup( SMESH.EDGE, "Borders at multi-connections = 2" )
+aGroup.Add( anIds )
+
+
+salome.sg.updateObjBrowser(1)
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
# $Header$
import salome
-from salome import sg
-
import geompy
-
import math
geom = salome.lcc.FindOrLoadComponent("FactoryServer", "GEOM")
-myBuilder = salome.myStudy.NewBuilder()
ShapeTypeCompSolid = 1
ShapeTypeSolid = 2
bcong1=geom.MakeBoolean(bcong1,cylcongx0,2)
bcong2=geom.MakeBoolean(bcong2,cylcongx0,2)
bcong1=geom.MakeBoolean(bcong1,cylcongy0,2)
+#NRI : inverse order of BOP
+bcong3=geom.MakeBoolean(bcong3,cylcongy0,2)
bcong3=geom.MakeBoolean(bcong3,cylcongx3,2)
bcong4=geom.MakeBoolean(bcong4,cylcongx3,2)
-bcong3=geom.MakeBoolean(bcong3,cylcongy0,2)
pf1 = geom.MakePointStruct(0., y0h, z3)
pf2 = geom.MakePointStruct(0., y1, z3)
#
import SMESH_fixation
-import SMESH
-import smeshpy
+
+import StdMeshers
compshell = SMESH_fixation.compshell
idcomp = SMESH_fixation.idcomp
geompy = SMESH_fixation.geompy
salome = SMESH_fixation.salome
-sg = SMESH_fixation.sg
ShapeTypeShell = 3
ShapeTypeFace = 4
status=geompy.CheckShape(compshell)
print " check status ", status
-### ---- launch SMESH
+### ---------------------------- SMESH --------------------------------------
+smesh = salome.lcc.FindOrLoadComponent("FactoryServer", "SMESH")
smeshgui = salome.ImportComponentGUI("SMESH")
smeshgui.Init(salome.myStudyId)
-gen=smeshpy.smeshpy()
-
### ---- create Hypothesis
print "-------------------------- create Hypothesis"
numberOfSegments = 5
-hyp1=gen.CreateHypothesis("NumberOfSegments")
-hypNbSeg=hyp1._narrow(SMESH.SMESH_NumberOfSegments)
+hypNbSeg=smesh.CreateHypothesis("NumberOfSegments", "libStdMeshersEngine.so")
hypNbSeg.SetNumberOfSegments(numberOfSegments)
-hypNbSegID = hypNbSeg.GetId()
+
print hypNbSeg.GetName()
-print hypNbSegID
+print hypNbSeg.GetId()
print hypNbSeg.GetNumberOfSegments()
-idseg = smeshgui.AddNewHypothesis( salome.orb.object_to_string(hypNbSeg) )
-smeshgui.SetName(idseg, "NumberOfSegments")
+smeshgui.SetName(salome.ObjectToID(hypNbSeg), "NumberOfSegments_5")
# ---- create Algorithms
print "-------------------------- Regular_1D"
-hypothesis=gen.CreateHypothesis("Regular_1D")
-regular1D = hypothesis._narrow(SMESH.SMESH_Regular_1D)
-regularID = smeshgui.AddNewAlgorithms( salome.orb.object_to_string(regular1D) )
-smeshgui.SetName(regularID, "Wire Discretisation")
+regular1D=smesh.CreateHypothesis("Regular_1D", "libStdMeshersEngine.so")
+
+smeshgui.SetName(salome.ObjectToID(regular1D), "Wire Discretisation")
print "-------------------------- Quadrangle_2D"
-hypothesis=gen.CreateHypothesis("Quadrangle_2D")
-quad2D = hypothesis._narrow(SMESH.SMESH_Quadrangle_2D)
-quadID = smeshgui.AddNewAlgorithms( salome.orb.object_to_string(quad2D) )
-smeshgui.SetName(quadID, "Quadrangle_2D")
+quad2D=smesh.CreateHypothesis("Quadrangle_2D", "libStdMeshersEngine.so")
+
+smeshgui.SetName(salome.ObjectToID(quad2D), "Quadrangle_2D")
print "-------------------------- Hexa_3D"
-hypothesis=gen.CreateHypothesis("Hexa_3D")
-hexa3D = hypothesis._narrow(SMESH.SMESH_Hexa_3D)
-hexaID = smeshgui.AddNewAlgorithms( salome.orb.object_to_string(hexa3D) )
-smeshgui.SetName(hexaID, "Hexa_3D")
+hexa3D=smesh.CreateHypothesis("Hexa_3D", "libStdMeshersEngine.so")
+
+smeshgui.SetName(salome.ObjectToID(hexa3D), "Hexa_3D")
# ---- init a Mesh with the compshell
+shape_mesh = salome.IDToObject( idcomp )
+
+mesh=smesh.CreateMesh(shape_mesh)
+smeshgui.SetName(salome.ObjectToID(mesh), "MeshCompShell")
-mesh=gen.Init(idcomp)
-idmesh = smeshgui.AddNewMesh( salome.orb.object_to_string(mesh) )
-smeshgui.SetName(idmesh, "MeshcompShel")
-smeshgui.SetShape(idcomp, idmesh)
# ---- add hypothesis to compshell
print "-------------------------- add hypothesis to compshell"
-ret=mesh.AddHypothesis(compshell,regular1D)
-print ret
-ret=mesh.AddHypothesis(compshell,hypNbSeg)
-print ret
-ret=mesh.AddHypothesis(compshell,quad2D)
-print ret
-ret=mesh.AddHypothesis(compshell,hexa3D)
-print ret
-
-smeshgui.SetAlgorithms( idmesh, regularID)
-smeshgui.SetHypothesis( idmesh, idseg )
-smeshgui.SetAlgorithms( idmesh, quadID )
-smeshgui.SetAlgorithms( idmesh, hexaID )
+mesh.AddHypothesis(shape_mesh,regular1D)
+mesh.AddHypothesis(shape_mesh,hypNbSeg)
-sg.updateObjBrowser(1)
+mesh.AddHypothesis(shape_mesh,quad2D)
+mesh.AddHypothesis(shape_mesh,hexa3D)
+salome.sg.updateObjBrowser(1)
print "-------------------------- compute compshell"
-ret=gen.Compute(mesh,idcomp)
+ret=smesh.Compute(mesh, shape_mesh)
print ret
if ret != 0:
log=mesh.GetLog(0) # no erase trace
for linelog in log:
print linelog
+ print "Information about the MeshcompShel:"
+ print "Number of nodes : ", mesh.NbNodes()
+ print "Number of edges : ", mesh.NbEdges()
+ print "Number of faces : ", mesh.NbFaces()
+ print "Number of quadrangles : ", mesh.NbQuadrangles()
+ print "Number of volumes : ", mesh.NbVolumes()
+ print "Number of hexahedrons : ", mesh.NbHexas()
else:
print "problem when Computing the mesh"
-
-sg.updateObjBrowser(1)
# Hypothesis and algorithms for the mesh generation are global
#
+import StdMeshers
+import NETGENPlugin
import SMESH_fixation
-import SMESH
-import smeshpy
compshell = SMESH_fixation.compshell
idcomp = SMESH_fixation.idcomp
geompy = SMESH_fixation.geompy
salome = SMESH_fixation.salome
-sg = SMESH_fixation.sg
ShapeTypeShell = 3
ShapeTypeFace = 4
status=geompy.CheckShape(compshell)
print " check status ", status
-### ---- launch SMESH
+### ---------------------------- SMESH --------------------------------------
+smesh = salome.lcc.FindOrLoadComponent("FactoryServer", "SMESH")
smeshgui = salome.ImportComponentGUI("SMESH")
smeshgui.Init(salome.myStudyId)
-gen=smeshpy.smeshpy()
-
### ---- create Hypothesis
print "-------------------------- create Hypothesis"
numberOfSegments = 5
-hypothesis=gen.CreateHypothesis("NumberOfSegments")
-hypNbSeg=hypothesis._narrow(SMESH.SMESH_NumberOfSegments)
+hypNbSeg=smesh.CreateHypothesis("NumberOfSegments", "libStdMeshersEngine.so")
hypNbSeg.SetNumberOfSegments(numberOfSegments)
-hypNbSegID = hypNbSeg.GetId()
+
print hypNbSeg.GetName()
-print hypNbSegID
+print hypNbSeg.GetId()
print hypNbSeg.GetNumberOfSegments()
-idseg = smeshgui.AddNewHypothesis( salome.orb.object_to_string(hypNbSeg) )
-smeshgui.SetName(idseg, "NumberOfSegments")
+smeshgui.SetName(salome.ObjectToID(hypNbSeg), "NumberOfSegments_5")
print "-------------------------- MaxElementArea"
-maxElementArea = 80
+## maxElementArea = 80
-hypothesis=gen.CreateHypothesis("MaxElementArea")
-hypArea=hypothesis._narrow(SMESH.SMESH_MaxElementArea)
-hypArea.SetMaxElementArea(maxElementArea)
-print hypArea.GetName()
-print hypArea.GetId()
-print hypArea.GetMaxElementArea()
+## hypArea=smesh.CreateHypothesis("MaxElementArea")
+## hypArea.SetMaxElementArea(maxElementArea)
+## print hypArea.GetName()
+## print hypArea.GetId()
+## print hypArea.GetMaxElementArea()
+## smeshgui.SetName(salome.ObjectToID(hypArea), "MaxElementArea_160")
+hypLengthFromEdges=smesh.CreateHypothesis("LengthFromEdges", "libStdMeshersEngine.so")
+smeshgui.SetName(salome.ObjectToID(hypLengthFromEdges), "LengthFromEdges")
-idarea = smeshgui.AddNewHypothesis( salome.orb.object_to_string(hypArea) )
-smeshgui.SetName(idarea, "MaxElementArea")
print "-------------------------- MaxElementVolume"
-maxElementVolume = 150
+maxElementVolume = 1000
-hypothesis=gen.CreateHypothesis("MaxElementVolume")
-hypVolume=hypothesis._narrow(SMESH.SMESH_MaxElementVolume)
+hypVolume=smesh.CreateHypothesis("MaxElementVolume", "libStdMeshersEngine.so")
hypVolume.SetMaxElementVolume(maxElementVolume)
+
print hypVolume.GetName()
print hypVolume.GetId()
print hypVolume.GetMaxElementVolume()
-idvolume = smeshgui.AddNewHypothesis( salome.orb.object_to_string(hypVolume) )
-smeshgui.SetName(idvolume, "MaxElementVolume")
+smeshgui.SetName(salome.ObjectToID(hypVolume), "MaxElementVolume_1000")
# ---- create Algorithms
print "-------------------------- Regular_1D"
-hypothesis=gen.CreateHypothesis("Regular_1D")
-regular1D = hypothesis._narrow(SMESH.SMESH_Regular_1D)
-regularID = smeshgui.AddNewAlgorithms( salome.orb.object_to_string(regular1D) )
-smeshgui.SetName(regularID, "Wire Discretisation")
+regular1D=smesh.CreateHypothesis("Regular_1D", "libStdMeshersEngine.so")
+
+smeshgui.SetName(salome.ObjectToID(regular1D), "Wire Discretisation")
print "-------------------------- MEFISTO_2D"
-hypothesis=gen.CreateHypothesis("MEFISTO_2D")
-mefisto2D = hypothesis._narrow(SMESH.SMESH_MEFISTO_2D)
-mefistoID = smeshgui.AddNewAlgorithms( salome.orb.object_to_string(mefisto2D) )
-smeshgui.SetName(mefistoID, "MEFISTO_2D")
+mefisto2D=smesh.CreateHypothesis("MEFISTO_2D", "libStdMeshersEngine.so")
+
+smeshgui.SetName(salome.ObjectToID(mefisto2D), "MEFISTO_2D")
print "-------------------------- NETGEN_3D"
-hypothesis=gen.CreateHypothesis("NETGEN_3D")
-netgen3D = hypothesis._narrow(SMESH.SMESH_NETGEN_3D)
-netgenID = smeshgui.AddNewAlgorithms( salome.orb.object_to_string(netgen3D) )
-smeshgui.SetName(netgenID, "NETGEN_3D")
+netgen3D=smesh.CreateHypothesis("NETGEN_3D", "libNETGENEngine.so")
+
+smeshgui.SetName(salome.ObjectToID(netgen3D), "NETGEN_3D")
# ---- init a Mesh with the compshell
-mesh=gen.Init(idcomp)
-idmesh = smeshgui.AddNewMesh( salome.orb.object_to_string(mesh) )
-smeshgui.SetName(idmesh, "MeshcompShell")
-smeshgui.SetShape(idcomp, idmesh)
+mesh=smesh.CreateMesh(compshell)
+smeshgui.SetName(salome.ObjectToID(mesh), "MeshcompShel")
# ---- add hypothesis to compshell
print "-------------------------- add hypothesis to compshell"
-ret=mesh.AddHypothesis(compshell,regular1D)
-print ret
-ret=mesh.AddHypothesis(compshell,hypNbSeg)
-print ret
-ret=mesh.AddHypothesis(compshell,mefisto2D)
-print ret
-ret=mesh.AddHypothesis(compshell,hypArea)
-print ret
-ret=mesh.AddHypothesis(compshell,netgen3D)
-print ret
-ret=mesh.AddHypothesis(compshell,hypVolume)
-print ret
+mesh.AddHypothesis(compshell,regular1D)
+mesh.AddHypothesis(compshell,hypNbSeg)
+
+mesh.AddHypothesis(compshell,mefisto2D)
+mesh.AddHypothesis(compshell,hypLengthFromEdges)
-smeshgui.SetAlgorithms( idmesh, regularID)
-smeshgui.SetHypothesis( idmesh, idseg )
-smeshgui.SetAlgorithms( idmesh, mefistoID )
-smeshgui.SetHypothesis( idmesh, idarea )
-smeshgui.SetAlgorithms( idmesh, netgenID )
-smeshgui.SetHypothesis( idmesh, idvolume )
+mesh.AddHypothesis(compshell,netgen3D)
+mesh.AddHypothesis(compshell,hypVolume)
-sg.updateObjBrowser(1)
+salome.sg.updateObjBrowser(1)
print "-------------------------- compute compshell"
-ret=gen.Compute(mesh,idcomp)
+ret=smesh.Compute(mesh,compshell)
print ret
if ret != 0:
log=mesh.GetLog(0) # no erase trace
for linelog in log:
print linelog
+ print "Information about the MeshcompShel:"
+ print "Number of nodes : ", mesh.NbNodes()
+ print "Number of edges : ", mesh.NbEdges()
+ print "Number of faces : ", mesh.NbFaces()
+ print "Number of triangles : ", mesh.NbTriangles()
+ print "Number of volumes : ", mesh.NbVolumes()
+ print "Number of tetrahedrons : ", mesh.NbTetras()
+
else:
print "problem when computing the mesh"
-
-sg.updateObjBrowser(1)
# Hypothesis and algorithms for the mesh generation are global
#
+import os
import salome
-from salome import sg
-
import geompy
-import SMESH
-import smeshpy
+import StdMeshers
+
+geom = salome.lcc.FindOrLoadComponent("FactoryServer", "GEOM")
+smesh = salome.lcc.FindOrLoadComponent("FactoryServer", "SMESH")
+
+smeshgui = salome.ImportComponentGUI("SMESH")
+smeshgui.Init(salome.myStudyId);
+
-geom = geompy.geom
-myBuilder = geompy.myBuilder
+# ---------------------------- GEOM --------------------------------------
ShapeTypeShell = 3
ShapeTypeFace = 4
ShapeTypeEdge = 6
-import os
-
# import a BRep
#before running this script, please be sure about
#the path the file fileName
print "number of Faces in flight : ",len(subFaceList)
print "number of Edges in flight : ",len(subEdgeList)
-# ---- launch SMESH
-
-smeshgui = salome.ImportComponentGUI("SMESH")
-smeshgui.Init(salome.myStudyId)
-gen=smeshpy.smeshpy()
+### ---------------------------- SMESH --------------------------------------
# ---- create Hypothesis
lengthOfSegments = 0.3
-hypothesis=gen.CreateHypothesis("LocalLength")
-hypLength=hypothesis._narrow(SMESH.SMESH_LocalLength)
+hypLength=smesh.CreateHypothesis("LocalLength", "libStdMeshersEngine.so")
hypLength.SetLength(lengthOfSegments)
-hypLengthID = hypLength.GetId()
+
print hypLength.GetName()
-print hypLengthID
+print hypLength.GetId()
print hypLength.GetLength()
-idlen = smeshgui.AddNewHypothesis( salome.orb.object_to_string(hypLength) )
-smeshgui.SetName(idlen, "LocalLength")
+smeshgui.SetName(salome.ObjectToID(hypLength), "LocalLength_0.3")
print "-------------------------- LengthFromEdges"
-hypothesis=gen.CreateHypothesis("LengthFromEdges")
-hypLengthFromEdge=hypothesis._narrow(SMESH.SMESH_LengthFromEdges)
-hypLengthFromEdgeID = hypLengthFromEdge.GetId()
+hypLengthFromEdge=smesh.CreateHypothesis("LengthFromEdges", "libStdMeshersEngine.so")
+
print hypLengthFromEdge.GetName()
-print hypLengthFromEdgeID
+print hypLengthFromEdge.GetId()
-idlenfromedge = smeshgui.AddNewHypothesis( salome.orb.object_to_string(hypLengthFromEdge) )
-smeshgui.SetName(idlenfromedge, "LengthFromEdge")
+smeshgui.SetName(salome.ObjectToID(hypLengthFromEdge), "LengthFromEdge")
# ---- create Algorithms
print "-------------------------- Regular_1D"
-hypothesis=gen.CreateHypothesis("Regular_1D")
-regular1D = hypothesis._narrow(SMESH.SMESH_Regular_1D)
-regularID = smeshgui.AddNewAlgorithms( salome.orb.object_to_string(regular1D) )
-smeshgui.SetName(regularID, "Wire Discretisation")
+regular1D=smesh.CreateHypothesis("Regular_1D", "libStdMeshersEngine.so")
+
+smeshgui.SetName(salome.ObjectToID(regular1D), "Wire Discretisation")
print "-------------------------- MEFISTO_2D"
-hypothesis=gen.CreateHypothesis("MEFISTO_2D")
-mefisto2D = hypothesis._narrow(SMESH.SMESH_MEFISTO_2D)
-mefistoID = smeshgui.AddNewAlgorithms( salome.orb.object_to_string(mefisto2D) )
-smeshgui.SetName(mefistoID, "MEFISTO_2D")
+mefisto2D=smesh.CreateHypothesis("MEFISTO_2D", "libStdMeshersEngine.so")
+
+smeshgui.SetName(salome.ObjectToID(mefisto2D), "MEFISTO_2D")
# ---- init a Mesh with the shell
+shape_mesh = salome.IDToObject( idShape )
-mesh=gen.Init(idShape)
-idmesh = smeshgui.AddNewMesh( salome.orb.object_to_string(mesh) )
-smeshgui.SetName(idmesh, "MeshFlight")
-smeshgui.SetShape(idShape, idmesh)
+mesh=smesh.CreateMesh(shape_mesh)
+smeshgui.SetName(salome.ObjectToID(mesh), "MeshFlight")
# ---- add hypothesis to flight
print "-------------------------- add hypothesis to flight"
-ret=mesh.AddHypothesis(shape,regular1D)
-print ret
-ret=mesh.AddHypothesis(shape,hypLength)
-print ret
-ret=mesh.AddHypothesis(shape,mefisto2D)
-print ret
-ret=mesh.AddHypothesis(shape,hypLengthFromEdge)
-print ret
-
-smeshgui.SetAlgorithms( idmesh, regularID)
-smeshgui.SetHypothesis( idmesh, idlen )
-smeshgui.SetAlgorithms( idmesh, mefistoID )
-smeshgui.SetHypothesis( idmesh, idlenfromedge)
+mesh.AddHypothesis(shape_mesh,regular1D)
+mesh.AddHypothesis(shape_mesh,hypLength)
+mesh.AddHypothesis(shape_mesh,mefisto2D)
+mesh.AddHypothesis(shape_mesh,hypLengthFromEdge)
-sg.updateObjBrowser(1)
+salome.sg.updateObjBrowser(1)
print "-------------------------- compute the skin flight"
-ret=gen.Compute(mesh,idShape)
+ret=smesh.Compute(mesh,shape_mesh)
print ret
if ret != 0:
log=mesh.GetLog(0) # no erase trace
for linelog in log:
print linelog
+ print "Information about the Mesh_mechanic_tetra:"
+ print "Number of nodes : ", mesh.NbNodes()
+ print "Number of edges : ", mesh.NbEdges()
+ print "Number of faces : ", mesh.NbFaces()
+ print "Number of triangles : ", mesh.NbTriangles()
+ print "Number of volumes : ", mesh.NbVolumes()
else:
print "probleme when computing the mesh"
-
-sg.updateObjBrowser(1)
--- /dev/null
+import salome\r
+from geompy import gg\r
+import geompy\r
+import SMESH\r
+\r
+import StdMeshers\r
+\r
+ShapeTypeCompSolid = 1\r
+ShapeTypeSolid = 2\r
+ShapeTypeShell = 3\r
+ShapeTypeFace = 4\r
+ShapeTypeWire = 5\r
+ShapeTypeEdge = 6\r
+ShapeTypeVertex = 7\r
+\r
+geom = salome.lcc.FindOrLoadComponent("FactoryServer", "GEOM")\r
+smesh = salome.lcc.FindOrLoadComponent("FactoryServer", "SMESH")\r
+\r
+geom.GetCurrentStudy(salome.myStudy._get_StudyId())\r
+smesh.SetCurrentStudy(salome.myStudy)\r
+\r
+# Create box without one plane\r
+\r
+box = geompy.MakeBox(0., 0., 0., 10., 20., 30.)\r
+subShapeList = geompy.SubShapeAll(box,ShapeTypeFace)\r
+\r
+FaceList = []\r
+for i in range( 5 ):\r
+ FaceList.append( subShapeList[ i ]._get_Name() )\r
+\r
+aBox = geompy.MakeSewing( FaceList, 1. )\r
+idbox = geompy.addToStudy( aBox, "box" )\r
+ \r
+aBox = salome.IDToObject( idbox )\r
+\r
+# Create mesh\r
+\r
+hyp1 = smesh.CreateHypothesis("NumberOfSegments", "libStdMeshersEngine.so")\r
+hyp1.SetNumberOfSegments(5)\r
+hyp2 = smesh.CreateHypothesis("MaxElementArea", "libStdMeshersEngine.so")\r
+hyp2.SetMaxElementArea(20)\r
+hyp3 = smesh.CreateHypothesis("MaxElementArea", "libStdMeshersEngine.so")\r
+hyp3.SetMaxElementArea(50)\r
+\r
+algo1 = smesh.CreateHypothesis("Regular_1D", "libStdMeshersEngine.so")\r
+algo2 = smesh.CreateHypothesis("MEFISTO_2D", "libStdMeshersEngine.so")\r
+\r
+mesh = smesh.CreateMesh(aBox)\r
+mesh.AddHypothesis(aBox,hyp1)\r
+mesh.AddHypothesis(aBox,hyp2)\r
+mesh.AddHypothesis(aBox,algo1)\r
+mesh.AddHypothesis(aBox,algo2)\r
+\r
+smesh.Compute(mesh,aBox)\r
+\r
+smeshgui = salome.ImportComponentGUI("SMESH")\r
+smeshgui.Init(salome.myStudyId);\r
+smeshgui.SetName( salome.ObjectToID( mesh ), "Mesh_freebord" );\r
+\r
+# Criterion : Free edges\r
+aFilterMgr = smesh.CreateFilterManager()\r
+aPredicate = aFilterMgr.CreateFreeBorders()\r
+aFilter = aFilterMgr.CreateFilter()\r
+aFilter.SetPredicate( aPredicate )\r
+\r
+anIds = aFilter.GetElementsId( mesh )\r
+\r
+# print result\r
+print "Criterion: Free edges Nb = ", len( anIds )\r
+for i in range( len( anIds ) ):\r
+ print anIds[ i ]\r
+\r
+# create group\r
+aGroup = mesh.CreateGroup( SMESH.EDGE, "Free edges" )\r
+aGroup.Add( anIds )\r
+\r
+\r
+salome.sg.updateObjBrowser(1)\r
# Module : SMESH
# $Header$
-import SMESH
-import smeshpy
import salome
-from salome import sg
-import math
-#import SMESH_BasicHypothesis_idl
-
import geompy
+geom = salome.lcc.FindOrLoadComponent("FactoryServer", "GEOM")
+smesh = salome.lcc.FindOrLoadComponent("FactoryServer", "SMESH")
-
-# ---------------------------- GEOM --------------------------------------
-geom = salome.lcc.FindOrLoadComponent("FactoryServer", "GEOM")
-myBuilder = salome.myStudy.NewBuilder()
-#from geompy import gg
+geom.GetCurrentStudy(salome.myStudy._get_StudyId())
+smesh.SetCurrentStudy(salome.myStudy)
smeshgui = salome.ImportComponentGUI("SMESH")
smeshgui.Init(salome.myStudyId);
+import StdMeshers
+
+# ---------------------------- GEOM --------------------------------------
ShapeTypeCompSolid = 1
ShapeTypeSolid = 2
ShapeTypeShell = 3
ShapeTypeEdge = 6
ShapeTypeVertex = 7
-
# ---- define contigous arcs and segment to define a closed wire
-
p1 = geom.MakePointStruct( 100.0, 0.0, 0.0 )
p2 = geom.MakePointStruct( 50.0, 50.0, 0.0 )
p3 = geom.MakePointStruct( 100.0, 100.0, 0.0 )
p7 = geom.MakePointStruct( 120.0, 30.0, 0.0 )
arc3 = geom.MakeArc( p6, p7, p1 )
-
# ---- define a closed wire with arcs and segment
-
List1 = []
List1.append( arc1 )
List1.append( seg1 )
Id_wire1 = geompy.addToStudy( wire1, "wire1")
-
# ---- define a planar face with wire
WantPlanarFace = 1 #True
face1 = geom.MakeFace( wire1, WantPlanarFace )
Id_face1 = geompy.addToStudy( face1, "face1")
-
# ---- create a shape by extrusion
pO = geom.MakePointStruct( 0.0, 0.0, 0.0 )
pz = geom.MakePointStruct( 0.0, 0.0, 100.0 )
prism1 = geom.MakePrism( face1, pO, pz )
Id_prism1 = geompy.addToStudy( prism1, "prism1")
-
-
# ---- create two cylinders
pc1 = geom.MakePointStruct( 90.0, 50.0, -40.0 )
Id_Cyl1 = geompy.addToStudy( cyl1, "cyl1" )
Id_Cyl2 = geompy.addToStudy( cyl2, "cyl2" )
-
# ---- cut with cyl1
shape = geom.MakeBoolean( prism1, cyl1, 2 )
Id_shape1 = geompy.addToStudy( shape1, "shape1")
-
+#faces = geompy.SubShapeAllSorted( shape1, ShapeTypeFace)
+#i = 0
+#for face in faces:
+# geompy.addToStudy(face,"face_" + str(i))
+# i = i+1
+
# ---- add a face sub shape in study to be meshed different
IdSubFaceList = []
-IdSubFaceList.append(10)
+IdSubFaceList.append(1)
sub_face = geompy.SubShapeSorted( shape1, ShapeTypeFace, IdSubFaceList )
name = geompy.SubShapeName( sub_face._get_Name(), shape1._get_Name() )
Id_SubFace = geompy.addToStudyInFather( shape1, sub_face, name )
-
# ---- add a face sub shape in study to be meshed different
IdSubFaceL = []
-IdSubFaceL.append(7)
+IdSubFaceL.append(2)
sub_face2 = geompy.SubShapeSorted( shape1, ShapeTypeFace, IdSubFaceL )
name = geompy.SubShapeName( sub_face2._get_Name(), shape1._get_Name() )
Id_SubFace2 = geompy.addToStudyInFather( shape1, sub_face2, name )
+# ---- add a face sub shape in study to be meshed different
+IdSubFaceL = []
+IdSubFaceL.append(3)
+sub_face3 = geompy.SubShapeSorted( shape1, ShapeTypeFace, IdSubFaceL )
+name = geompy.SubShapeName( sub_face3._get_Name(), shape1._get_Name() )
+Id_SubFace3 = geompy.addToStudyInFather( shape1, sub_face3, name )
+# ---- add a face sub shape in study to be meshed different
+IdSubFaceL = []
+IdSubFaceL.append(6)
+sub_face4 = geompy.SubShapeSorted( shape1, ShapeTypeFace, IdSubFaceL )
+name = geompy.SubShapeName( sub_face4._get_Name(), shape1._get_Name() )
-# ---------------------------- SMESH --------------------------------------
-
-# ---- launch SMESH, init a Mesh with shape 'shape1'
-gen = smeshpy.smeshpy()
-mesh = gen.Init( Id_shape1 )
+Id_SubFace4 = geompy.addToStudyInFather( shape1, sub_face4, name )
-idmesh = smeshgui.AddNewMesh( salome.orb.object_to_string(mesh) )
-smeshgui.SetName( idmesh, "Mesh_meca" );
-smeshgui.SetShape( Id_shape1, idmesh );
+# ---------------------------- SMESH --------------------------------------
# ------------------------------ Length Hypothesis
print "-------------------------- create Hypothesis"
print "-------------------------- LocalLength"
-hyp1 = gen.CreateHypothesis( "LocalLength" )
-hypLen1 = hyp1._narrow( SMESH.SMESH_LocalLength )
-hypLen1.SetLength( 100.0 )
-print hypLen1.GetName()
-print hypLen1.GetId()
-print hypLen1.GetLength()
-
-idlength = smeshgui.AddNewHypothesis( salome.orb.object_to_string(hypLen1) );
-smeshgui.SetName(idlength, "Local_Length_100");
+hyp1 = smesh.CreateHypothesis("LocalLength", "libStdMeshersEngine.so")
+hyp1.SetLength( 100.0 )
+print hyp1.GetName()
+print hyp1.GetId()
+print hyp1.GetLength()
+idlength = salome.ObjectToID(hyp1)
+smeshgui.SetName(idlength, "Local_Length_100");
print "-------------------------- NumberOfSegments"
-hyp2 = gen.CreateHypothesis( "NumberOfSegments" )
-hypNbSeg1 = hyp2._narrow( SMESH.SMESH_NumberOfSegments )
-hypNbSeg1.SetNumberOfSegments( 10 )
-print hypNbSeg1.GetName()
-print hypNbSeg1.GetId()
-print hypNbSeg1.GetNumberOfSegments()
+hyp2 = smesh.CreateHypothesis("NumberOfSegments", "libStdMeshersEngine.so")
+hyp2.SetNumberOfSegments( 10 )
+print hyp2.GetName()
+print hyp2.GetId()
+print hyp2.GetNumberOfSegments()
-idseg = smeshgui.AddNewHypothesis( salome.orb.object_to_string(hypNbSeg1) );
+idseg = salome.ObjectToID(hyp2)
smeshgui.SetName(idseg, "NumberOfSegments_12");
-
print "-------------------------- MaxElementArea"
-hyp3 = gen.CreateHypothesis( "MaxElementArea" )
-hypArea1 = hyp3._narrow( SMESH.SMESH_MaxElementArea )
-hypArea1.SetMaxElementArea( 25 )
-print hypArea1.GetName()
-print hypArea1.GetId()
-print hypArea1.GetMaxElementArea()
+hyp3 = smesh.CreateHypothesis( "MaxElementArea", "libStdMeshersEngine.so" )
+hyp3.SetMaxElementArea( 25 )
+print hyp3.GetName()
+print hyp3.GetId()
+print hyp3.GetMaxElementArea()
-idarea1 = smeshgui.AddNewHypothesis( salome.orb.object_to_string(hypArea1) );
+idarea1 = salome.ObjectToID(hyp3)
smeshgui.SetName(idarea1, "MaxElementArea_20");
-
-
print "-------------------------- MaxElementArea"
-hyp4 = gen.CreateHypothesis( "MaxElementArea" )
-hypArea2 = hyp4._narrow( SMESH.SMESH_MaxElementArea )
-hypArea2.SetMaxElementArea( 35 )
-print hypArea2. GetName()
-print hypArea2.GetId()
-print hypArea2.GetMaxElementArea()
+hyp4 = smesh.CreateHypothesis("MaxElementArea", "libStdMeshersEngine.so")
+hyp4.SetMaxElementArea( 35 )
+print hyp4.GetName()
+print hyp4.GetId()
+print hyp4.GetMaxElementArea()
-idarea2 = smeshgui.AddNewHypothesis( salome.orb.object_to_string(hypArea2) );
+idarea2 = salome.ObjectToID(hyp4)
smeshgui.SetName(idarea2, "MaxElementArea_30");
print "-------------------------- Regular_1D"
-alg1 = gen.CreateHypothesis( "Regular_1D" )
-algo1 = alg1._narrow( SMESH.SMESH_Algo )
-listHyp =algo1.GetCompatibleHypothesis()
+alg1 = smesh.CreateHypothesis("Regular_1D", "libStdMeshersEngine.so")
+listHyp =alg1.GetCompatibleHypothesis()
for hyp in listHyp:
print hyp
-algoReg1d = alg1._narrow( SMESH.SMESH_Regular_1D )
-print algoReg1d.GetName()
-print algoReg1d.GetId()
+print alg1.GetName()
+print alg1.GetId()
-idreg1d = smeshgui.AddNewAlgorithms( salome.orb.object_to_string(algoReg1d) );
+idreg1d = salome.ObjectToID(alg1)
smeshgui.SetName( idreg1d, "Regular_1D" );
-
-
print "-------------------------- MEFISTO_2D"
-alg2 = gen.CreateHypothesis( "MEFISTO_2D" )
-algo2 = alg2._narrow( SMESH.SMESH_Algo )
-listHyp = algo2.GetCompatibleHypothesis()
+alg2 = smesh.CreateHypothesis("MEFISTO_2D", "libStdMeshersEngine.so")
+listHyp = alg2.GetCompatibleHypothesis()
for hyp in listHyp:
print hyp
-algoMef = alg2._narrow( SMESH.SMESH_MEFISTO_2D )
-print algoMef.GetName()
-print algoMef.GetId()
+print alg2.GetName()
+print alg2.GetId()
-idmef = smeshgui.AddNewAlgorithms( salome.orb.object_to_string(algoMef) );
+idmef = salome.ObjectToID(alg2)
smeshgui.SetName( idmef, "MEFISTO_2D" );
-
-
print "-------------------------- SMESH_Quadrangle_2D"
-alg3 = gen.CreateHypothesis( "Quadrangle_2D" )
-algo3 = alg3._narrow( SMESH.SMESH_2D_Algo )
-listHyp = algo3.GetCompatibleHypothesis()
+alg3 = smesh.CreateHypothesis( "Quadrangle_2D", "libStdMeshersEngine.so" )
+listHyp = alg3.GetCompatibleHypothesis()
for hyp in listHyp:
print hyp
-algoQad2 = alg3._narrow( SMESH.SMESH_Quadrangle_2D )
-print algoQad2.GetName()
-print algoQad2.GetId()
+print alg3.GetName()
+print alg3.GetId()
-idqad2 = smeshgui.AddNewAlgorithms( salome.orb.object_to_string(algoQad2) );
+idqad2 = salome.ObjectToID(alg3)
smeshgui.SetName( idqad2, "SMESH_Quadrangle_2D" );
-
print "-------------------------- add hypothesis to main shape1"
shape_mesh = salome.IDToObject( Id_shape1 )
-submesh = mesh.GetElementsOnShape( shape_mesh )
-
-ret = mesh.AddHypothesis( shape_mesh, algoReg1d ) # Regular 1D/wire discretisation
-print ret
-ret = mesh.AddHypothesis( shape_mesh, algoMef ) # MEFISTO 2D
-print ret
-ret = mesh.AddHypothesis( shape_mesh, hypNbSeg1 ) # nb segments
-print ret
-ret = mesh.AddHypothesis( shape_mesh, hypArea1 ) # max area
-print ret
-smeshgui.SetAlgorithms( idmesh, idreg1d ); # Regular 1D/wire discretisation
-smeshgui.SetAlgorithms( idmesh, idmef ); # MEFISTO 2D
-smeshgui.SetHypothesis( idmesh, idseg ); # nb segments
-smeshgui.SetHypothesis( idmesh, idarea1 ); # max area
+mesh = smesh.CreateMesh(shape_mesh)
+idmesh = salome.ObjectToID(mesh)
+smeshgui.SetName( idmesh, "Mesh_mechanic" );
+mesh.AddHypothesis( shape_mesh, alg1 ) # Regular 1D/wire discretisation
+mesh.AddHypothesis( shape_mesh, alg2 ) # MEFISTO 2D
-print "-------------------------- add hypothesis and algorith to sub face"
+ret = mesh.AddHypothesis( shape_mesh, hyp2 ) # nb segments
+ret = mesh.AddHypothesis( shape_mesh, hyp3 ) # max area
-sub_face = salome.IDToObject( Id_SubFace )
-submesh = mesh.GetElementsOnShape( sub_face )
+print "--------Add hypothesis and algorith to sub face"
-ret = mesh.AddHypothesis( sub_face, algoQad2 ) # Quadrangle 2D
-print ret
-ret = mesh.AddHypothesis( sub_face, hypArea2 ) # max area
-print ret
+#sub_face = salome.IDToObject( Id_SubFace )
+submesh = mesh.GetSubMesh(sub_face, "SubMeshFace")
-idsm2 = smeshgui.AddSubMeshOnShape( idmesh,
- Id_SubFace,
- salome.orb.object_to_string(submesh),
- ShapeTypeFace )
+mesh.AddHypothesis( sub_face, alg3 ) # Quadrangle 2D
+mesh.AddHypothesis( sub_face, hyp4 ) # max area
-smeshgui.SetName(idsm2, "SubMeshFace")
-smeshgui.SetAlgorithms( idsm2, idqad2 ); # Quadrangle 2D
-smeshgui.SetHypothesis( idsm2, idarea2 ); # max area
+print "--------Add hypothesis and algorith to sub face 2"
+#sub_face2 = salome.IDToObject( Id_SubFace2 )
+submesh = mesh.GetSubMesh(sub_face2, "SubMeshFace2")
+mesh.AddHypothesis( sub_face2, alg3 ) # Quadrangle 2D
+ret = mesh.AddHypothesis( sub_face2, hyp4 ) # max area
-print "-------------------------- add hypothesis and algorith to sub face"
+print "--------Add hypothesis and algorith to sub face 3"
-sub_face2 = salome.IDToObject( Id_SubFace2 )
-submesh = mesh.GetElementsOnShape( sub_face2 )
+#sub_face3 = salome.IDToObject( Id_SubFace3 )
+submesh = mesh.GetSubMesh(sub_face3, "SubMeshFace3")
-ret = mesh.AddHypothesis( sub_face2, algoQad2 ) # Quadrangle 2D
-print ret
-ret = mesh.AddHypothesis( sub_face2, hypArea2 ) # max area
-print ret
+mesh.AddHypothesis( sub_face3, alg3 ) # Quadrangle 2D
+ret = mesh.AddHypothesis( sub_face3, hyp4 ) # max area
-idsm3 = smeshgui.AddSubMeshOnShape( idmesh,
- Id_SubFace2,
- salome.orb.object_to_string(submesh),
- ShapeTypeFace )
+print "--------Add hypothesis and algorith to sub face 4"
-smeshgui.SetName(idsm3, "SubMeshFace2")
-smeshgui.SetAlgorithms( idsm3, idqad2 ); # Quadrangle 2D
-smeshgui.SetHypothesis( idsm3, idarea2 ); # max area
+#sub_face4 = salome.IDToObject( Id_SubFace4 )
+submesh = mesh.GetSubMesh(sub_face4, "SubMeshFace4")
+mesh.AddHypothesis( sub_face4, alg3 ) # Quadrangle 2D
+ret = mesh.AddHypothesis( sub_face4, hyp4 ) # max area
+smesh.Compute(mesh,shape_mesh)
+print "Information about the Mesh_mechanic:"
+print "Number of nodes : ", mesh.NbNodes()
+print "Number of edges : ", mesh.NbEdges()
+print "Number of faces : ", mesh.NbFaces()
+print "Number of triangles : ", mesh.NbTriangles()
+print "Number of quadrangles: ", mesh.NbQuadrangles()
-sg.updateObjBrowser(1);
+salome.sg.updateObjBrowser(1);
# Module : SMESH
# $Header$
-import SMESH
-import smeshpy
import salome
-from salome import sg
-import math
-
import geompy
-# ---------------------------- GEOM --------------------------------------
-geom = salome.lcc.FindOrLoadComponent("FactoryServer", "GEOM")
-myBuilder = salome.myStudy.NewBuilder()
-#from geompy import gg
+import StdMeshers
+import NETGENPlugin
+
+geom = salome.lcc.FindOrLoadComponent("FactoryServer", "GEOM")
+smesh = salome.lcc.FindOrLoadComponent("FactoryServer", "SMESH")
smeshgui = salome.ImportComponentGUI("SMESH")
-smeshgui.Init(salome.myStudyId)
+smeshgui.Init(salome.myStudyId);
+# ---------------------------- GEOM --------------------------------------
ShapeTypeCompSolid = 1
ShapeTypeSolid = 2
ShapeTypeShell = 3
### ---------------------------- SMESH --------------------------------------
-# ---- launch SMESH, init a Mesh with shape 'mechanic'
-
-gen = smeshpy.smeshpy()
-mesh = gen.Init( idMechanic )
-
-idmesh = smeshgui.AddNewMesh( salome.orb.object_to_string(mesh) )
-smeshgui.SetName( idmesh, "Mesh_mechanic" )
-smeshgui.SetShape( idMechanic, idmesh )
-
print "-------------------------- NumberOfSegments"
numberOfSegment = 10
-hypNumberOfSegment = gen.CreateHypothesis( "NumberOfSegments" )
-hypNbSeg = hypNumberOfSegment._narrow( SMESH.SMESH_NumberOfSegments )
+hypNbSeg = smesh.CreateHypothesis( "NumberOfSegments", "libStdMeshersEngine.so" )
hypNbSeg.SetNumberOfSegments(numberOfSegment)
print hypNbSeg.GetName()
print hypNbSeg.GetId()
print hypNbSeg.GetNumberOfSegments()
-idSeg = smeshgui.AddNewHypothesis( salome.orb.object_to_string(hypNbSeg) )
-smeshgui.SetName(idSeg, "NumberOfSegments")
+smeshgui.SetName(salome.ObjectToID(hypNbSeg), "NumberOfSegments_10")
print "-------------------------- MaxElementArea"
maxElementArea = 20
-hypMaxElementArea = gen.CreateHypothesis( "MaxElementArea" )
-hypArea = hypMaxElementArea._narrow( SMESH.SMESH_MaxElementArea )
+hypArea = smesh.CreateHypothesis( "MaxElementArea", "libStdMeshersEngine.so" )
hypArea.SetMaxElementArea(maxElementArea)
print hypArea.GetName()
print hypArea.GetId()
print hypArea.GetMaxElementArea()
-idArea = smeshgui.AddNewHypothesis( salome.orb.object_to_string(hypArea) )
-smeshgui.SetName(idArea, "MaxElementArea")
+smeshgui.SetName(salome.ObjectToID(hypArea), "MaxElementArea_20")
print "-------------------------- MaxElementVolume"
maxElementVolume = 20
-hypMaxElementVolume = gen.CreateHypothesis( "MaxElementVolume" )
-hypVolume = hypMaxElementVolume._narrow( SMESH.SMESH_MaxElementVolume )
+hypVolume = smesh.CreateHypothesis( "MaxElementVolume", "libStdMeshersEngine.so" )
hypVolume.SetMaxElementVolume(maxElementVolume)
print hypVolume.GetName()
print hypVolume.GetId()
print hypVolume.GetMaxElementVolume()
-idVolume = smeshgui.AddNewHypothesis( salome.orb.object_to_string(hypVolume) )
-smeshgui.SetName(idVolume, "MaxElementArea")
+smeshgui.SetName(salome.ObjectToID(hypVolume), "MaxElementVolume_20")
print "-------------------------- Regular_1D"
-alg1D = gen.CreateHypothesis( "Regular_1D" )
-algo1D = alg1D._narrow( SMESH.SMESH_Algo )
-listHyp =algo1D.GetCompatibleHypothesis()
+algoReg1D = smesh.CreateHypothesis( "Regular_1D", "libStdMeshersEngine.so" )
+listHyp =algoReg1D.GetCompatibleHypothesis()
for hyp in listHyp:
print hyp
-algoReg1D = alg1D._narrow( SMESH.SMESH_Regular_1D )
print algoReg1D.GetName()
print algoReg1D.GetId()
-idReg1D = smeshgui.AddNewAlgorithms( salome.orb.object_to_string(algoReg1D) )
-smeshgui.SetName( idReg1D, "Regular_1D" )
+smeshgui.SetName(salome.ObjectToID(algoReg1D), "Regular_1D" )
print "-------------------------- MEFISTO_2D"
-alg2D = gen.CreateHypothesis( "MEFISTO_2D" )
-algo2D = alg2D._narrow( SMESH.SMESH_Algo )
-listHyp = algo2D.GetCompatibleHypothesis()
+algoMef = smesh.CreateHypothesis( "MEFISTO_2D", "libStdMeshersEngine.so" )
+listHyp = algoMef.GetCompatibleHypothesis()
for hyp in listHyp:
print hyp
-algoMef = alg2D._narrow( SMESH.SMESH_MEFISTO_2D )
print algoMef.GetName()
print algoMef.GetId()
-idMef = smeshgui.AddNewAlgorithms( salome.orb.object_to_string(algoMef) )
-smeshgui.SetName( idMef, "MEFISTO_2D" )
+smeshgui.SetName(salome.ObjectToID(algoMef), "MEFISTO_2D" )
print "-------------------------- NETGEN_3D"
-alg3D = gen.CreateHypothesis( "NETGEN_3D" )
-algo3D = alg3D._narrow( SMESH.SMESH_Algo )
-listHyp = algo3D.GetCompatibleHypothesis()
+algoNg = smesh.CreateHypothesis( "NETGEN_3D", "libNETGENEngine.so" )
+listHyp = algoNg.GetCompatibleHypothesis()
for hyp in listHyp:
print hyp
-algoNg = alg3D._narrow( SMESH.SMESH_NETGEN_3D )
print algoNg.GetName()
print algoNg.GetId()
-idNg = smeshgui.AddNewAlgorithms( salome.orb.object_to_string(algoNg) )
-smeshgui.SetName( idNg, "NETGEN_2D" )
+smeshgui.SetName(salome.ObjectToID(algoNg), "NETGEN_3D" )
print "-------------------------- add hypothesis to main mechanic"
shape_mesh = salome.IDToObject( idMechanic )
-submesh = mesh.GetElementsOnShape( shape_mesh )
-
-ret = mesh.AddHypothesis( shape_mesh, algoReg1D ) # Regular 1D/wire discretisation
-print ret
-ret = mesh.AddHypothesis( shape_mesh, algoMef ) # MEFISTO 2D
-print ret
-ret = mesh.AddHypothesis( shape_mesh, algoNg ) # NETGEN 3D
-print ret
-ret = mesh.AddHypothesis( shape_mesh, hypNbSeg ) # nb segments
-print ret
-ret = mesh.AddHypothesis( shape_mesh, hypArea ) # max area
-print ret
-ret = mesh.AddHypothesis( shape_mesh, hypVolume ) # max volume
-print ret
-
-smeshgui.SetAlgorithms( idmesh, idReg1D ); # Regular 1D/wire discretisation
-smeshgui.SetAlgorithms( idmesh, idMef ); # MEFISTO 2D
-smeshgui.SetAlgorithms( idmesh, idNg ); # NETGEN 3D
-smeshgui.SetHypothesis( idmesh, idSeg ); # nb segments
-smeshgui.SetHypothesis( idmesh, idArea ); # max area
-smeshgui.SetHypothesis( idmesh, idVolume ); # max volume
-
-sg.updateObjBrowser(1);
+
+mesh = smesh.CreateMesh(shape_mesh)
+smeshgui.SetName(salome.ObjectToID(mesh), "Mesh_mechanic_tetra" );
+
+mesh.AddHypothesis( shape_mesh, algoReg1D ) # Regular 1D/wire discretisation
+mesh.AddHypothesis( shape_mesh, algoMef ) # MEFISTO 2D
+mesh.AddHypothesis( shape_mesh, algoNg ) # NETGEN 3D
+
+mesh.AddHypothesis( shape_mesh, hypNbSeg ) # nb segments
+mesh.AddHypothesis( shape_mesh, hypArea ) # max area
+mesh.AddHypothesis( shape_mesh, hypVolume ) # max volume
print "-------------------------- compute the mesh of the mechanic piece"
-ret=gen.Compute(mesh,idMechanic)
-print ret
-log=mesh.GetLog(0) # no erase trace
-for linelog in log:
- print linelog
+smesh.Compute(mesh,shape_mesh)
+
+print "Information about the Mesh_mechanic_tetra:"
+print "Number of nodes : ", mesh.NbNodes()
+print "Number of edges : ", mesh.NbEdges()
+print "Number of faces : ", mesh.NbFaces()
+print "Number of triangles : ", mesh.NbTriangles()
+print "Number of volumes: ", mesh.NbVolumes()
+print "Number of tetrahedrons: ", mesh.NbTetras()
+
+salome.sg.updateObjBrowser(1);
-sg.updateObjBrowser(1)
myBuilder = salome.myStudy.NewBuilder()
from geompy import gg
-smeshgui = salome.ImportComponentGUI("SMESH")
-smeshgui.Init(salome.myStudyId);
-
ShapeTypeCompSolid = 1
ShapeTypeSolid = 2
ShapeTypeShell = 3
# File : SMESH_test1.py
# Module : SMESH
-import SMESH
-import smeshpy
import salome
-from salome import sg
-import math
-#import SMESH_BasicHypothesis_idl
-
import geompy
-geom = salome.lcc.FindOrLoadComponent("FactoryServer", "GEOM")
-myBuilder = salome.myStudy.NewBuilder()
-from geompy import gg
+import StdMeshers
-smeshgui = salome.ImportComponentGUI("SMESH")
-smeshgui.Init(salome.myStudyId);
+geom = salome.lcc.FindOrLoadComponent("FactoryServer", "GEOM")
+smesh = salome.lcc.FindOrLoadComponent("FactoryServer", "SMESH")
+
+geom.GetCurrentStudy(salome.myStudy._get_StudyId())
+smesh.SetCurrentStudy(salome.myStudy)
ShapeTypeCompSolid = 1
ShapeTypeSolid = 2
print name
idedge=geompy.addToStudyInFather(face,edge,name)
-# ---- launch SMESH, init a Mesh with the box
-gen=smeshpy.smeshpy()
-mesh=gen.Init(idbox)
-
-idmesh = smeshgui.AddNewMesh( salome.orb.object_to_string(mesh) )
-smeshgui.SetName(idmesh, "Meshbox");
-smeshgui.SetShape(idbox, idmesh);
+# ---- launch SMESH
+smeshgui = salome.ImportComponentGUI("SMESH")
+smeshgui.Init(salome.myStudyId);
# ---- create Hypothesis
print "-------------------------- create Hypothesis"
print "-------------------------- LocalLength"
-hyp1=gen.CreateHypothesis("LocalLength")
-hypLen1 = hyp1._narrow(SMESH.SMESH_LocalLength)
+
+hypLen1 = smesh.CreateHypothesis("LocalLength", "libStdMeshersEngine.so")
hypLen1.SetLength(100)
print hypLen1.GetName()
print hypLen1.GetId()
print hypLen1.GetLength()
-idlength = smeshgui.AddNewHypothesis( salome.orb.object_to_string(hypLen1) );
+idlength = salome.ObjectToID(hypLen1)
smeshgui.SetName(idlength, "Local_Length_100");
print "-------------------------- NumberOfSegments"
-hyp2=gen.CreateHypothesis("NumberOfSegments")
-hypNbSeg1=hyp2._narrow(SMESH.SMESH_NumberOfSegments)
+hypNbSeg1 = smesh.CreateHypothesis("NumberOfSegments", "libStdMeshersEngine.so")
hypNbSeg1.SetNumberOfSegments(7)
print hypNbSeg1.GetName()
print hypNbSeg1.GetId()
print hypNbSeg1.GetNumberOfSegments()
-idseg = smeshgui.AddNewHypothesis( salome.orb.object_to_string(hypNbSeg1) );
+idseg = salome.ObjectToID(hypNbSeg1)
smeshgui.SetName(idseg, "NumberOfSegments_7");
print "-------------------------- MaxElementArea"
-hyp3=gen.CreateHypothesis("MaxElementArea")
-hypArea1=hyp3._narrow(SMESH.SMESH_MaxElementArea)
+hypArea1 = smesh.CreateHypothesis("MaxElementArea", "libStdMeshersEngine.so")
hypArea1.SetMaxElementArea(2500)
print hypArea1.GetName()
print hypArea1.GetId()
print hypArea1.GetMaxElementArea()
-idarea1 = smeshgui.AddNewHypothesis( salome.orb.object_to_string(hypArea1) );
+idarea1 = salome.ObjectToID(hypArea1)
smeshgui.SetName(idarea1, "MaxElementArea_2500");
print "-------------------------- MaxElementArea"
-hyp3=gen.CreateHypothesis("MaxElementArea")
-hypArea2=hyp3._narrow(SMESH.SMESH_MaxElementArea)
+hypArea2 = smesh.CreateHypothesis("MaxElementArea", "libStdMeshersEngine.so")
hypArea2.SetMaxElementArea(500)
print hypArea2.GetName()
print hypArea2.GetId()
print hypArea2.GetMaxElementArea()
-idarea2 = smeshgui.AddNewHypothesis( salome.orb.object_to_string(hypArea2) );
+idarea2 = salome.ObjectToID(hypArea2)
smeshgui.SetName(idarea2, "MaxElementArea_500");
print "-------------------------- Regular_1D"
-alg1=gen.CreateHypothesis("Regular_1D")
-algo1=alg1._narrow(SMESH.SMESH_Algo)
-listHyp=algo1.GetCompatibleHypothesis()
+algoReg = smesh.CreateHypothesis("Regular_1D", "libStdMeshersEngine.so")
+listHyp=algoReg.GetCompatibleHypothesis()
for hyp in listHyp:
print hyp
-algoReg=alg1._narrow(SMESH.SMESH_Regular_1D)
print algoReg.GetName()
print algoReg.GetId()
-idreg = smeshgui.AddNewAlgorithms( salome.orb.object_to_string(algoReg) );
+idreg = salome.ObjectToID(algoReg)
smeshgui.SetName(idreg, "Regular_1D");
print "-------------------------- MEFISTO_2D"
-alg2=gen.CreateHypothesis("MEFISTO_2D")
-algo2=alg2._narrow(SMESH.SMESH_Algo)
-listHyp=algo2.GetCompatibleHypothesis()
+algoMef = smesh.CreateHypothesis("MEFISTO_2D", "libStdMeshersEngine.so")
+listHyp=algoMef.GetCompatibleHypothesis()
for hyp in listHyp:
print hyp
-algoMef=alg2._narrow(SMESH.SMESH_MEFISTO_2D)
print algoMef.GetName()
print algoMef.GetId()
-idmef = smeshgui.AddNewAlgorithms( salome.orb.object_to_string(algoMef) );
+idmef = salome.ObjectToID(algoMef)
smeshgui.SetName(idmef, "MEFISTO_2D");
+# ---- Init a Mesh with the box
+
+box=salome.IDToObject(idbox)
+mesh=smesh.CreateMesh(box)
+
+idmesh = salome.ObjectToID(mesh)
+smeshgui.SetName(idmesh, "Meshbox");
+
+# ---- add hypothesis to box
+print "-------------------------- add hypothesis to box"
+mesh.AddHypothesis(box,algoReg)
+mesh.AddHypothesis(box,hypNbSeg1)
+mesh.AddHypothesis(box,algoMef)
+mesh.AddHypothesis(box,hypArea1)
+
# ---- add hypothesis to edge
print "-------------------------- add hypothesis to edge"
edge=salome.IDToObject(idedge)
-submesh=mesh.GetElementsOnShape(edge)
-ret=mesh.AddHypothesis(edge,algoReg)
-print ret
-ret=mesh.AddHypothesis(edge,hypLen1)
-print ret
-
-idsm1 = smeshgui.AddSubMeshOnShape( idmesh,
- idedge,
- salome.orb.object_to_string(submesh),
- ShapeTypeEdge )
-smeshgui.SetName(idsm1, "SubMeshEdge")
-smeshgui.SetAlgorithms( idsm1, idreg );
-smeshgui.SetHypothesis( idsm1, idlength );
+submesh = mesh.GetSubMesh(edge, "SubMeshEdge")
+mesh.AddHypothesis(edge , algoReg)
+mesh.AddHypothesis(edge, hypLen1)
print "-------------------------- add hypothesis to face"
-face=salome.IDToObject(idface)
-submesh=mesh.GetElementsOnShape(face)
-ret=mesh.AddHypothesis(face,hypArea2)
-print ret
-
-idsm2 = smeshgui.AddSubMeshOnShape( idmesh,
- idface,
- salome.orb.object_to_string(submesh),
- ShapeTypeFace )
-smeshgui.SetName(idsm2, "SubMeshFace")
-smeshgui.SetHypothesis( idsm2, idarea2 );
-
-# ---- add hypothesis to box
+face = salome.IDToObject(idface)
+submesh =mesh.GetSubMesh(face, "SubMeshFace")
+mesh.AddHypothesis(face,hypArea2)
-print "-------------------------- add hypothesis to box"
-box=salome.IDToObject(idbox)
-submesh=mesh.GetElementsOnShape(box)
-ret=mesh.AddHypothesis(box,algoReg)
-print ret
-ret=mesh.AddHypothesis(box,hypNbSeg1)
-print ret
-ret=mesh.AddHypothesis(box,algoMef)
-print ret
-ret=mesh.AddHypothesis(box,hypArea1)
-print ret
-
-smeshgui.SetAlgorithms( idmesh, idreg );
-smeshgui.SetHypothesis( idmesh, idseg );
-smeshgui.SetAlgorithms( idmesh, idmef );
-smeshgui.SetHypothesis( idmesh, idarea1 );
-
-sg.updateObjBrowser(1);
+salome.sg.updateObjBrowser(1);
# ---- compute box
print "-------------------------- compute box"
-ret=gen.Compute(mesh,idbox)
+ret=smesh.Compute(mesh,box)
print ret
log=mesh.GetLog(0); # no erase trace
for linelog in log:
print linelog
-sg.updateObjBrowser(1);
+salome.sg.updateObjBrowser(1);
# ---- compute edge
myBuilder = salome.myStudy.NewBuilder()
from geompy import gg
-smeshgui = salome.ImportComponentGUI("SMESH")
-smeshgui.Init(salome.myStudyId);
-
ShapeTypeCompSolid = 1
ShapeTypeSolid = 2
ShapeTypeShell = 3
--- /dev/null
+import salome
+from geompy import gg
+import geompy
+import SMESH
+
+import StdMeshers
+
+ShapeTypeCompSolid = 1
+ShapeTypeSolid = 2
+ShapeTypeShell = 3
+ShapeTypeFace = 4
+ShapeTypeWire = 5
+ShapeTypeEdge = 6
+ShapeTypeVertex = 7
+
+geom = salome.lcc.FindOrLoadComponent("FactoryServer", "GEOM")
+smesh = salome.lcc.FindOrLoadComponent("FactoryServer", "SMESH")
+
+geom.GetCurrentStudy(salome.myStudy._get_StudyId())
+smesh.SetCurrentStudy(salome.myStudy)
+
+box = geompy.MakeBox(0., 0., 0., 100., 200., 300.)
+idbox = geompy.addToStudy(box,"box")
+
+subShapeList = geompy.SubShapeAll(box,ShapeTypeFace)
+face = subShapeList[0]
+name = geompy.SubShapeName( face._get_Name(), box._get_Name() )
+idface = geompy.addToStudyInFather(box,face,name)
+
+box = salome.IDToObject(idbox)
+face = salome.IDToObject(idface)
+
+hyp1 = smesh.CreateHypothesis("NumberOfSegments", "libStdMeshersEngine.so")
+hyp1.SetNumberOfSegments(10)
+hyp2 = smesh.CreateHypothesis("MaxElementArea", "libStdMeshersEngine.so")
+hyp2.SetMaxElementArea(10)
+hyp3 = smesh.CreateHypothesis("MaxElementArea", "libStdMeshersEngine.so")
+hyp3.SetMaxElementArea(100)
+
+algo1 = smesh.CreateHypothesis("Regular_1D", "libStdMeshersEngine.so")
+algo2 = smesh.CreateHypothesis("MEFISTO_2D", "libStdMeshersEngine.so")
+
+mesh = smesh.CreateMesh(box)
+mesh.AddHypothesis(box,hyp1)
+mesh.AddHypothesis(box,hyp2)
+mesh.AddHypothesis(box,algo1)
+mesh.AddHypothesis(box,algo2)
+
+submesh = mesh.GetSubMesh(face, "SubMeshFace")
+mesh.AddHypothesis(face,hyp1)
+mesh.AddHypothesis(face,hyp3)
+mesh.AddHypothesis(face,algo1)
+mesh.AddHypothesis(face,algo2)
+
+smesh.Compute(mesh,box)
+
+faces = submesh.GetElementsByType(SMESH.FACE)
+if len(faces) > 1:
+ print len(faces), len(faces)/2
+ group1 = mesh.CreateGroup(SMESH.FACE,"Group of faces")
+ group2 = mesh.CreateGroup(SMESH.FACE,"Another group of faces")
+ group1.Add(faces[:int(len(faces)/2)])
+ group2.Add(faces[int(len(faces)/2):])
+
+salome.sg.updateObjBrowser(1)
--- /dev/null
+# Copyright (C) 2003 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
+# CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
+#
+# This library 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.
+#
+# This library 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 this library; if not, write to the Free Software
+# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+#
+# See http://www.opencascade.org/SALOME/ or email : webmaster.salome@opencascade.org
+#
+#
+#
+# File : SMESH_test1.py
+# Module : SMESH
+
+import salome
+import SMESH
+import SALOMEDS
+import CORBA
+import os
+import os.path
+
+def SetSObjName(theSObj,theName) :
+ ok, anAttr = theSObj.FindAttribute("AttributeName")
+ if ok:
+ aName = anAttr._narrow(SALOMEDS.AttributeName)
+ #print aName.__dict__
+ aName.SetValue(theName)
+
+def ConvertMED2UNV(thePath,theFile) :
+ anInitFileName = thePath + theFile
+ aMeshes,aResult = smesh.CreateMeshesFromMED(anInitFileName)
+ print aResult, aMeshes
+
+ for iMesh in range(len(aMeshes)) :
+ aMesh = aMeshes[iMesh]
+ anSObj = salome.ObjectToSObject(aMesh)
+ print anSObj.GetName(),
+ aFileName = anInitFileName
+ aFileName = os.path.basename(aFileName)
+ SetSObjName(anSObj,aFileName)
+ print anSObj.GetName()
+
+ aFileName = thePath + theFile + "." + str(iMesh) + ".unv"
+ aMesh.ExportUNV(aFileName)
+ aMesh = smesh.CreateMeshesFromUNV(aFileName)
+ anSObj = salome.ObjectToSObject(aMesh)
+ print anSObj.GetName(),
+ os.remove(aFileName)
+ aFileName = os.path.basename(aFileName)
+ SetSObjName(anSObj,aFileName)
+ print anSObj.GetName()
+
+smesh = salome.lcc.FindOrLoadComponent("FactoryServer", "SMESH")
+smesh.SetCurrentStudy(salome.myStudy)
+
+aPath = os.getenv('KERNEL_ROOT_DIR') + '/examples/'
+aListDir = os.listdir(aPath)
+print aListDir
+
+for iFile in range(len(aListDir)) :
+ aFileName = aListDir[iFile];
+ aName,anExt = os.path.splitext(aFileName)
+ if anExt == ".med" :
+ aFileName = os.path.basename(aFileName)
+ print aFileName
+ ConvertMED2UNV(aPath,aFileName)
+ #break
+
+salome.sg.updateObjBrowser(1);
--- /dev/null
+import os
+import re
+
+import batchmode_salome
+import batchmode_geompy
+import batchmode_smesh
+
+geom = batchmode_geompy.geom
+smesh = batchmode_smesh.smesh
+
+geom.GetCurrentStudy(batchmode_salome.myStudyId)
+smesh.SetCurrentStudy(batchmode_salome.myStudy)
+
+ShapeType = batchmode_smesh.ShapeType
+
+import StdMeshers
+
+def CreateMesh (theFileName, area, len = None, nbseg = None):
+
+ if not(os.path.isfile(theFileName)) or re.search("\.brep$", theFileName) is None :
+ print "Incorrect file name !"
+ return
+
+ if (len is None) and (nbseg is None):
+ print "Define length or number of segments !"
+ return
+
+ if (len is not None) and (nbseg is not None):
+ print "Only one Hypothesis (from length and number of segments) can be defined !"
+ return
+
+
+ # ---- Import shape from BREP file and add it to the study
+ shape_mesh = geom.ImportBREP(theFileName)
+ Id_shape = batchmode_geompy.addToStudy( shape_mesh, "shape_mesh")
+
+
+
+ # ---- SMESH
+
+ # ---- create Hypothesis
+
+ print "-------------------------- create Hypothesis"
+ if (len is not None):
+ print "-------------------------- LocalLength"
+ hypLength1 = smesh.CreateHypothesis("LocalLength", "libStdMeshersEngine.so")
+ hypLength1.SetLength(len)
+ print "Hypothesis type: ", hypLength1.GetName()
+ print "Hypothesis ID: ", hypLength1.GetId()
+ print "Hypothesis Value: ", hypLength1.GetLength()
+
+ if (nbseg is not None):
+ print "-------------------------- NumberOfSegments"
+ hypNbSeg1 = smesh.CreateHypothesis("NumberOfSegments", "libStdMeshersEngine.so")
+ hypNbSeg1.SetNumberOfSegments(nbseg)
+ print "Hypothesis type: ", hypNbSeg1.GetName()
+ print "Hypothesis ID: ", hypNbSeg1.GetId()
+ print "Hypothesis Value: ", hypNbSeg1.GetNumberOfSegments()
+
+
+ if (area == "LengthFromEdges"):
+ print "-------------------------- LengthFromEdges"
+ hypLengthFromEdges = smesh.CreateHypothesis("LengthFromEdges", "libStdMeshersEngine.so")
+ hypLengthFromEdges.SetMode(1)
+ print "Hypothesis type: ", hypLengthFromEdges.GetName()
+ print "Hypothesis ID: ", hypLengthFromEdges.GetId()
+ print "LengthFromEdges Mode: ", hypLengthFromEdges.GetMode()
+
+ else:
+ print "-------------------------- MaxElementArea"
+ hypArea1 = smesh.CreateHypothesis("MaxElementArea", "libStdMeshersEngine.so")
+ hypArea1.SetMaxElementArea(area)
+ print "Hypothesis type: ", hypArea1.GetName()
+ print "Hypothesis ID: ", hypArea1.GetId()
+ print "Hypothesis Value: ", hypArea1.GetMaxElementArea()
+
+
+
+ print "-------------------------- Regular_1D"
+ algoReg = smesh.CreateHypothesis("Regular_1D", "libStdMeshersEngine.so")
+
+ listHyp = algoReg.GetCompatibleHypothesis()
+ for hyp in listHyp:
+ print hyp
+
+ print "Algo name: ", algoReg.GetName()
+ print "Algo ID: ", algoReg.GetId()
+
+ print "-------------------------- MEFISTO_2D"
+ algoMef = smesh.CreateHypothesis("MEFISTO_2D", "libStdMeshersEngine.so")
+
+ listHyp=algoMef.GetCompatibleHypothesis()
+ for hyp in listHyp:
+ print hyp
+
+ print "Algo name: ", algoMef.GetName()
+ print "Algo ID: ", algoMef.GetId()
+
+
+
+ # ---- add hypothesis to shape
+
+ print "-------------------------- add hypothesis to shape"
+ mesh = smesh.CreateMesh(shape_mesh)
+
+ ret = mesh.AddHypothesis(shape_mesh, algoReg)
+ print "Add Regular_1D algo .... ",
+ print ret
+
+ if (nbseg is not None):
+ ret=mesh.AddHypothesis(shape_mesh, hypNbSeg1)
+ print "Add Number Of Segements algo .... ",
+ print ret
+
+ if (len is not None):
+ ret=mesh.AddHypothesis(shape_mesh,hypLength1)
+ print "Add Local Length algo .... ",
+ print ret
+
+ ret=mesh.AddHypothesis(shape_mesh, algoMef)
+ print "Add MEFISTO_2D algo....",
+ print ret
+
+ if (area == "LengthFromEdges"):
+ ret = mesh.AddHypothesis( shape_mesh, hypLengthFromEdges) # length from edge
+ print "Add Length From Edges algo .... ",
+ print ret
+ else:
+ ret=mesh.AddHypothesis(shape_mesh, hypArea1)
+ print "Add Max Triangle Area algo .... ",
+ print ret
+
+ # ---- compute mesh
+
+ print "-------------------------- compute mesh"
+ ret=smesh.Compute(mesh,shape_mesh)
+ print "Compute Mesh .... ",
+ print ret
+ log=mesh.GetLog(0); # no erase trace
+ #for linelog in log:
+ # print linelog
+
+ print "------------ INFORMATION ABOUT MESH ------------"
+
+ print "Number of nodes: ", mesh.NbNodes()
+ print "Number of edges: ", mesh.NbEdges()
+ print "Number of faces: ", mesh.NbFaces()
+ print "Number of triangles: ", mesh.NbTriangles()
+
+ return mesh
father = myStudy.FindComponent("MESH")
if father is None:
father = myStudyBuilder.NewComponent("MESH")
- A1 = myStudyBuilder.FindOrCreateAttribute(father, "AttributeName");
- FName = A1._narrow(SALOMEDS.AttributeName)
- #FName.SetValue("Mesh")
+ FName = myStudyBuilder.FindOrCreateAttribute(father, "AttributeName");
Comp = modulecatalog.GetComponent( "SMESH" )
FName.SetValue( Comp._get_componentusername() )
- A2 = myStudyBuilder.FindOrCreateAttribute(father, "AttributePixMap");
- aPixmap = A2._narrow(SALOMEDS.AttributePixMap);
+ aPixmap = myStudyBuilder.FindOrCreateAttribute(father, "AttributePixMap");
aPixmap.SetPixMap( "ICON_OBJBROWSER_Mesh" );
myStudyBuilder.DefineComponentInstance(father,smesh)
pass
#------------------------------------------------------------
def AddNewMesh(IOR):
+ # VSR: added temporarily - objects are published automatically by the engine
+ aSO = myStudy.FindObjectIOR( IOR )
+ if aSO is not None:
+ return aSO.GetID()
+ # VSR ######################################################################
+
res,HypothesisRoot = mySComponentMesh.FindSubObject ( Tag_HypothesisRoot )
if HypothesisRoot is None or res == 0:
HypothesisRoot = myStudyBuilder.NewObjectToTag(mySComponentMesh, Tag_HypothesisRoot)
- anAttr = myStudyBuilder.FindOrCreateAttribute(HypothesisRoot, "AttributeName")
- aName = anAttr._narrow(SALOMEDS.AttributeName)
- aName.SetValue("Hypothesis Definition")
- anAttr = myStudyBuilder.FindOrCreateAttribute(HypothesisRoot, "AttributePixMap")
- aPixmap = anAttr._narrow(SALOMEDS.AttributePixMap)
+ aName = myStudyBuilder.FindOrCreateAttribute(HypothesisRoot, "AttributeName")
+ aName.SetValue("Hypotheses")
+ aPixmap = myStudyBuilder.FindOrCreateAttribute(HypothesisRoot, "AttributePixMap")
aPixmap.SetPixMap( "mesh_tree_hypo.png" )
- anAttr = myStudyBuilder.FindOrCreateAttribute(HypothesisRoot, "AttributeSelectable")
- aSelAttr = anAttr._narrow(SALOMEDS.AttributeSelectable)
+ aSelAttr = myStudyBuilder.FindOrCreateAttribute(HypothesisRoot, "AttributeSelectable")
aSelAttr.SetSelectable(0);
res, AlgorithmsRoot = mySComponentMesh.FindSubObject (Tag_AlgorithmsRoot)
if AlgorithmsRoot is None or res == 0:
AlgorithmsRoot = myStudyBuilder.NewObjectToTag (mySComponentMesh, Tag_AlgorithmsRoot)
- anAttr = myStudyBuilder.FindOrCreateAttribute(AlgorithmsRoot, "AttributeName")
- aName = anAttr._narrow(SALOMEDS.AttributeName)
- aName.SetValue("Algorithms Definition");
- anAttr = myStudyBuilder.FindOrCreateAttribute(AlgorithmsRoot, "AttributePixMap");
- aPixmap = anAttr._narrow(SALOMEDS.AttributePixMap);
+ aName = myStudyBuilder.FindOrCreateAttribute(AlgorithmsRoot, "AttributeName")
+ aName.SetValue("Algorithms");
+ aPixmap = myStudyBuilder.FindOrCreateAttribute(AlgorithmsRoot, "AttributePixMap");
aPixmap.SetPixMap( "mesh_tree_algo.png" );
- anAttr = myStudyBuilder.FindOrCreateAttribute(AlgorithmsRoot, "AttributeSelectable");
- aSelAttr = anAttr._narrow(SALOMEDS.AttributeSelectable);
+ aSelAttr = myStudyBuilder.FindOrCreateAttribute(AlgorithmsRoot, "AttributeSelectable");
aSelAttr.SetSelectable(0);
HypothesisRoot = HypothesisRoot._narrow(SALOMEDS.SObject)
newMesh = myStudyBuilder.NewObject(mySComponentMesh)
- newMesh = newMesh._narrow(SALOMEDS.SObject)
- anAttr = myStudyBuilder.FindOrCreateAttribute(newMesh, "AttributePixMap")
- aPixmap = anAttr._narrow(SALOMEDS.AttributePixMap)
+ aPixmap = myStudyBuilder.FindOrCreateAttribute(newMesh, "AttributePixMap")
aPixmap.SetPixMap( "mesh_tree_mesh.png" )
- anAttr = myStudyBuilder.FindOrCreateAttribute(newMesh, "AttributeIOR")
- anIOR = anAttr._narrow(SALOMEDS.AttributeIOR)
+ anIOR = myStudyBuilder.FindOrCreateAttribute(newMesh, "AttributeIOR")
anIOR.SetValue(IOR)
return newMesh.GetID()
#------------------------------------------------------------
def AddNewHypothesis(IOR):
+ # VSR: added temporarily - objects are published automatically by the engine
+ aSO = myStudy.FindObjectIOR( IOR )
+ if aSO is not None:
+ return aSO.GetID()
+ # VSR ######################################################################
+
res, HypothesisRoot = mySComponentMesh.FindSubObject (Tag_HypothesisRoot)
if HypothesisRoot is None or res == 0:
HypothesisRoot = myStudyBuilder.NewObjectToTag (mySComponentMesh, Tag_HypothesisRoot)
- anAttr = myStudyBuilder.FindOrCreateAttribute(HypothesisRoot, "AttributeName");
- aName = anAttr._narrow(SALOMEDS.AttributeName);
- aName.SetValue("Hypothesis Definition");
- anAttr = myStudyBuilder.FindOrCreateAttribute(HypothesisRoot, "AttributeSelectable");
- aSelAttr = anAttr._narrow(SALOMEDS.AttributeSelectable);
+ aName = myStudyBuilder.FindOrCreateAttribute(HypothesisRoot, "AttributeName");
+ aName.SetValue("Hypotheses");
+ aSelAttr = myStudyBuilder.FindOrCreateAttribute(HypothesisRoot, "AttributeSelectable");
aSelAttr.SetSelectable(0);
- anAttr = myStudyBuilder.FindOrCreateAttribute(HypothesisRoot, "AttributePixMap");
- aPixmap = anAttr._narrow(SALOMEDS.AttributePixMap);
+ aPixmap = myStudyBuilder.FindOrCreateAttribute(HypothesisRoot, "AttributePixMap");
aPixmap.SetPixMap( "mesh_tree_hypo.png" );
# Add New Hypothesis
newHypo = myStudyBuilder.NewObject(HypothesisRoot)
- newHypo = newHypo._narrow(SALOMEDS.SObject)
- anAttr = myStudyBuilder.FindOrCreateAttribute(newHypo, "AttributePixMap")
- aPixmap = anAttr._narrow(SALOMEDS.AttributePixMap)
+ aPixmap = myStudyBuilder.FindOrCreateAttribute(newHypo, "AttributePixMap")
H = orb.string_to_object(IOR)
- H = H._narrow( SMESH.SMESH_Hypothesis );
aType = H.GetName();
aPixmap.SetPixMap( "mesh_tree_hypo.png_" + aType );
- anAttr = myStudyBuilder.FindOrCreateAttribute(newHypo, "AttributeIOR");
- anIOR = anAttr._narrow(SALOMEDS.AttributeIOR);
+ anIOR = myStudyBuilder.FindOrCreateAttribute(newHypo, "AttributeIOR");
anIOR.SetValue(IOR);
return newHypo.GetID();
#------------------------------------------------------------
def AddNewAlgorithms(IOR):
+ # VSR: added temporarily - objects are published automatically by the engine
+ aSO = myStudy.FindObjectIOR( IOR )
+ if aSO is not None:
+ return aSO.GetID()
+ # VSR ######################################################################
+
res, AlgorithmsRoot = mySComponentMesh.FindSubObject (Tag_AlgorithmsRoot)
if AlgorithmsRoot is None or res == 0:
AlgorithmsRoot = myStudyBuilde.NewObjectToTag (mySComponentMesh, Tag_AlgorithmsRoot)
- anAttr = myStudyBuilder.FindOrCreateAttribute(AlgorithmsRoot, "AttributeName")
- aName = anAttr._narrow(SALOMEDS.AttributeName);
- aName.SetValue("Algorithms Definition");
- anAttr = myStudyBuilder.FindOrCreateAttribute(AlgorithmsRoot, "AttributeSelectable")
- aSelAttr = anAttr._narrow(SALOMEDS.AttributeSelectable);
+ aName = myStudyBuilder.FindOrCreateAttribute(AlgorithmsRoot, "AttributeName")
+ aName.SetValue("Algorithms");
+ aSelAttr = myStudyBuilder.FindOrCreateAttribute(AlgorithmsRoot, "AttributeSelectable")
aSelAttr.SetSelectable(0);
- anAttr = myStudyBuilder.FindOrCreateAttribute(AlgorithmsRoot, "AttributePixMap");
- aPixmap = anAttr._narrow(SALOMEDS.AttributePixMap);
+ aPixmap = myStudyBuilder.FindOrCreateAttribute(AlgorithmsRoot, "AttributePixMap");
aPixmap.SetPixMap( "mesh_tree_algo.png" );
# Add New Algorithms
newHypo = myStudyBuilder.NewObject(AlgorithmsRoot)
- newHypo = newHypo._narrow(SALOMEDS.SObject)
- anAttr = myStudyBuilder.FindOrCreateAttribute(newHypo, "AttributePixMap");
+ aPixmap = myStudyBuilder.FindOrCreateAttribute(newHypo, "AttributePixMap");
aPixmap = anAttr._narrow(SALOMEDS.AttributePixMap);
H = orb.string_to_object(IOR)
- H = H._narrow( SMESH.SMESH_Hypothesis);
aType = H.GetName(); #QString in fact
aPixmap.SetPixMap( "mesh_tree_algo.png_" + aType );
- anAttr = myStudyBuilder.FindOrCreateAttribute(newHypo, "AttributeIOR");
- anIOR = anAttr._narrow(SALOMEDS.AttributeIOR);
+ anIOR = myStudyBuilder.FindOrCreateAttribute(newHypo, "AttributeIOR");
anIOR.SetValue(IOR);
return newHypo.GetID();
#------------------------------------------------------------
def SetShape(ShapeEntry, MeshEntry):
-
SO_MorSM = myStudy.FindObjectID( MeshEntry )
- SO_MorSM = SO_MorSM._narrow(SALOMEDS.SObject)
SO_GeomShape = myStudy.FindObjectID( ShapeEntry );
- SO_GeomShape = SO_GeomShape._narrow(SALOMEDS.SObject)
if SO_MorSM is not None and SO_GeomShape is not None :
+ # VSR: added temporarily - shape reference is published automatically by the engine
+ res, Ref = SO_MorSM.FindSubObject( Tag_RefOnShape );
+ if res == 1 :
+ return;
+ # VSR ######################################################################
+
SO = myStudyBuilder.NewObjectToTag (SO_MorSM, Tag_RefOnShape);
- SO = SO._narrow(SALOMEDS.SObject)
myStudyBuilder.Addreference (SO,SO_GeomShape);
res, AHR = SO_MorSM.FindSubObject (Tag_RefOnAppliedHypothesis)
if AHR is None or res == 0:
AHR = myStudyBuilder.NewObjectToTag (SO_MorSM, Tag_RefOnAppliedHypothesis);
- anAttr = myStudyBuilder.FindOrCreateAttribute(AHR, "AttributeName");
- aName = anAttr._narrow(SALOMEDS.AttributeName);
- aName.SetValue("Applied Hypothesis");
- anAttr = myStudyBuilder.FindOrCreateAttribute(AHR, "AttributeSelectable");
- aSelAttr = anAttr._narrow(SALOMEDS.AttributeSelectable);
+ aName = myStudyBuilder.FindOrCreateAttribute(AHR, "AttributeName");
+
+ # The same name as in SMESH_Mesh_i::AddHypothesis() ##################
+ aName.SetValue("Applied hypotheses");
+
+ aSelAttr = myStudyBuilder.FindOrCreateAttribute(AHR, "AttributeSelectable");
aSelAttr.SetSelectable(0);
- anAttr = myStudyBuilder.FindOrCreateAttribute(AHR, "AttributePixMap");
- aPixmap = anAttr._narrow(SALOMEDS.AttributePixMap);
+ aPixmap = myStudyBuilder.FindOrCreateAttribute(AHR, "AttributePixMap");
aPixmap.SetPixMap( "mesh_tree_hypo.png" );
-
- SO = myStudyBuilder.NewObject(AHR);
- SO = SO._narrow(SALOMEDS.SObject)
- myStudyBuilder.Addreference (SO,SO_Hypothesis);
+
+ # VSR: added temporarily - reference to applied hypothesis is published automatically by the engine
+ else :
+ it = myStudy.NewChildIterator(AHR);
+ while it.More() :
+ res, Ref = it.Value().ReferencedObject();
+ if res and Ref is not None and Ref.GetID() == Hypothesis_Entry :
+ return;
+ it.Next();
+ # VSR ######################################################################
+
+ SO = myStudyBuilder.NewObject(AHR);
+ myStudyBuilder.Addreference (SO,SO_Hypothesis);
#------------------------------------------------------------
def SetAlgorithms(Mesh_Or_SubMesh_Entry, Algorithms_Entry):
res, AHR = SO_MorSM.FindSubObject (Tag_RefOnAppliedAlgorithms);
if AHR is None or res == 0:
AHR = myStudyBuilder.NewObjectToTag (SO_MorSM, Tag_RefOnAppliedAlgorithms);
- anAttr = myStudyBuilder.FindOrCreateAttribute(AHR, "AttributeName");
- aName = anAttr._narrow(SALOMEDS.AttributeName);
- aName.SetValue("Applied Algorithm");
- anAttr = myStudyBuilder.FindOrCreateAttribute(AHR, "AttributeSelectable");
- aSelAttr = anAttr._narrow(SALOMEDS.AttributeSelectable);
+ aName = myStudyBuilder.FindOrCreateAttribute(AHR, "AttributeName");
+
+ # The same name as in SMESH_Mesh_i::AddHypothesis() ##################
+ aName.SetValue("Applied algorithms");
+
+ aSelAttr = myStudyBuilder.FindOrCreateAttribute(AHR, "AttributeSelectable");
aSelAttr.SetSelectable(0);
- anAttr = myStudyBuilder.FindOrCreateAttribute(AHR, "AttributePixMap");
- aPixmap = anAttr._narrow(SALOMEDS.AttributePixMap);
+ aPixmap = myStudyBuilder.FindOrCreateAttribute(AHR, "AttributePixMap");
aPixmap.SetPixMap( "mesh_tree_algo.png" );
-
+
+ # VSR: added temporarily - reference to applied hypothesis is published automatically by the engine
+ else :
+ it = myStudy.NewChildIterator(AHR);
+ while it.More() :
+ res, Ref = it.Value().ReferencedObject();
+ if res and Ref is not None and Ref.GetID() == Algorithms_Entry :
+ return;
+ it.Next();
+ # VSR ######################################################################
+
SO = myStudyBuilder.NewObject(AHR);
myStudyBuilder.Addreference (SO,SO_Algorithms);
#------------------------------------------------------------
def AddSubMesh ( SO_Mesh_Entry, SM_IOR, ST):
+ # VSR: added temporarily - objects are published automatically by the engine
+ aSO = myStudy.FindObjectIOR( SM_IOR )
+ if aSO is not None:
+ return aSO.GetID()
+ # VSR ######################################################################
+
SO_Mesh = myStudy.FindObjectID( SO_Mesh_Entry )
if ( SO_Mesh ) :
if ST == ShapeTypeCompSolid :
Tag_Shape = Tag_SubMeshOnSolid;
- Name = "SubMeshes On Solid";
+ Name = "SubMeshes on Solid";
elif ST == ShapeTypeFace :
Tag_Shape = Tag_SubMeshOnFace;
- Name = "SubMeshes On Face";
+ Name = "SubMeshes on Face";
elif ST == ShapeTypeEdge :
Tag_Shape = Tag_SubMeshOnEdge;
- Name = "SubMeshes On Edge";
+ Name = "SubMeshes on Edge";
elif ST == ShapeTypeVertex :
Tag_Shape = Tag_SubMeshOnVertex;
- Name = "SubMeshes On Vertex";
+ Name = "SubMeshes on Vertex";
else :
Tag_Shape = Tag_SubMeshOnCompound;
- Name = "SubMeshes On Compound";
+ Name = "SubMeshes on Compound";
res, SubmeshesRoot = SO_Mesh.FindSubObject (Tag_Shape)
if SubmeshesRoot is None or res == 0:
SubmeshesRoot = myStudyBuilder.NewObjectToTag (SO_Mesh, Tag_Shape);
- anAttr = myStudyBuilder.FindOrCreateAttribute(SubmeshesRoot, "AttributeName");
-
- aName = anAttr._narrow(SALOMEDS.AttributeName);
+ aName = myStudyBuilder.FindOrCreateAttribute(SubmeshesRoot, "AttributeName");
aName.SetValue(Name);
- anAttr = myStudyBuilder.FindOrCreateAttribute(SubmeshesRoot, "AttributeSelectable");
- aSelAttr = anAttr._narrow(SALOMEDS.AttributeSelectable);
+ aSelAttr = myStudyBuilder.FindOrCreateAttribute(SubmeshesRoot, "AttributeSelectable");
aSelAttr.SetSelectable(0);
SO = myStudyBuilder.NewObject (SubmeshesRoot);
- SO = SO._narrow(SALOMEDS.SObject)
- anAttr = myStudyBuilder.FindOrCreateAttribute(SO, "AttributeIOR");
- anIOR = anAttr._narrow(SALOMEDS.AttributeIOR);
+ anIOR = myStudyBuilder.FindOrCreateAttribute(SO, "AttributeIOR");
anIOR.SetValue(SM_IOR);
return SO.GetID();
#------------------------------------------------------------
def AddSubMeshOnShape (Mesh_Entry, GeomShape_Entry, SM_IOR, ST) :
- SO_GeomShape = myStudy.FindObjectID( GeomShape_Entry );
- if SO_GeomShape != None :
- SM_Entry = AddSubMesh (Mesh_Entry,SM_IOR,ST);
- SO_SM = myStudy.FindObjectID( SM_Entry );
-
- if SO_SM != None :
- SetShape (GeomShape_Entry, SM_Entry);
- return SO_SM.GetID();
+ # VSR: added temporarily - objects are published automatically by the engine
+ aSO = myStudy.FindObjectIOR( SM_IOR )
+ if aSO is not None:
+ return aSO.GetID()
+ # VSR ######################################################################
+ SO_GeomShape = myStudy.FindObjectID( GeomShape_Entry );
+ if SO_GeomShape != None :
+ SM_Entry = AddSubMesh (Mesh_Entry,SM_IOR,ST);
+ SO_SM = myStudy.FindObjectID( SM_Entry );
+
+ if SO_SM != None :
+ SetShape (GeomShape_Entry, SM_Entry);
+ return SM_Entry;
- return None;
+ return None;
#------------------------------------------------------------
def SetName(Entry, Name):
SO = myStudy.FindObjectID( Entry );
if SO != None :
- anAttr = myStudyBuilder.FindOrCreateAttribute(SO, "AttributeName");
- aName = anAttr._narrow(SALOMEDS.AttributeName);
+ aName = myStudyBuilder.FindOrCreateAttribute(SO, "AttributeName");
aName.SetValue(Name);
--- /dev/null
+# SMESH StdMeshers : implementaion of SMESH idl descriptions
+#
+# Copyright (C) 2003 CEA
+#
+# This library 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.
+#
+# This library 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 this library; if not, write to the Free Software
+# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+#
+# See http://www.salome-platform.org or email : webmaster.salome@opencascade.org
+#
+#
+#
+# File : Makefile.in
+# Author : Julia DOROVSKIKH
+# Module : SMESH
+# $Header$
+
+top_srcdir=@top_srcdir@
+top_builddir=../..
+srcdir=@srcdir@
+VPATH=.:@srcdir@:@top_srcdir@/idl:$(top_builddir)/idl
+
+
+@COMMENCE@
+
+# header files
+EXPORT_HEADERS = \
+ StdMeshers_LengthFromEdges.hxx \
+ StdMeshers_LocalLength.hxx \
+ StdMeshers_NumberOfSegments.hxx \
+ StdMeshers_MaxElementArea.hxx \
+ StdMeshers_MaxElementVolume.hxx \
+ StdMeshers_NotConformAllowed.hxx \
+ StdMeshers_Regular_1D.hxx \
+ StdMeshers_Quadrangle_2D.hxx \
+ StdMeshers_MEFISTO_2D.hxx \
+ StdMeshers_Hexa_3D.hxx
+
+EXPORT_PYSCRIPTS =
+
+# Libraries targets
+
+LIB = libStdMeshers.la
+
+LIB_SRC = \
+ StdMeshers_LengthFromEdges.cxx \
+ StdMeshers_LocalLength.cxx \
+ StdMeshers_MaxElementArea.cxx \
+ StdMeshers_MaxElementVolume.cxx \
+ StdMeshers_NumberOfSegments.cxx \
+ StdMeshers_NotConformAllowed.cxx \
+ StdMeshers_Regular_1D.cxx \
+ StdMeshers_Quadrangle_2D.cxx \
+ StdMeshers_MEFISTO_2D.cxx \
+ StdMeshers_Hexa_3D.cxx
+
+LIB_SERVER_IDL =
+
+LIB_CLIENT_IDL =
+
+# Executables targets
+BIN =
+BIN_SRC =
+
+# additionnal information to compil and link file
+CPPFLAGS+= $(OCC_INCLUDES) -I${KERNEL_ROOT_DIR}/include/salome $(BOOST_CPPFLAGS)
+CXXFLAGS+= $(OCC_CXXFLAGS) -I${KERNEL_ROOT_DIR}/include/salome
+
+LDFLAGS+= -lSMESHimpl -lMEFISTO2D -L${KERNEL_ROOT_DIR}/lib/salome
+
+@CONCLUDE@
--- /dev/null
+// SMESH SMESH : implementaion of SMESH idl descriptions
+//
+// Copyright (C) 2003 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
+// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
+//
+// This library 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.
+//
+// This library 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 this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+//
+// See http://www.opencascade.org/SALOME/ or email : webmaster.salome@opencascade.org
+//
+//
+//
+// File : StdMeshers_Hexa_3D.cxx
+// Moved here from SMESH_Hexa_3D.cxx
+// Author : Paul RASCLE, EDF
+// Module : SMESH
+// $Header$
+
+using namespace std;
+#include "StdMeshers_Hexa_3D.hxx"
+#include "StdMeshers_Quadrangle_2D.hxx"
+#include "SMESH_Gen.hxx"
+#include "SMESH_Mesh.hxx"
+
+#include "SMDS_MeshElement.hxx"
+#include "SMDS_MeshNode.hxx"
+#include "SMDS_FacePosition.hxx"
+
+#include <TopExp.hxx>
+#include <TopTools_IndexedDataMapOfShapeListOfShape.hxx>
+#include <TopTools_ListOfShape.hxx>
+#include <TopTools_ListIteratorOfListOfShape.hxx>
+#include <TColStd_ListIteratorOfListOfInteger.hxx>
+
+#include <BRep_Tool.hxx>
+#include <Geom_Surface.hxx>
+#include <Geom_Curve.hxx>
+#include <Geom2d_Curve.hxx>
+#include <Handle_Geom2d_Curve.hxx>
+#include <Handle_Geom_Curve.hxx>
+
+#include "utilities.h"
+#include "Utils_ExceptHandlers.hxx"
+
+
+//=============================================================================
+/*!
+ *
+ */
+//=============================================================================
+
+StdMeshers_Hexa_3D::StdMeshers_Hexa_3D(int hypId, int studyId,
+ SMESH_Gen * gen):SMESH_3D_Algo(hypId, studyId, gen)
+{
+ MESSAGE("StdMeshers_Hexa_3D::StdMeshers_Hexa_3D");
+ _name = "Hexa_3D";
+// _shapeType = TopAbs_SOLID;
+ _shapeType = (1 << TopAbs_SHELL) | (1 << TopAbs_SOLID); // 1 bit /shape type
+// MESSAGE("_shapeType octal " << oct << _shapeType);
+ for (int i = 0; i < 6; i++)
+ _quads[i] = 0;
+}
+
+//=============================================================================
+/*!
+ *
+ */
+//=============================================================================
+
+StdMeshers_Hexa_3D::~StdMeshers_Hexa_3D()
+{
+ MESSAGE("StdMeshers_Hexa_3D::~StdMeshers_Hexa_3D");
+}
+
+//=============================================================================
+/*!
+ *
+ */
+//=============================================================================
+
+bool StdMeshers_Hexa_3D::CheckHypothesis
+ (SMESH_Mesh& aMesh,
+ const TopoDS_Shape& aShape,
+ SMESH_Hypothesis::Hypothesis_Status& aStatus)
+{
+ MESSAGE("StdMeshers_Hexa_3D::CheckHypothesis");
+
+ bool isOk = true;
+ aStatus = SMESH_Hypothesis::HYP_OK;
+
+ // nothing to check
+
+ return isOk;
+}
+
+//=============================================================================
+/*!
+ * Hexahedron mesh on hexaedron like form
+ * -0. - shape and face mesh verification
+ * -1. - identify faces and vertices of the "cube"
+ * -2. - Algorithm from:
+ * "Application de l'interpolation transfinie à la création de maillages
+ * C0 ou G1 continus sur des triangles, quadrangles, tetraedres, pentaedres
+ * et hexaedres déformés."
+ * Alain PERONNET - 8 janvier 1999
+ */
+//=============================================================================
+
+bool StdMeshers_Hexa_3D::Compute(SMESH_Mesh & aMesh,
+ const TopoDS_Shape & aShape)throw(SALOME_Exception)
+{
+ Unexpect aCatch(SalomeException);
+ MESSAGE("StdMeshers_Hexa_3D::Compute");
+
+ bool isOk = false;
+ SMESHDS_Mesh * meshDS = aMesh.GetMeshDS();
+ SMESH_subMesh *theSubMesh = aMesh.GetSubMesh(aShape);
+ //const SMESHDS_SubMesh *& subMeshDS = theSubMesh->GetSubMeshDS();
+
+ // 0. - shape and face mesh verification
+ // 0.1 - shape must be a solid (or a shell) with 6 faces
+ MESSAGE("---");
+
+ vector < SMESH_subMesh * >meshFaces;
+ for (TopExp_Explorer exp(aShape, TopAbs_FACE); exp.More(); exp.Next())
+ {
+ SMESH_subMesh *aSubMesh = aMesh.GetSubMeshContaining(exp.Current());
+ ASSERT(aSubMesh);
+ meshFaces.push_back(aSubMesh);
+ }
+ if (meshFaces.size() != 6)
+ {
+ SCRUTE(meshFaces.size());
+ ASSERT(0);
+ return false;
+ }
+
+ // 0.2 - is each face meshed with Quadrangle_2D? (so, with a wire of 4 edges)
+ MESSAGE("---");
+
+ for (int i = 0; i < 6; i++)
+ {
+ TopoDS_Shape aShape = meshFaces[i]->GetSubShape();
+ SMESH_Algo *algo = _gen->GetAlgo(aMesh, aShape);
+ string algoName = algo->GetName();
+ if (algoName != "Quadrangle_2D")
+ {
+ // *** delete _quads
+ SCRUTE(algoName);
+ ASSERT(0);
+ return false;
+ }
+ StdMeshers_Quadrangle_2D *quadAlgo =
+ dynamic_cast < StdMeshers_Quadrangle_2D * >(algo);
+ ASSERT(quadAlgo);
+ try
+ {
+ _quads[i] = quadAlgo->CheckAnd2Dcompute(aMesh, aShape);
+ // *** to delete after usage
+ }
+ catch(SALOME_Exception & S_ex)
+ {
+ // *** delete _quads
+ // *** throw exception
+ ASSERT(0);
+ }
+ }
+
+ // 1. - identify faces and vertices of the "cube"
+ // 1.1 - ancestor maps vertex->edges in the cube
+ MESSAGE("---");
+
+ TopTools_IndexedDataMapOfShapeListOfShape MS;
+ TopExp::MapShapesAndAncestors(aShape, TopAbs_VERTEX, TopAbs_EDGE, MS);
+
+ // 1.2 - first face is choosen as face Y=0 of the unit cube
+ MESSAGE("---");
+
+ const TopoDS_Shape & aFace = meshFaces[0]->GetSubShape();
+ const TopoDS_Face & F = TopoDS::Face(aFace);
+
+ // 1.3 - identify the 4 vertices of the face Y=0: V000, V100, V101, V001
+ MESSAGE("---");
+
+ int i = 0;
+ TopoDS_Edge E = _quads[0]->edge[i]; //edge will be Y=0,Z=0 on unit cube
+ double f, l;
+ Handle(Geom2d_Curve) C2d = BRep_Tool::CurveOnSurface(E, F, f, l);
+ TopoDS_Vertex VFirst, VLast;
+ TopExp::Vertices(E, VFirst, VLast); // corresponds to f and l
+ bool isForward =
+ (((l - f) * (_quads[0]->last[i] - _quads[0]->first[i])) > 0);
+
+ if (isForward)
+ {
+ _cube.V000 = VFirst; // will be (0,0,0) on the unit cube
+ _cube.V100 = VLast; // will be (1,0,0) on the unit cube
+ }
+ else
+ {
+ _cube.V000 = VLast;
+ _cube.V100 = VFirst;
+ }
+
+ i = 1;
+ E = _quads[0]->edge[i];
+ C2d = BRep_Tool::CurveOnSurface(E, F, f, l);
+ TopExp::Vertices(E, VFirst, VLast);
+ isForward = (((l - f) * (_quads[0]->last[i] - _quads[0]->first[i])) > 0);
+ if (isForward)
+ _cube.V101 = VLast; // will be (1,0,1) on the unit cube
+ else
+ _cube.V101 = VFirst;
+
+ i = 2;
+ E = _quads[0]->edge[i];
+ C2d = BRep_Tool::CurveOnSurface(E, F, f, l);
+ TopExp::Vertices(E, VFirst, VLast);
+ isForward = (((l - f) * (_quads[0]->last[i] - _quads[0]->first[i])) > 0);
+ if (isForward)
+ _cube.V001 = VLast; // will be (0,0,1) on the unit cube
+ else
+ _cube.V001 = VFirst;
+
+ // 1.4 - find edge X=0, Z=0 (ancestor of V000 not in face Y=0)
+ // - find edge X=1, Z=0 (ancestor of V100 not in face Y=0)
+ // - find edge X=1, Z=1 (ancestor of V101 not in face Y=0)
+ // - find edge X=0, Z=1 (ancestor of V001 not in face Y=0)
+ MESSAGE("---");
+
+ TopoDS_Edge E_0Y0 = EdgeNotInFace(aMesh, aShape, F, _cube.V000, MS);
+ ASSERT(!E_0Y0.IsNull());
+
+ TopoDS_Edge E_1Y0 = EdgeNotInFace(aMesh, aShape, F, _cube.V100, MS);
+ ASSERT(!E_1Y0.IsNull());
+
+ TopoDS_Edge E_1Y1 = EdgeNotInFace(aMesh, aShape, F, _cube.V101, MS);
+ ASSERT(!E_1Y1.IsNull());
+
+ TopoDS_Edge E_0Y1 = EdgeNotInFace(aMesh, aShape, F, _cube.V001, MS);
+ ASSERT(!E_0Y1.IsNull());
+
+ // 1.5 - identify the 4 vertices in face Y=1: V010, V110, V111, V011
+ MESSAGE("---");
+
+ TopExp::Vertices(E_0Y0, VFirst, VLast);
+ if (VFirst.IsSame(_cube.V000))
+ _cube.V010 = VLast;
+ else
+ _cube.V010 = VFirst;
+
+ TopExp::Vertices(E_1Y0, VFirst, VLast);
+ if (VFirst.IsSame(_cube.V100))
+ _cube.V110 = VLast;
+ else
+ _cube.V110 = VFirst;
+
+ TopExp::Vertices(E_1Y1, VFirst, VLast);
+ if (VFirst.IsSame(_cube.V101))
+ _cube.V111 = VLast;
+ else
+ _cube.V111 = VFirst;
+
+ TopExp::Vertices(E_0Y1, VFirst, VLast);
+ if (VFirst.IsSame(_cube.V001))
+ _cube.V011 = VLast;
+ else
+ _cube.V011 = VFirst;
+
+ // 1.6 - find remaining faces given 4 vertices
+ MESSAGE("---");
+
+ _indY0 = 0;
+ _cube.quad_Y0 = _quads[_indY0];
+
+ _indY1 = GetFaceIndex(aMesh, aShape, meshFaces,
+ _cube.V010, _cube.V011, _cube.V110, _cube.V111);
+ _cube.quad_Y1 = _quads[_indY1];
+
+ _indZ0 = GetFaceIndex(aMesh, aShape, meshFaces,
+ _cube.V000, _cube.V010, _cube.V100, _cube.V110);
+ _cube.quad_Z0 = _quads[_indZ0];
+
+ _indZ1 = GetFaceIndex(aMesh, aShape, meshFaces,
+ _cube.V001, _cube.V011, _cube.V101, _cube.V111);
+ _cube.quad_Z1 = _quads[_indZ1];
+
+ _indX0 = GetFaceIndex(aMesh, aShape, meshFaces,
+ _cube.V000, _cube.V001, _cube.V010, _cube.V011);
+ _cube.quad_X0 = _quads[_indX0];
+
+ _indX1 = GetFaceIndex(aMesh, aShape, meshFaces,
+ _cube.V100, _cube.V101, _cube.V110, _cube.V111);
+ _cube.quad_X1 = _quads[_indX1];
+
+ MESSAGE("---");
+
+ // 1.7 - get convertion coefs from face 2D normalized to 3D normalized
+
+ Conv2DStruct cx0; // for face X=0
+ Conv2DStruct cx1; // for face X=1
+ Conv2DStruct cy0;
+ Conv2DStruct cy1;
+ Conv2DStruct cz0;
+ Conv2DStruct cz1;
+
+ GetConv2DCoefs(*_cube.quad_X0, meshFaces[_indX0]->GetSubShape(),
+ _cube.V000, _cube.V010, _cube.V011, _cube.V001, cx0);
+ GetConv2DCoefs(*_cube.quad_X1, meshFaces[_indX1]->GetSubShape(),
+ _cube.V100, _cube.V110, _cube.V111, _cube.V101, cx1);
+ GetConv2DCoefs(*_cube.quad_Y0, meshFaces[_indY0]->GetSubShape(),
+ _cube.V000, _cube.V100, _cube.V101, _cube.V001, cy0);
+ GetConv2DCoefs(*_cube.quad_Y1, meshFaces[_indY1]->GetSubShape(),
+ _cube.V010, _cube.V110, _cube.V111, _cube.V011, cy1);
+ GetConv2DCoefs(*_cube.quad_Z0, meshFaces[_indZ0]->GetSubShape(),
+ _cube.V000, _cube.V100, _cube.V110, _cube.V010, cz0);
+ GetConv2DCoefs(*_cube.quad_Z1, meshFaces[_indZ1]->GetSubShape(),
+ _cube.V001, _cube.V101, _cube.V111, _cube.V011, cz1);
+
+ // 1.8 - create a 3D structure for normalized values
+
+ MESSAGE("---");
+ int nbx = _cube.quad_Y0->nbPts[0];
+ int nby = _cube.quad_Y0->nbPts[1];
+ int nbz;
+ if (cx0.a1 != 0)
+ nbz = _cube.quad_X0->nbPts[1];
+ else
+ nbz = _cube.quad_X0->nbPts[0];
+ //SCRUTE(nbx);
+ //SCRUTE(nby);
+ //SCRUTE(nbz);
+ int nbxyz = nbx * nby * nbz;
+ Point3DStruct *np = new Point3DStruct[nbxyz];
+
+ // 1.9 - store node indexes of faces
+
+ {
+ const TopoDS_Face & F = TopoDS::Face(meshFaces[_indX0]->GetSubShape());
+
+ faceQuadStruct *quad = _cube.quad_X0;
+ int i = 0; // j = x/face , k = y/face
+ int nbdown = quad->nbPts[0];
+ int nbright = quad->nbPts[1];
+
+
+ SMDS_NodeIteratorPtr itf= aMesh.GetSubMesh(F)->GetSubMeshDS()->GetNodes();
+
+ while(itf->more())
+ {
+ const SMDS_MeshNode * node = itf->next();
+ const SMDS_FacePosition* fpos =
+ static_cast<const SMDS_FacePosition*>(node->GetPosition().get());
+ double ri = fpos->GetUParameter();
+ double rj = fpos->GetVParameter();
+ int i1 = int (ri);
+ int j1 = int (rj);
+ int ij1 = j1 * nbdown + i1;
+ quad->uv_grid[ij1].node = node;
+ }
+
+ for (int i1 = 0; i1 < nbdown; i1++)
+ for (int j1 = 0; j1 < nbright; j1++)
+ {
+ int ij1 = j1 * nbdown + i1;
+ int j = cx0.ia * i1 + cx0.ib * j1 + cx0.ic; // j = x/face
+ int k = cx0.ja * i1 + cx0.jb * j1 + cx0.jc; // k = y/face
+ int ijk = k * nbx * nby + j * nbx + i;
+ //MESSAGE(" "<<ij1<<" "<<i<<" "<<j<<" "<<ijk);
+ np[ijk].node = quad->uv_grid[ij1].node;
+ //SCRUTE(np[ijk].nodeId);
+ }
+ }
+
+ {
+ const TopoDS_Face & F = TopoDS::Face(meshFaces[_indX1]->GetSubShape());
+
+ SMDS_NodeIteratorPtr itf= aMesh.GetSubMesh(F)->GetSubMeshDS()->GetNodes();
+
+ faceQuadStruct *quad = _cube.quad_X1;
+ int i = nbx - 1; // j = x/face , k = y/face
+ int nbdown = quad->nbPts[0];
+ int nbright = quad->nbPts[1];
+
+ while(itf->more())
+ {
+ const SMDS_MeshNode * node = itf->next();
+ const SMDS_FacePosition* fpos =
+ static_cast<const SMDS_FacePosition*>(node->GetPosition().get());
+ double ri = fpos->GetUParameter();
+ double rj = fpos->GetVParameter();
+ int i1 = int (ri);
+ int j1 = int (rj);
+ int ij1 = j1 * nbdown + i1;
+ quad->uv_grid[ij1].node = node;
+ }
+
+ for (int i1 = 0; i1 < nbdown; i1++)
+ for (int j1 = 0; j1 < nbright; j1++)
+ {
+ int ij1 = j1 * nbdown + i1;
+ int j = cx1.ia * i1 + cx1.ib * j1 + cx1.ic; // j = x/face
+ int k = cx1.ja * i1 + cx1.jb * j1 + cx1.jc; // k = y/face
+ int ijk = k * nbx * nby + j * nbx + i;
+ //MESSAGE(" "<<ij1<<" "<<i<<" "<<j<<" "<<ijk);
+ np[ijk].node = quad->uv_grid[ij1].node;
+ //SCRUTE(np[ijk].nodeId);
+ }
+ }
+
+ {
+ const TopoDS_Face & F = TopoDS::Face(meshFaces[_indY0]->GetSubShape());
+
+ SMDS_NodeIteratorPtr itf= aMesh.GetSubMesh(F)->GetSubMeshDS()->GetNodes();
+
+ faceQuadStruct *quad = _cube.quad_Y0;
+ int j = 0; // i = x/face , k = y/face
+ int nbdown = quad->nbPts[0];
+ int nbright = quad->nbPts[1];
+
+ while(itf->more())
+ {
+ const SMDS_MeshNode * node = itf->next();
+ const SMDS_FacePosition * fpos =
+ static_cast<const SMDS_FacePosition*>(node->GetPosition().get());
+ double ri = fpos->GetUParameter();
+ double rj = fpos->GetVParameter();
+ int i1 = int (ri);
+ int j1 = int (rj);
+ int ij1 = j1 * nbdown + i1;
+ quad->uv_grid[ij1].node = node;
+ }
+
+ for (int i1 = 0; i1 < nbdown; i1++)
+ for (int j1 = 0; j1 < nbright; j1++)
+ {
+ int ij1 = j1 * nbdown + i1;
+ int i = cy0.ia * i1 + cy0.ib * j1 + cy0.ic; // i = x/face
+ int k = cy0.ja * i1 + cy0.jb * j1 + cy0.jc; // k = y/face
+ int ijk = k * nbx * nby + j * nbx + i;
+ //MESSAGE(" "<<ij1<<" "<<i<<" "<<j<<" "<<ijk);
+ np[ijk].node = quad->uv_grid[ij1].node;
+ //SCRUTE(np[ijk].nodeId);
+ }
+ }
+
+ {
+ const TopoDS_Face & F = TopoDS::Face(meshFaces[_indY1]->GetSubShape());
+
+ SMDS_NodeIteratorPtr itf= aMesh.GetSubMesh(F)->GetSubMeshDS()->GetNodes();
+
+ faceQuadStruct *quad = _cube.quad_Y1;
+ int j = nby - 1; // i = x/face , k = y/face
+ int nbdown = quad->nbPts[0];
+ int nbright = quad->nbPts[1];
+
+ while(itf->more())
+ {
+ const SMDS_MeshNode * node = itf->next();
+ const SMDS_FacePosition* fpos =
+ static_cast<const SMDS_FacePosition *>(node->GetPosition().get());
+ double ri = fpos->GetUParameter();
+ double rj = fpos->GetVParameter();
+ int i1 = int (ri);
+ int j1 = int (rj);
+ int ij1 = j1 * nbdown + i1;
+ quad->uv_grid[ij1].node = node;
+ }
+
+ for (int i1 = 0; i1 < nbdown; i1++)
+ for (int j1 = 0; j1 < nbright; j1++)
+ {
+ int ij1 = j1 * nbdown + i1;
+ int i = cy1.ia * i1 + cy1.ib * j1 + cy1.ic; // i = x/face
+ int k = cy1.ja * i1 + cy1.jb * j1 + cy1.jc; // k = y/face
+ int ijk = k * nbx * nby + j * nbx + i;
+ //MESSAGE(" "<<ij1<<" "<<i<<" "<<j<<" "<<ijk);
+ np[ijk].node = quad->uv_grid[ij1].node;
+ //SCRUTE(np[ijk].nodeId);
+ }
+ }
+
+ {
+ const TopoDS_Face & F = TopoDS::Face(meshFaces[_indZ0]->GetSubShape());
+
+ SMDS_NodeIteratorPtr itf= aMesh.GetSubMesh(F)->GetSubMeshDS()->GetNodes();
+
+ faceQuadStruct *quad = _cube.quad_Z0;
+ int k = 0; // i = x/face , j = y/face
+ int nbdown = quad->nbPts[0];
+ int nbright = quad->nbPts[1];
+
+ while(itf->more())
+ {
+ const SMDS_MeshNode * node = itf->next();
+ const SMDS_FacePosition * fpos =
+ static_cast<const SMDS_FacePosition*>(node->GetPosition().get());
+ double ri = fpos->GetUParameter();
+ double rj = fpos->GetVParameter();
+ int i1 = int (ri);
+ int j1 = int (rj);
+ int ij1 = j1 * nbdown + i1;
+ quad->uv_grid[ij1].node = node;
+ }
+
+ for (int i1 = 0; i1 < nbdown; i1++)
+ for (int j1 = 0; j1 < nbright; j1++)
+ {
+ int ij1 = j1 * nbdown + i1;
+ int i = cz0.ia * i1 + cz0.ib * j1 + cz0.ic; // i = x/face
+ int j = cz0.ja * i1 + cz0.jb * j1 + cz0.jc; // j = y/face
+ int ijk = k * nbx * nby + j * nbx + i;
+ //MESSAGE(" "<<ij1<<" "<<i<<" "<<j<<" "<<ijk);
+ np[ijk].node = quad->uv_grid[ij1].node;
+ //SCRUTE(np[ijk].nodeId);
+ }
+ }
+
+ {
+ const TopoDS_Face & F = TopoDS::Face(meshFaces[_indZ1]->GetSubShape());
+
+ SMDS_NodeIteratorPtr itf= aMesh.GetSubMesh(F)->GetSubMeshDS()->GetNodes();
+
+ faceQuadStruct *quad = _cube.quad_Z1;
+ int k = nbz - 1; // i = x/face , j = y/face
+ int nbdown = quad->nbPts[0];
+ int nbright = quad->nbPts[1];
+
+ while(itf->more())
+ {
+ const SMDS_MeshNode * node = itf->next();
+ const SMDS_FacePosition* fpos =
+ static_cast<const SMDS_FacePosition*>(node->GetPosition().get());
+ double ri = fpos->GetUParameter();
+ double rj = fpos->GetVParameter();
+ int i1 = int (ri);
+ int j1 = int (rj);
+ int ij1 = j1 * nbdown + i1;
+ quad->uv_grid[ij1].node = node;
+ }
+
+ for (int i1 = 0; i1 < nbdown; i1++)
+ for (int j1 = 0; j1 < nbright; j1++)
+ {
+ int ij1 = j1 * nbdown + i1;
+ int i = cz1.ia * i1 + cz1.ib * j1 + cz1.ic; // i = x/face
+ int j = cz1.ja * i1 + cz1.jb * j1 + cz1.jc; // j = y/face
+ int ijk = k * nbx * nby + j * nbx + i;
+ //MESSAGE(" "<<ij1<<" "<<i<<" "<<j<<" "<<ijk);
+ np[ijk].node = quad->uv_grid[ij1].node;
+ //SCRUTE(np[ijk].nodeId);
+ }
+ }
+
+ // 2.0 - for each node of the cube:
+ // - get the 8 points 3D = 8 vertices of the cube
+ // - get the 12 points 3D on the 12 edges of the cube
+ // - get the 6 points 3D on the 6 faces with their ID
+ // - compute the point 3D
+ // - store the point 3D in SMESHDS, store its ID in 3D structure
+
+ TopoDS_Shell aShell;
+ TopExp_Explorer exp(aShape, TopAbs_SHELL);
+ if (exp.More())
+ {
+ aShell = TopoDS::Shell(exp.Current());
+ }
+ else
+ {
+ MESSAGE("no shell...");
+ ASSERT(0);
+ }
+
+ Pt3 p000, p001, p010, p011, p100, p101, p110, p111;
+ Pt3 px00, px01, px10, px11;
+ Pt3 p0y0, p0y1, p1y0, p1y1;
+ Pt3 p00z, p01z, p10z, p11z;
+ Pt3 pxy0, pxy1, px0z, px1z, p0yz, p1yz;
+
+ GetPoint(p000, 0, 0, 0, nbx, nby, nbz, np, meshDS);
+ GetPoint(p001, 0, 0, nbz - 1, nbx, nby, nbz, np, meshDS);
+ GetPoint(p010, 0, nby - 1, 0, nbx, nby, nbz, np, meshDS);
+ GetPoint(p011, 0, nby - 1, nbz - 1, nbx, nby, nbz, np, meshDS);
+ GetPoint(p100, nbx - 1, 0, 0, nbx, nby, nbz, np, meshDS);
+ GetPoint(p101, nbx - 1, 0, nbz - 1, nbx, nby, nbz, np, meshDS);
+ GetPoint(p110, nbx - 1, nby - 1, 0, nbx, nby, nbz, np, meshDS);
+ GetPoint(p111, nbx - 1, nby - 1, nbz - 1, nbx, nby, nbz, np, meshDS);
+
+ for (int i = 1; i < nbx - 1; i++)
+ {
+ for (int j = 1; j < nby - 1; j++)
+ {
+ for (int k = 1; k < nbz - 1; k++)
+ {
+ // *** seulement maillage regulier
+ // 12 points on edges
+ GetPoint(px00, i, 0, 0, nbx, nby, nbz, np, meshDS);
+ GetPoint(px01, i, 0, nbz - 1, nbx, nby, nbz, np, meshDS);
+ GetPoint(px10, i, nby - 1, 0, nbx, nby, nbz, np, meshDS);
+ GetPoint(px11, i, nby - 1, nbz - 1, nbx, nby, nbz, np, meshDS);
+
+ GetPoint(p0y0, 0, j, 0, nbx, nby, nbz, np, meshDS);
+ GetPoint(p0y1, 0, j, nbz - 1, nbx, nby, nbz, np, meshDS);
+ GetPoint(p1y0, nbx - 1, j, 0, nbx, nby, nbz, np, meshDS);
+ GetPoint(p1y1, nbx - 1, j, nbz - 1, nbx, nby, nbz, np, meshDS);
+
+ GetPoint(p00z, 0, 0, k, nbx, nby, nbz, np, meshDS);
+ GetPoint(p01z, 0, nby - 1, k, nbx, nby, nbz, np, meshDS);
+ GetPoint(p10z, nbx - 1, 0, k, nbx, nby, nbz, np, meshDS);
+ GetPoint(p11z, nbx - 1, nby - 1, k, nbx, nby, nbz, np, meshDS);
+
+ // 12 points on faces
+ GetPoint(pxy0, i, j, 0, nbx, nby, nbz, np, meshDS);
+ GetPoint(pxy1, i, j, nbz - 1, nbx, nby, nbz, np, meshDS);
+ GetPoint(px0z, i, 0, k, nbx, nby, nbz, np, meshDS);
+ GetPoint(px1z, i, nby - 1, k, nbx, nby, nbz, np, meshDS);
+ GetPoint(p0yz, 0, j, k, nbx, nby, nbz, np, meshDS);
+ GetPoint(p1yz, nbx - 1, j, k, nbx, nby, nbz, np, meshDS);
+
+ int ijk = k * nbx * nby + j * nbx + i;
+ double x = double (i) / double (nbx - 1); // *** seulement
+ double y = double (j) / double (nby - 1); // *** maillage
+ double z = double (k) / double (nbz - 1); // *** regulier
+
+ Pt3 X;
+ for (int i = 0; i < 3; i++)
+ {
+ X[i] =
+ (1 - x) * p0yz[i] + x * p1yz[i]
+ + (1 - y) * px0z[i] + y * px1z[i]
+ + (1 - z) * pxy0[i] + z * pxy1[i]
+ - (1 - x) * ((1 - y) * p00z[i] + y * p01z[i])
+ - x * ((1 - y) * p10z[i] + y * p11z[i])
+ - (1 - y) * ((1 - z) * px00[i] + z * px01[i])
+ - y * ((1 - z) * px10[i] + z * px11[i])
+ - (1 - z) * ((1 - x) * p0y0[i] + x * p1y0[i])
+ - z * ((1 - x) * p0y1[i] + x * p1y1[i])
+ + (1 - x) * ((1 - y) * ((1 - z) * p000[i] + z * p001[i])
+ + y * ((1 - z) * p010[i] + z * p011[i]))
+ + x * ((1 - y) * ((1 - z) * p100[i] + z * p101[i])
+ + y * ((1 - z) * p110[i] + z * p111[i]));
+ }
+
+ SMDS_MeshNode * node = meshDS->AddNode(X[0], X[1], X[2]);
+ np[ijk].node = node;
+ //meshDS->SetNodeInVolume(node, TopoDS::Solid(aShape));
+ meshDS->SetNodeInVolume(node, aShell);
+ }
+ }
+ }
+
+ //2.1 - for each node of the cube (less 3 *1 Faces):
+ // - store hexahedron in SMESHDS
+ MESSAGE("Storing hexahedron into the DS");
+ for (int i = 0; i < nbx - 1; i++)
+ for (int j = 0; j < nby - 1; j++)
+ for (int k = 0; k < nbz - 1; k++)
+ {
+ int n1 = k * nbx * nby + j * nbx + i;
+ int n2 = k * nbx * nby + j * nbx + i + 1;
+ int n3 = k * nbx * nby + (j + 1) * nbx + i + 1;
+ int n4 = k * nbx * nby + (j + 1) * nbx + i;
+ int n5 = (k + 1) * nbx * nby + j * nbx + i;
+ int n6 = (k + 1) * nbx * nby + j * nbx + i + 1;
+ int n7 = (k + 1) * nbx * nby + (j + 1) * nbx + i + 1;
+ int n8 = (k + 1) * nbx * nby + (j + 1) * nbx + i;
+
+// MESSAGE(" "<<n1<<" "<<n2<<" "<<n3<<" "<<n4<<" "<<n5<<" "<<n6<<" "<<n7<<" "<<n8);
+ //MESSAGE(" "<<np[n1].nodeId<<" "<<np[n2].nodeId<<" "<<np[n3].nodeId<<" "<<np[n4].nodeId<<" "<<np[n5].nodeId<<" "<<np[n6].nodeId<<" "<<np[n7].nodeId<<" "<<np[n8].nodeId);
+
+ SMDS_MeshVolume * elt = meshDS->AddVolume(np[n1].node,
+ np[n2].node,
+ np[n3].node,
+ np[n4].node,
+ np[n5].node,
+ np[n6].node,
+ np[n7].node,
+ np[n8].node);
+ ;
+ meshDS->SetMeshElementOnShape(elt, aShell);
+
+ // *** 5 tetrahedres ... verifier orientations,
+ // mettre en coherence &vec quadrangles-> triangles
+ // choisir afficher 1 parmi edges, face et volumes
+// int tetra1 = meshDS->AddVolume(np[n1].nodeId,
+// np[n2].nodeId,
+// np[n4].nodeId,
+// np[n5].nodeId);
+// int tetra2 = meshDS->AddVolume(np[n2].nodeId,
+// np[n3].nodeId,
+// np[n4].nodeId,
+// np[n7].nodeId);
+// int tetra3 = meshDS->AddVolume(np[n5].nodeId,
+// np[n6].nodeId,
+// np[n7].nodeId,
+// np[n2].nodeId);
+// int tetra4 = meshDS->AddVolume(np[n5].nodeId,
+// np[n7].nodeId,
+// np[n8].nodeId,
+// np[n4].nodeId);
+// int tetra5 = meshDS->AddVolume(np[n5].nodeId,
+// np[n7].nodeId,
+// np[n2].nodeId,
+// np[n4].nodeId);
+
+ }
+
+ MESSAGE("End of StdMeshers_Hexa_3D::Compute()");
+ return true;
+}
+
+//=============================================================================
+/*!
+ *
+ */
+//=============================================================================
+
+void StdMeshers_Hexa_3D::GetPoint(Pt3 p, int i, int j, int k, int nbx, int nby,
+ int nbz, Point3DStruct * np, const SMESHDS_Mesh * meshDS)
+{
+ int ijk = k * nbx * nby + j * nbx + i;
+ const SMDS_MeshNode * node = np[ijk].node;
+ p[0] = node->X();
+ p[1] = node->Y();
+ p[2] = node->Z();
+ //MESSAGE(" "<<i<<" "<<j<<" "<<k<<" "<<p[0]<<" "<<p[1]<<" "<<p[2]);
+}
+
+//=============================================================================
+/*!
+ *
+ */
+//=============================================================================
+
+int StdMeshers_Hexa_3D::GetFaceIndex(SMESH_Mesh & aMesh,
+ const TopoDS_Shape & aShape,
+ const vector < SMESH_subMesh * >&meshFaces,
+ const TopoDS_Vertex & V0,
+ const TopoDS_Vertex & V1,
+ const TopoDS_Vertex & V2, const TopoDS_Vertex & V3)
+{
+ MESSAGE("StdMeshers_Hexa_3D::GetFaceIndex");
+ int faceIndex = -1;
+ for (int i = 1; i < 6; i++)
+ {
+ const TopoDS_Shape & aFace = meshFaces[i]->GetSubShape();
+ //const TopoDS_Face& F = TopoDS::Face(aFace);
+ TopTools_IndexedMapOfShape M;
+ TopExp::MapShapes(aFace, TopAbs_VERTEX, M);
+ bool verticesInShape = false;
+ if (M.Contains(V0))
+ if (M.Contains(V1))
+ if (M.Contains(V2))
+ if (M.Contains(V3))
+ verticesInShape = true;
+ if (verticesInShape)
+ {
+ faceIndex = i;
+ break;
+ }
+ }
+ ASSERT(faceIndex > 0);
+ SCRUTE(faceIndex);
+ return faceIndex;
+}
+
+//=============================================================================
+/*!
+ *
+ */
+//=============================================================================
+
+TopoDS_Edge
+ StdMeshers_Hexa_3D::EdgeNotInFace(SMESH_Mesh & aMesh,
+ const TopoDS_Shape & aShape,
+ const TopoDS_Face & aFace,
+ const TopoDS_Vertex & aVertex,
+ const TopTools_IndexedDataMapOfShapeListOfShape & MS)
+{
+ MESSAGE("StdMeshers_Hexa_3D::EdgeNotInFace");
+ TopTools_IndexedDataMapOfShapeListOfShape MF;
+ TopExp::MapShapesAndAncestors(aFace, TopAbs_VERTEX, TopAbs_EDGE, MF);
+ const TopTools_ListOfShape & ancestorsInSolid = MS.FindFromKey(aVertex);
+ const TopTools_ListOfShape & ancestorsInFace = MF.FindFromKey(aVertex);
+ SCRUTE(ancestorsInSolid.Extent());
+ SCRUTE(ancestorsInFace.Extent());
+ ASSERT(ancestorsInSolid.Extent() == 6); // 6 (edges doublees)
+ ASSERT(ancestorsInFace.Extent() == 2);
+
+ TopoDS_Edge E;
+ E.Nullify();
+ TopTools_ListIteratorOfListOfShape its(ancestorsInSolid);
+ for (; its.More(); its.Next())
+ {
+ TopoDS_Shape ancestor = its.Value();
+ TopTools_ListIteratorOfListOfShape itf(ancestorsInFace);
+ bool isInFace = false;
+ for (; itf.More(); itf.Next())
+ {
+ TopoDS_Shape ancestorInFace = itf.Value();
+ if (ancestorInFace.IsSame(ancestor))
+ {
+ isInFace = true;
+ break;
+ }
+ }
+ if (!isInFace)
+ {
+ E = TopoDS::Edge(ancestor);
+ break;
+ }
+ }
+ return E;
+}
+
+//=============================================================================
+/*!
+ *
+ */
+//=============================================================================
+
+void StdMeshers_Hexa_3D::GetConv2DCoefs(const faceQuadStruct & quad,
+ const TopoDS_Shape & aShape,
+ const TopoDS_Vertex & V0,
+ const TopoDS_Vertex & V1,
+ const TopoDS_Vertex & V2, const TopoDS_Vertex & V3, Conv2DStruct & conv)
+{
+ MESSAGE("StdMeshers_Hexa_3D::GetConv2DCoefs");
+ const TopoDS_Face & F = TopoDS::Face(aShape);
+ TopoDS_Edge E = quad.edge[0];
+ double f, l;
+ Handle(Geom2d_Curve) C2d = BRep_Tool::CurveOnSurface(E, F, f, l);
+ TopoDS_Vertex VFirst, VLast;
+ TopExp::Vertices(E, VFirst, VLast); // corresponds to f and l
+ bool isForward = (((l - f) * (quad.last[0] - quad.first[0])) > 0);
+ TopoDS_Vertex VA, VB;
+ if (isForward)
+ {
+ VA = VFirst;
+ VB = VLast;
+ }
+ else
+ {
+ VA = VLast;
+ VB = VFirst;
+ }
+ int a1, b1, c1, a2, b2, c2;
+ if (VA.IsSame(V0))
+ if (VB.IsSame(V1))
+ {
+ a1 = 1;
+ b1 = 0;
+ c1 = 0; // x
+ a2 = 0;
+ b2 = 1;
+ c2 = 0; // y
+ }
+ else
+ {
+ ASSERT(VB.IsSame(V3));
+ a1 = 0;
+ b1 = 1;
+ c1 = 0; // y
+ a2 = 1;
+ b2 = 0;
+ c2 = 0; // x
+ }
+ if (VA.IsSame(V1))
+ if (VB.IsSame(V2))
+ {
+ a1 = 0;
+ b1 = -1;
+ c1 = 1; // 1-y
+ a2 = 1;
+ b2 = 0;
+ c2 = 0; // x
+ }
+ else
+ {
+ ASSERT(VB.IsSame(V0));
+ a1 = -1;
+ b1 = 0;
+ c1 = 1; // 1-x
+ a2 = 0;
+ b2 = 1;
+ c2 = 0; // y
+ }
+ if (VA.IsSame(V2))
+ if (VB.IsSame(V3))
+ {
+ a1 = -1;
+ b1 = 0;
+ c1 = 1; // 1-x
+ a2 = 0;
+ b2 = -1;
+ c2 = 1; // 1-y
+ }
+ else
+ {
+ ASSERT(VB.IsSame(V1));
+ a1 = 0;
+ b1 = -1;
+ c1 = 1; // 1-y
+ a2 = -1;
+ b2 = 0;
+ c2 = 1; // 1-x
+ }
+ if (VA.IsSame(V3))
+ if (VB.IsSame(V0))
+ {
+ a1 = 0;
+ b1 = 1;
+ c1 = 0; // y
+ a2 = -1;
+ b2 = 0;
+ c2 = 1; // 1-x
+ }
+ else
+ {
+ ASSERT(VB.IsSame(V2));
+ a1 = 1;
+ b1 = 0;
+ c1 = 0; // x
+ a2 = 0;
+ b2 = -1;
+ c2 = 1; // 1-y
+ }
+ MESSAGE("X = " << c1 << "+ " << a1 << "*x + " << b1 << "*y");
+ MESSAGE("Y = " << c2 << "+ " << a2 << "*x + " << b2 << "*y");
+ conv.a1 = a1;
+ conv.b1 = b1;
+ conv.c1 = c1;
+ conv.a2 = a2;
+ conv.b2 = b2;
+ conv.c2 = c2;
+
+ int nbdown = quad.nbPts[0];
+ int nbright = quad.nbPts[1];
+ conv.ia = int (a1);
+ conv.ib = int (b1);
+ conv.ic =
+ int (c1 * a1 * a1) * (nbdown - 1) + int (c1 * b1 * b1) * (nbright - 1);
+ conv.ja = int (a2);
+ conv.jb = int (b2);
+ conv.jc =
+ int (c2 * a2 * a2) * (nbdown - 1) + int (c2 * b2 * b2) * (nbright - 1);
+ MESSAGE("I " << conv.ia << " " << conv.ib << " " << conv.ic);
+ MESSAGE("J " << conv.ja << " " << conv.jb << " " << conv.jc);
+}
+
+//=============================================================================
+/*!
+ *
+ */
+//=============================================================================
+
+ostream & StdMeshers_Hexa_3D::SaveTo(ostream & save)
+{
+ return save;
+}
+
+//=============================================================================
+/*!
+ *
+ */
+//=============================================================================
+
+istream & StdMeshers_Hexa_3D::LoadFrom(istream & load)
+{
+ return load;
+}
+
+//=============================================================================
+/*!
+ *
+ */
+//=============================================================================
+
+ostream & operator <<(ostream & save, StdMeshers_Hexa_3D & hyp)
+{
+ return hyp.SaveTo( save );
+}
+
+//=============================================================================
+/*!
+ *
+ */
+//=============================================================================
+
+istream & operator >>(istream & load, StdMeshers_Hexa_3D & hyp)
+{
+ return hyp.LoadFrom( load );
+}
--- /dev/null
+// SMESH SMESH : implementaion of SMESH idl descriptions
+//
+// Copyright (C) 2003 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
+// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
+//
+// This library 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.
+//
+// This library 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 this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+//
+// See http://www.opencascade.org/SALOME/ or email : webmaster.salome@opencascade.org
+//
+//
+//
+// File : StdMeshers_Hexa_3D.hxx
+// Moved here from SMESH_Hexa_3D.hxx
+// Author : Paul RASCLE, EDF
+// Module : SMESH
+// $Header$
+
+#ifndef _SMESH_HEXA_3D_HXX_
+#define _SMESH_HEXA_3D_HXX_
+
+#include "SMESH_3D_Algo.hxx"
+#include "SMESH_Mesh.hxx"
+#include "StdMeshers_Quadrangle_2D.hxx"
+#include "Utils_SALOME_Exception.hxx"
+
+typedef struct point3Dstruct
+{
+ const SMDS_MeshNode * node;
+} Point3DStruct;
+
+typedef double Pt3[3];
+
+typedef struct conv2dstruct
+{
+ double a1; // X = a1*x + b1*y + c1
+ double b1; // Y = a2*x + b2*y + c2
+ double c1; // a1, b1 a2, b2 in {-1,0,1}
+ double a2; // c1, c2 in {0,1}
+ double b2;
+ double c2;
+ int ia; // I = ia*i + ib*j + ic
+ int ib;
+ int ic;
+ int ja; // J = ja*i + jb*j + jc
+ int jb;
+ int jc;
+} Conv2DStruct;
+
+typedef struct cubeStruct
+{
+ TopoDS_Vertex V000;
+ TopoDS_Vertex V001;
+ TopoDS_Vertex V010;
+ TopoDS_Vertex V011;
+ TopoDS_Vertex V100;
+ TopoDS_Vertex V101;
+ TopoDS_Vertex V110;
+ TopoDS_Vertex V111;
+ faceQuadStruct* quad_X0;
+ faceQuadStruct* quad_X1;
+ faceQuadStruct* quad_Y0;
+ faceQuadStruct* quad_Y1;
+ faceQuadStruct* quad_Z0;
+ faceQuadStruct* quad_Z1;
+ Point3DStruct* np; // normalised 3D coordinates
+} CubeStruct;
+
+class StdMeshers_Hexa_3D:
+ public SMESH_3D_Algo
+{
+public:
+ StdMeshers_Hexa_3D(int hypId, int studyId, SMESH_Gen* gen);
+ virtual ~StdMeshers_Hexa_3D();
+
+ virtual bool CheckHypothesis(SMESH_Mesh& aMesh,
+ const TopoDS_Shape& aShape,
+ SMESH_Hypothesis::Hypothesis_Status& aStatus);
+
+ virtual bool Compute(SMESH_Mesh& aMesh,
+ const TopoDS_Shape& aShape)
+ throw (SALOME_Exception);
+
+ ostream & SaveTo(ostream & save);
+ istream & LoadFrom(istream & load);
+ friend ostream & operator << (ostream & save, StdMeshers_Hexa_3D & hyp);
+ friend istream & operator >> (istream & load, StdMeshers_Hexa_3D & hyp);
+
+protected:
+ TopoDS_Edge
+ EdgeNotInFace(SMESH_Mesh& aMesh,
+ const TopoDS_Shape& aShape,
+ const TopoDS_Face& aFace,
+ const TopoDS_Vertex& aVertex,
+ const TopTools_IndexedDataMapOfShapeListOfShape& MS);
+
+ int GetFaceIndex(SMESH_Mesh& aMesh,
+ const TopoDS_Shape& aShape,
+ const vector<SMESH_subMesh*>& meshFaces,
+ const TopoDS_Vertex& V0,
+ const TopoDS_Vertex& V1,
+ const TopoDS_Vertex& V2,
+ const TopoDS_Vertex& V3);
+
+ void GetConv2DCoefs(const faceQuadStruct& quad,
+ const TopoDS_Shape& aShape,
+ const TopoDS_Vertex& V0,
+ const TopoDS_Vertex& V1,
+ const TopoDS_Vertex& V2,
+ const TopoDS_Vertex& V3,
+ Conv2DStruct& conv);
+
+ void GetPoint(Pt3 p,
+ int i, int j, int k,
+ int nbx, int nby, int nbz,
+ Point3DStruct *np,
+ const SMESHDS_Mesh* meshDS);
+
+ CubeStruct _cube;
+ FaceQuadStruct* _quads[6];
+ int _indX0;
+ int _indX1;
+ int _indY0;
+ int _indY1;
+ int _indZ0;
+ int _indZ1;
+};
+
+#endif
--- /dev/null
+// SMESH SMESH : implementaion of SMESH idl descriptions
+//
+// Copyright (C) 2003 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
+// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
+//
+// This library 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.
+//
+// This library 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 this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+//
+// See http://www.opencascade.org/SALOME/ or email : webmaster.salome@opencascade.org
+//
+//
+//
+// File : StdMeshers_LengthFromEdges.cxx
+// Moved here from SMESH_LengthFromEdges.cxx
+// Author : Paul RASCLE, EDF
+// Module : SMESH
+// $Header$
+
+using namespace std;
+#include "StdMeshers_LengthFromEdges.hxx"
+#include "utilities.h"
+
+//=============================================================================
+/*!
+ *
+ */
+//=============================================================================
+
+StdMeshers_LengthFromEdges::StdMeshers_LengthFromEdges(int hypId, int studyId, SMESH_Gen* gen)
+ : SMESH_Hypothesis(hypId, studyId, gen)
+{
+ _mode =1;
+ _name = "LengthFromEdges";
+// SCRUTE(_name);
+// SCRUTE(&_name);
+ _param_algo_dim = 2; // is used by SMESH_MEFISTO_2D
+}
+
+//=============================================================================
+/*!
+ *
+ */
+//=============================================================================
+
+StdMeshers_LengthFromEdges::~StdMeshers_LengthFromEdges()
+{
+}
+
+//=============================================================================
+/*!
+ *
+ */
+//=============================================================================
+
+void StdMeshers_LengthFromEdges::SetMode(int mode)
+ throw (SALOME_Exception)
+{
+ int oldMode = _mode;
+ if (mode <= 0)
+ throw SALOME_Exception(LOCALIZED("mode must be positive"));
+ _mode = mode;
+ if (oldMode != _mode)
+ NotifySubMeshesHypothesisModification();
+}
+
+//=============================================================================
+/*!
+ *
+ */
+//=============================================================================
+
+int StdMeshers_LengthFromEdges::GetMode()
+{
+ return _mode;
+}
+
+//=============================================================================
+/*!
+ *
+ */
+//=============================================================================
+
+ostream & StdMeshers_LengthFromEdges::SaveTo(ostream & save)
+{
+ save << this->_mode;
+ return save;
+}
+
+//=============================================================================
+/*!
+ *
+ */
+//=============================================================================
+
+istream & StdMeshers_LengthFromEdges::LoadFrom(istream & load)
+{
+ bool isOK = true;
+ int a;
+ isOK = (load >> a);
+ if (isOK)
+ this->_mode = a;
+ else
+ load.clear(ios::badbit | load.rdstate());
+ return load;
+}
+
+//=============================================================================
+/*!
+ *
+ */
+//=============================================================================
+
+ostream & operator << (ostream & save, StdMeshers_LengthFromEdges & hyp)
+{
+ return hyp.SaveTo( save );
+}
+
+//=============================================================================
+/*!
+ *
+ */
+//=============================================================================
+
+istream & operator >> (istream & load, StdMeshers_LengthFromEdges & hyp)
+{
+ return hyp.LoadFrom( load );
+}
+
--- /dev/null
+// SMESH SMESH : implementaion of SMESH idl descriptions
+//
+// Copyright (C) 2003 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
+// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
+//
+// This library 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.
+//
+// This library 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 this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+//
+// See http://www.opencascade.org/SALOME/ or email : webmaster.salome@opencascade.org
+//
+//
+//
+// File : StdMeshers_LengthFromEdges.hxx
+// Moved here from SMESH_LengthFromEdges.hxx
+// Author : Paul RASCLE, EDF
+// Module : SMESH
+// $Header$
+
+#ifndef _SMESH_LENGTHFROMEDGES_HXX_
+#define _SMESH_LENGTHFROMEDGES_HXX_
+
+#include "SMESH_Hypothesis.hxx"
+#include "Utils_SALOME_Exception.hxx"
+
+class StdMeshers_LengthFromEdges:
+ public SMESH_Hypothesis
+{
+public:
+ StdMeshers_LengthFromEdges(int hypId, int studyId, SMESH_Gen* gen);
+ virtual ~StdMeshers_LengthFromEdges();
+
+ void SetMode(int mode)
+ throw (SALOME_Exception);
+
+ int GetMode();
+
+ virtual ostream & SaveTo(ostream & save);
+ virtual istream & LoadFrom(istream & load);
+ friend ostream & operator << (ostream & save, StdMeshers_LengthFromEdges & hyp);
+ friend istream & operator >> (istream & load, StdMeshers_LengthFromEdges & hyp);
+
+protected:
+ int _mode;
+};
+
+#endif
--- /dev/null
+// SMESH SMESH : implementaion of SMESH idl descriptions
+//
+// Copyright (C) 2003 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
+// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
+//
+// This library 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.
+//
+// This library 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 this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+//
+// See http://www.opencascade.org/SALOME/ or email : webmaster.salome@opencascade.org
+//
+//
+//
+// File : StdMeshers_LocalLength.cxx
+// Moved here from SMESH_LocalLength.cxx
+// Author : Paul RASCLE, EDF
+// Module : SMESH
+// $Header$
+
+using namespace std;
+#include "StdMeshers_LocalLength.hxx"
+#include "utilities.h"
+
+//=============================================================================
+/*!
+ *
+ */
+//=============================================================================
+
+StdMeshers_LocalLength::StdMeshers_LocalLength(int hypId, int studyId,
+ SMESH_Gen * gen):SMESH_Hypothesis(hypId, studyId, gen)
+{
+ _length = 1.;
+ _name = "LocalLength";
+// SCRUTE(_name);
+// SCRUTE(&_name);
+ _param_algo_dim = 1; // is used by SMESH_Regular_1D
+}
+
+//=============================================================================
+/*!
+ *
+ */
+//=============================================================================
+
+StdMeshers_LocalLength::~StdMeshers_LocalLength()
+{
+}
+
+//=============================================================================
+/*!
+ *
+ */
+//=============================================================================
+
+void StdMeshers_LocalLength::SetLength(double length) throw(SALOME_Exception)
+{
+ double oldLength = _length;
+ if (length <= 0)
+ throw SALOME_Exception(LOCALIZED("length must be positive"));
+ _length = length;
+ if (oldLength != _length)
+ NotifySubMeshesHypothesisModification();
+}
+
+//=============================================================================
+/*!
+ *
+ */
+//=============================================================================
+
+double StdMeshers_LocalLength::GetLength() const
+{
+ return _length;
+}
+
+//=============================================================================
+/*!
+ *
+ */
+//=============================================================================
+
+ostream & StdMeshers_LocalLength::SaveTo(ostream & save)
+{
+ save << this->_length;
+ return save;
+}
+
+//=============================================================================
+/*!
+ *
+ */
+//=============================================================================
+
+istream & StdMeshers_LocalLength::LoadFrom(istream & load)
+{
+ bool isOK = true;
+ double a;
+ isOK = (load >> a);
+ if (isOK)
+ this->_length = a;
+ else
+ load.clear(ios::badbit | load.rdstate());
+ return load;
+}
+
+//=============================================================================
+/*!
+ *
+ */
+//=============================================================================
+
+ostream & operator <<(ostream & save, StdMeshers_LocalLength & hyp)
+{
+ return hyp.SaveTo( save );
+}
+
+//=============================================================================
+/*!
+ *
+ */
+//=============================================================================
+
+istream & operator >>(istream & load, StdMeshers_LocalLength & hyp)
+{
+ return hyp.LoadFrom( load );
+}
--- /dev/null
+// SMESH SMESH : implementaion of SMESH idl descriptions
+//
+// Copyright (C) 2003 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
+// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
+//
+// This library 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.
+//
+// This library 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 this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+//
+// See http://www.opencascade.org/SALOME/ or email : webmaster.salome@opencascade.org
+//
+//
+//
+// File : StdMeshers_LocalLength.hxx
+// Moved here from SMESH_LocalLength.hxx
+// Author : Paul RASCLE, EDF
+// Module : SMESH
+// $Header$
+
+#ifndef _SMESH_LOCALLENGTH_HXX_
+#define _SMESH_LOCALLENGTH_HXX_
+
+#include "SMESH_Hypothesis.hxx"
+#include "Utils_SALOME_Exception.hxx"
+
+class StdMeshers_LocalLength:public SMESH_Hypothesis
+{
+ public:
+ StdMeshers_LocalLength(int hypId, int studyId, SMESH_Gen * gen);
+ virtual ~ StdMeshers_LocalLength();
+
+ void SetLength(double length) throw(SALOME_Exception);
+
+ double GetLength() const;
+
+ virtual ostream & SaveTo(ostream & save);
+ virtual istream & LoadFrom(istream & load);
+ friend ostream & operator <<(ostream & save, StdMeshers_LocalLength & hyp);
+ friend istream & operator >>(istream & load, StdMeshers_LocalLength & hyp);
+
+ protected:
+ double _length;
+};
+
+#endif
--- /dev/null
+// SMESH SMESH : implementaion of SMESH idl descriptions
+//
+// Copyright (C) 2003 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
+// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
+//
+// This library 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.
+//
+// This library 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 this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+//
+// See http://www.opencascade.org/SALOME/ or email : webmaster.salome@opencascade.org
+//
+//
+//
+// File : StdMeshers_MEFISTO_2D.cxx
+// Moved here from SMESH_MEFISTO_2D.cxx
+// Author : Paul RASCLE, EDF
+// Module : SMESH
+// $Header$
+
+using namespace std;
+#include "StdMeshers_MEFISTO_2D.hxx"
+#include "SMESH_Gen.hxx"
+#include "SMESH_Mesh.hxx"
+
+#include "StdMeshers_MaxElementArea.hxx"
+#include "StdMeshers_LengthFromEdges.hxx"
+
+#include "Rn.h"
+#include "aptrte.h"
+
+#include "SMDS_MeshElement.hxx"
+#include "SMDS_MeshNode.hxx"
+#include "SMDS_EdgePosition.hxx"
+#include "SMDS_FacePosition.hxx"
+
+#include "utilities.h"
+
+#include <TopoDS_Face.hxx>
+#include <TopoDS_Edge.hxx>
+#include <TopoDS_Shape.hxx>
+#include <Geom_Surface.hxx>
+#include <GeomAdaptor_Curve.hxx>
+#include <Geom2d_Curve.hxx>
+#include <gp_Pnt2d.hxx>
+#include <BRep_Tool.hxx>
+#include <BRepTools.hxx>
+#include <BRepTools_WireExplorer.hxx>
+#include <GCPnts_AbscissaPoint.hxx>
+#include <GCPnts_UniformAbscissa.hxx>
+#include <TColStd_ListIteratorOfListOfInteger.hxx>
+
+#include <string>
+#include <algorithm>
+
+//=============================================================================
+/*!
+ *
+ */
+//=============================================================================
+
+StdMeshers_MEFISTO_2D::StdMeshers_MEFISTO_2D(int hypId, int studyId,
+ SMESH_Gen * gen):SMESH_2D_Algo(hypId, studyId, gen)
+{
+ MESSAGE("StdMeshers_MEFISTO_2D::StdMeshers_MEFISTO_2D");
+ _name = "MEFISTO_2D";
+// _shapeType = TopAbs_FACE;
+ _shapeType = (1 << TopAbs_FACE);
+ _compatibleHypothesis.push_back("MaxElementArea");
+ _compatibleHypothesis.push_back("LengthFromEdges");
+
+ _edgeLength = 0;
+ _maxElementArea = 0;
+ _hypMaxElementArea = NULL;
+ _hypLengthFromEdges = NULL;
+}
+
+//=============================================================================
+/*!
+ *
+ */
+//=============================================================================
+
+StdMeshers_MEFISTO_2D::~StdMeshers_MEFISTO_2D()
+{
+ MESSAGE("StdMeshers_MEFISTO_2D::~StdMeshers_MEFISTO_2D");
+}
+
+//=============================================================================
+/*!
+ *
+ */
+//=============================================================================
+
+bool StdMeshers_MEFISTO_2D::CheckHypothesis
+ (SMESH_Mesh& aMesh,
+ const TopoDS_Shape& aShape,
+ SMESH_Hypothesis::Hypothesis_Status& aStatus)
+{
+ //MESSAGE("StdMeshers_MEFISTO_2D::CheckHypothesis");
+
+ _hypMaxElementArea = NULL;
+ _hypLengthFromEdges = NULL;
+
+ list <const SMESHDS_Hypothesis * >::const_iterator itl;
+ const SMESHDS_Hypothesis *theHyp;
+
+ const list <const SMESHDS_Hypothesis * >&hyps = GetUsedHypothesis(aMesh, aShape);
+ int nbHyp = hyps.size();
+ if (!nbHyp)
+ {
+ aStatus = SMESH_Hypothesis::HYP_MISSING;
+ return false; // can't work with no hypothesis
+ }
+
+ itl = hyps.begin();
+ theHyp = (*itl); // use only the first hypothesis
+
+ string hypName = theHyp->GetName();
+ int hypId = theHyp->GetID();
+ //SCRUTE(hypName);
+
+ bool isOk = false;
+
+ if (hypName == "MaxElementArea")
+ {
+ _hypMaxElementArea = static_cast<const StdMeshers_MaxElementArea *>(theHyp);
+ ASSERT(_hypMaxElementArea);
+ _maxElementArea = _hypMaxElementArea->GetMaxArea();
+ _edgeLength = 0;
+ isOk = true;
+ aStatus = SMESH_Hypothesis::HYP_OK;
+ }
+
+ else if (hypName == "LengthFromEdges")
+ {
+ _hypLengthFromEdges = static_cast<const StdMeshers_LengthFromEdges *>(theHyp);
+ ASSERT(_hypLengthFromEdges);
+ _edgeLength = 0;
+ _maxElementArea = 0;
+ isOk = true;
+ aStatus = SMESH_Hypothesis::HYP_OK;
+ }
+ else
+ aStatus = SMESH_Hypothesis::HYP_INCOMPATIBLE;
+
+ if (isOk)
+ {
+ isOk = false;
+ if (_maxElementArea > 0)
+ {
+ _edgeLength = 2 * sqrt(_maxElementArea); // triangles : minorant
+ isOk = true;
+ }
+ else
+ isOk = (_hypLengthFromEdges != NULL); // **** check mode
+ if (!isOk)
+ aStatus = SMESH_Hypothesis::HYP_BAD_PARAMETER;
+ }
+
+ //SCRUTE(_edgeLength);
+ //SCRUTE(_maxElementArea);
+ return isOk;
+}
+
+//=============================================================================
+/*!
+ *
+ */
+//=============================================================================
+
+bool StdMeshers_MEFISTO_2D::Compute(SMESH_Mesh & aMesh, const TopoDS_Shape & aShape)
+{
+ MESSAGE("StdMeshers_MEFISTO_2D::Compute");
+
+ if (_hypLengthFromEdges)
+ _edgeLength = ComputeEdgeElementLength(aMesh, aShape);
+
+ bool isOk = false;
+ const SMESHDS_Mesh * meshDS = aMesh.GetMeshDS();
+ SMESH_subMesh *theSubMesh = aMesh.GetSubMesh(aShape);
+
+ const TopoDS_Face & FF = TopoDS::Face(aShape);
+ bool faceIsForward = (FF.Orientation() == TopAbs_FORWARD);
+ TopoDS_Face F = TopoDS::Face(FF.Oriented(TopAbs_FORWARD));
+
+ Z nblf; //nombre de lignes fermees (enveloppe en tete)
+ Z *nudslf = NULL; //numero du dernier sommet de chaque ligne fermee
+ R2 *uvslf = NULL;
+ Z nbpti = 0; //nombre points internes futurs sommets de la triangulation
+ R2 *uvpti = NULL;
+
+ Z nbst;
+ R2 *uvst = NULL;
+ Z nbt;
+ Z *nust = NULL;
+ Z ierr = 0;
+
+ Z nutysu = 1; // 1: il existe un fonction areteideale_()
+ // Z nutysu=0; // 0: on utilise aretmx
+ R aretmx = _edgeLength; // longueur max aretes future triangulation
+ //SCRUTE(aretmx);
+
+ nblf = NumberOfWires(F);
+ //SCRUTE(nblf);
+
+ nudslf = new Z[1 + nblf];
+ nudslf[0] = 0;
+ int iw = 1;
+ int nbpnt = 0;
+
+ const TopoDS_Wire OW1 = BRepTools::OuterWire(F);
+ nbpnt += NumberOfPoints(aMesh, OW1);
+ nudslf[iw++] = nbpnt;
+ //SCRUTE(nbpnt);
+
+ for (TopExp_Explorer exp(F, TopAbs_WIRE); exp.More(); exp.Next())
+ {
+ const TopoDS_Wire & W = TopoDS::Wire(exp.Current());
+ if (!OW1.IsSame(W))
+ {
+ nbpnt += NumberOfPoints(aMesh, W);
+ nudslf[iw++] = nbpnt;
+ //SCRUTE(nbpnt);
+ }
+ }
+
+ uvslf = new R2[nudslf[nblf]];
+ //SCRUTE(nudslf[nblf]);
+ int m = 0;
+
+ map<int, const SMDS_MeshNode*> mefistoToDS; // correspondence mefisto index--> points IDNodes
+ TopoDS_Wire OW = BRepTools::OuterWire(F);
+ LoadPoints(aMesh, F, OW, uvslf, m, mefistoToDS);
+ //SCRUTE(m);
+
+ for (TopExp_Explorer exp(F, TopAbs_WIRE); exp.More(); exp.Next())
+ {
+ const TopoDS_Wire & W = TopoDS::Wire(exp.Current());
+ if (!OW.IsSame(W))
+ {
+ LoadPoints(aMesh, F, W, uvslf, m, mefistoToDS);
+ //SCRUTE(m);
+ }
+ }
+// SCRUTE(nudslf[nblf]);
+// for (int i=0; i<=nblf; i++)
+// {
+// MESSAGE(" -+- " <<i<< " "<< nudslf[i]);
+// }
+// for (int i=0; i<nudslf[nblf]; i++)
+// {
+// MESSAGE(" -+- " <<i<< " "<< uvslf[i]);
+// }
+// SCRUTE(nutysu);
+// SCRUTE(aretmx);
+// SCRUTE(nblf);
+
+ MESSAGE("MEFISTO triangulation ...");
+ uvst = NULL;
+ nust = NULL;
+ aptrte(nutysu, aretmx,
+ nblf, nudslf, uvslf, nbpti, uvpti, nbst, uvst, nbt, nust, ierr);
+
+ if (ierr == 0)
+ {
+ MESSAGE("... End Triangulation Generated Triangle Number " << nbt);
+ MESSAGE(" Node Number " << nbst);
+ //SCRUTE(nbst);
+ //SCRUTE(nbt);
+ StoreResult(aMesh, nbst, uvst, nbt, nust, F,
+ faceIsForward, mefistoToDS);
+ isOk = true;
+ }
+ else
+ {
+ MESSAGE("Error in Triangulation");
+ isOk = false;
+ }
+ if (nudslf != NULL)
+ delete[]nudslf;
+ if (uvslf != NULL)
+ delete[]uvslf;
+ if (uvst != NULL)
+ delete[]uvst;
+ if (nust != NULL)
+ delete[]nust;
+ return isOk;
+}
+
+//=============================================================================
+/*!
+ *
+ */
+//=============================================================================
+
+void StdMeshers_MEFISTO_2D::LoadPoints(SMESH_Mesh & aMesh,
+ const TopoDS_Face & FF,
+ const TopoDS_Wire & WW, R2 * uvslf, int &m,
+ map<int, const SMDS_MeshNode*>&mefistoToDS)
+{
+ MESSAGE("StdMeshers_MEFISTO_2D::LoadPoints");
+
+ SMDS_Mesh * meshDS = aMesh.GetMeshDS();
+
+ double scalex;
+ double scaley;
+ TopoDS_Face F = TopoDS::Face(FF.Oriented(TopAbs_FORWARD));
+ ComputeScaleOnFace(aMesh, F, scalex, scaley);
+
+ TopoDS_Wire W = TopoDS::Wire(WW.Oriented(TopAbs_FORWARD));
+ BRepTools_WireExplorer wexp(W, F);
+ for (wexp.Init(W, F); wexp.More(); wexp.Next())
+ {
+ const TopoDS_Edge & E = wexp.Current();
+
+ // --- IDNodes of first and last Vertex
+
+ TopoDS_Vertex VFirst, VLast;
+ TopExp::Vertices(E, VFirst, VLast); // corresponds to f and l
+
+ ASSERT(!VFirst.IsNull());
+ SMDS_NodeIteratorPtr lid=
+ aMesh.GetSubMesh(VFirst)->GetSubMeshDS()->GetNodes();
+ const SMDS_MeshNode* idFirst = lid->next();
+
+ ASSERT(!VLast.IsNull());
+ lid=aMesh.GetSubMesh(VLast)->GetSubMeshDS()->GetNodes();
+ const SMDS_MeshNode* idLast = lid->next();
+
+ // --- edge internal IDNodes (relies on good order storage, not checked)
+
+ int nbPoints = aMesh.GetSubMesh(E)->GetSubMeshDS()->NbNodes();
+ //SCRUTE(nbPoints);
+
+ double f, l;
+ Handle(Geom2d_Curve) C2d = BRep_Tool::CurveOnSurface(E, F, f, l);
+
+ SMDS_NodeIteratorPtr ite= aMesh.GetSubMesh(E)->GetSubMeshDS()->GetNodes();
+
+ bool isForward = (E.Orientation() == TopAbs_FORWARD);
+ map<double, const SMDS_MeshNode*> params;
+
+ while(ite->more())
+ {
+ const SMDS_MeshNode * node = ite->next();
+ const SMDS_EdgePosition* epos =
+ static_cast<const SMDS_EdgePosition*>(node->GetPosition().get());
+ double param = epos->GetUParameter();
+ params[param] = node;
+ }
+ // --- load 2D values into MEFISTO structure,
+ // add IDNodes in mefistoToDS map
+
+ if (E.Orientation() == TopAbs_FORWARD)
+ {
+ gp_Pnt2d p = C2d->Value(f); // first point = Vertex Forward
+ uvslf[m].x = scalex * p.X();
+ uvslf[m].y = scaley * p.Y();
+ mefistoToDS[m + 1] = idFirst;
+ //MESSAGE(" "<<m<<" "<<mefistoToDS[m+1]);
+ //MESSAGE("__ f "<<f<<" "<<uvslf[m].x <<" "<<uvslf[m].y);
+ m++;
+ map<double, const SMDS_MeshNode*>::iterator itp = params.begin();
+ for (int i = 1; i <= nbPoints; i++) // nbPoints internal
+ {
+ double param = (*itp).first;
+ gp_Pnt2d p = C2d->Value(param);
+ uvslf[m].x = scalex * p.X();
+ uvslf[m].y = scaley * p.Y();
+ mefistoToDS[m + 1] = (*itp).second;
+// MESSAGE(" "<<m<<" "<<mefistoToDS[m+1]);
+// MESSAGE("__ "<<i<<" "<<param<<" "<<uvslf[m].x <<" "<<uvslf[m].y);
+ m++;
+ itp++;
+ }
+ }
+ else
+ {
+ gp_Pnt2d p = C2d->Value(l); // last point = Vertex Reversed
+ uvslf[m].x = scalex * p.X();
+ uvslf[m].y = scaley * p.Y();
+ mefistoToDS[m + 1] = idLast;
+// MESSAGE(" "<<m<<" "<<mefistoToDS[m+1]);
+// MESSAGE("__ l "<<l<<" "<<uvslf[m].x <<" "<<uvslf[m].y);
+ m++;
+ map<double, const SMDS_MeshNode*>::reverse_iterator itp = params.rbegin();
+ for (int i = nbPoints; i >= 1; i--)
+ {
+ double param = (*itp).first;
+ gp_Pnt2d p = C2d->Value(param);
+ uvslf[m].x = scalex * p.X();
+ uvslf[m].y = scaley * p.Y();
+ mefistoToDS[m + 1] = (*itp).second;
+// MESSAGE(" "<<m<<" "<<mefistoToDS[m+1]);
+// MESSAGE("__ "<<i<<" "<<param<<" "<<uvslf[m].x <<" "<<uvslf[m].y);
+ m++;
+ itp++;
+ }
+ }
+ }
+}
+
+//=============================================================================
+/*!
+ *
+ */
+//=============================================================================
+
+// **** a mettre dans SMESH_Algo ou SMESH_2D_Algo
+
+void StdMeshers_MEFISTO_2D::ComputeScaleOnFace(SMESH_Mesh & aMesh,
+ const TopoDS_Face & aFace, double &scalex, double &scaley)
+{
+ //MESSAGE("StdMeshers_MEFISTO_2D::ComputeScaleOnFace");
+ TopoDS_Face F = TopoDS::Face(aFace.Oriented(TopAbs_FORWARD));
+ TopoDS_Wire W = BRepTools::OuterWire(F);
+
+ BRepTools_WireExplorer wexp(W, F);
+
+ double xmin = 1.e300; // min & max of face 2D parametric coord.
+ double xmax = -1.e300;
+ double ymin = 1.e300;
+ double ymax = -1.e300;
+ int nbp = 50;
+ scalex = 1;
+ scaley = 1;
+ for (wexp.Init(W, F); wexp.More(); wexp.Next())
+ {
+ const TopoDS_Edge & E = wexp.Current();
+ double f, l;
+ Handle(Geom2d_Curve) C2d = BRep_Tool::CurveOnSurface(E, F, f, l);
+ for (int i = 0; i <= nbp; i++)
+ {
+ double param = f + (double (i) / double (nbp))*(l - f);
+ gp_Pnt2d p = C2d->Value(param);
+ if (p.X() < xmin)
+ xmin = p.X();
+ if (p.X() > xmax)
+ xmax = p.X();
+ if (p.Y() < ymin)
+ ymin = p.Y();
+ if (p.Y() > ymax)
+ ymax = p.Y();
+// MESSAGE(" "<< f<<" "<<l<<" "<<param<<" "<<xmin<<" "<<xmax<<" "<<ymin<<" "<<ymax);
+ }
+ }
+// SCRUTE(xmin);
+// SCRUTE(xmax);
+// SCRUTE(ymin);
+// SCRUTE(ymax);
+ double xmoy = (xmax + xmin) / 2.;
+ double ymoy = (ymax + ymin) / 2.;
+
+ Handle(Geom_Surface) S = BRep_Tool::Surface(F); // 3D surface
+
+ double length_x = 0;
+ double length_y = 0;
+ gp_Pnt PX0 = S->Value(xmin, ymoy);
+ gp_Pnt PY0 = S->Value(xmoy, ymin);
+ for (int i = 1; i <= nbp; i++)
+ {
+ double x = xmin + (double (i) / double (nbp))*(xmax - xmin);
+ gp_Pnt PX = S->Value(x, ymoy);
+ double y = ymin + (double (i) / double (nbp))*(ymax - ymin);
+ gp_Pnt PY = S->Value(xmoy, y);
+ length_x += PX.Distance(PX0);
+ length_y += PY.Distance(PY0);
+ PX0.SetCoord(PX.X(), PX.Y(), PX.Z());
+ PY0.SetCoord(PY.X(), PY.Y(), PY.Z());
+ }
+// SCRUTE(length_x);
+// SCRUTE(length_y);
+ scalex = length_x / (xmax - xmin);
+ scaley = length_y / (ymax - ymin);
+// SCRUTE(scalex);
+// SCRUTE(scaley);
+ ASSERT(scalex);
+ ASSERT(scaley);
+}
+
+//=============================================================================
+/*!
+ *
+ */
+//=============================================================================
+
+void StdMeshers_MEFISTO_2D::StoreResult(SMESH_Mesh & aMesh,
+ Z nbst, R2 * uvst, Z nbt, Z * nust,
+ const TopoDS_Face & F, bool faceIsForward,
+ map<int, const SMDS_MeshNode*>&mefistoToDS)
+{
+ double scalex;
+ double scaley;
+ ComputeScaleOnFace(aMesh, F, scalex, scaley);
+
+ SMESHDS_Mesh * meshDS = aMesh.GetMeshDS();
+
+ Z n, m;
+ Handle(Geom_Surface) S = BRep_Tool::Surface(F);
+
+ for (n = 0; n < nbst; n++)
+ {
+ double u = uvst[n][0] / scalex;
+ double v = uvst[n][1] / scaley;
+ gp_Pnt P = S->Value(u, v);
+
+ if (mefistoToDS.find(n + 1) == mefistoToDS.end())
+ {
+ SMDS_MeshNode * node = meshDS->AddNode(P.X(), P.Y(), P.Z());
+ meshDS->SetNodeOnFace(node, F);
+
+ //MESSAGE(nodeId<<" "<<P.X()<<" "<<P.Y()<<" "<<P.Z());
+ mefistoToDS[n + 1] = node;
+ //MESSAGE(" "<<n<<" "<<mefistoToDS[n+1]);
+ SMDS_FacePosition* fpos =
+ static_cast<SMDS_FacePosition*>(node->GetPosition().get());
+ fpos->SetUParameter(u);
+ fpos->SetVParameter(v);
+ }
+ }
+
+ m = 0;
+ int mt = 0;
+
+ //SCRUTE(faceIsForward);
+ for (n = 1; n <= nbt; n++)
+ {
+ int inode1 = nust[m++];
+ int inode2 = nust[m++];
+ int inode3 = nust[m++];
+
+ const SMDS_MeshNode *n1, *n2, *n3;
+ n1 = mefistoToDS[inode1];
+ n2 = mefistoToDS[inode2];
+ n3 = mefistoToDS[inode3];
+ //MESSAGE("-- "<<inode1<<" "<<inode2<<" "<<inode3<<" ++ "<<nodeId1<<" "<<nodeId2<<" "<<nodeId3);
+
+ // triangle points must be in trigonometric order if face is Forward
+ // else they must be put clockwise
+
+ bool triangleIsWellOriented = faceIsForward;
+
+ SMDS_MeshElement * elt;
+ if (triangleIsWellOriented)
+ elt = meshDS->AddFace(n1, n2, n3);
+ else
+ elt = meshDS->AddFace(n1, n3, n2);
+
+ meshDS->SetMeshElementOnShape(elt, F);
+ m++;
+ }
+}
+
+//=============================================================================
+/*!
+ *
+ */
+//=============================================================================
+
+double StdMeshers_MEFISTO_2D::ComputeEdgeElementLength(SMESH_Mesh & aMesh,
+ const TopoDS_Shape & aShape)
+{
+ MESSAGE("StdMeshers_MEFISTO_2D::ComputeEdgeElementLength");
+ // **** a mettre dans SMESH_2D_Algo ?
+
+ const TopoDS_Face & FF = TopoDS::Face(aShape);
+ bool faceIsForward = (FF.Orientation() == TopAbs_FORWARD);
+ TopoDS_Face F = TopoDS::Face(FF.Oriented(TopAbs_FORWARD));
+
+ double meanElementLength = 100;
+ double wireLength = 0;
+ int wireElementsNumber = 0;
+ for (TopExp_Explorer exp(F, TopAbs_WIRE); exp.More(); exp.Next())
+ {
+ const TopoDS_Wire & W = TopoDS::Wire(exp.Current());
+ for (TopExp_Explorer expe(W, TopAbs_EDGE); expe.More(); expe.Next())
+ {
+ const TopoDS_Edge & E = TopoDS::Edge(expe.Current());
+ int nb = aMesh.GetSubMesh(E)->GetSubMeshDS()->NbNodes();
+ double length = EdgeLength(E);
+ wireLength += length;
+ wireElementsNumber += nb;
+ }
+ }
+ if (wireElementsNumber)
+ meanElementLength = wireLength / wireElementsNumber;
+ //SCRUTE(meanElementLength);
+ return meanElementLength;
+}
+
+//=============================================================================
+/*!
+ *
+ */
+//=============================================================================
+
+ostream & StdMeshers_MEFISTO_2D::SaveTo(ostream & save)
+{
+ return save;
+}
+
+//=============================================================================
+/*!
+ *
+ */
+//=============================================================================
+
+istream & StdMeshers_MEFISTO_2D::LoadFrom(istream & load)
+{
+ return load;
+}
+
+//=============================================================================
+/*!
+ *
+ */
+//=============================================================================
+
+ostream & operator <<(ostream & save, StdMeshers_MEFISTO_2D & hyp)
+{
+ return hyp.SaveTo( save );
+}
+
+//=============================================================================
+/*!
+ *
+ */
+//=============================================================================
+
+istream & operator >>(istream & load, StdMeshers_MEFISTO_2D & hyp)
+{
+ return hyp.LoadFrom( load );
+}
--- /dev/null
+// SMESH SMESH : implementaion of SMESH idl descriptions
+//
+// Copyright (C) 2003 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
+// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
+//
+// This library 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.
+//
+// This library 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 this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+//
+// See http://www.opencascade.org/SALOME/ or email : webmaster.salome@opencascade.org
+//
+//
+//
+// File : StdMeshers_MEFISTO_2D.hxx
+// Moved here from SMESH_MEFISTO_2D.hxx
+// Author : Paul RASCLE, EDF
+// Module : SMESH
+// $Header$
+
+#ifndef _StdMeshers_MEFISTO_2D_HXX_
+#define _StdMeshers_MEFISTO_2D_HXX_
+
+#include "SMESH_2D_Algo.hxx"
+#include "StdMeshers_MaxElementArea.hxx"
+#include "StdMeshers_LengthFromEdges.hxx"
+#include "Rn.h"
+
+class SMDS_MeshNode;
+#include <TopoDS_Face.hxx>
+#include <map>
+
+class StdMeshers_MEFISTO_2D:
+ public SMESH_2D_Algo
+{
+public:
+ StdMeshers_MEFISTO_2D(int hypId, int studyId, SMESH_Gen* gen);
+ virtual ~StdMeshers_MEFISTO_2D();
+
+ virtual bool CheckHypothesis(SMESH_Mesh& aMesh,
+ const TopoDS_Shape& aShape,
+ SMESH_Hypothesis::Hypothesis_Status& aStatus);
+
+ virtual bool Compute(SMESH_Mesh& aMesh,
+ const TopoDS_Shape& aShape);
+
+ double ComputeEdgeElementLength(SMESH_Mesh& aMesh,
+ const TopoDS_Shape& aShape);
+
+ void LoadPoints(SMESH_Mesh& aMesh,
+ const TopoDS_Face& F,
+ const TopoDS_Wire& W,
+ R2* uvslf,
+ int& m,
+ map<int,const SMDS_MeshNode*>& mefistoToDS);
+
+ void ComputeScaleOnFace(SMESH_Mesh& aMesh,
+ const TopoDS_Face& aFace,
+ double& scalex,
+ double& scaley);
+
+ void StoreResult (SMESH_Mesh& aMesh,
+ Z nbst, R2* uvst, Z nbt, Z* nust,
+ const TopoDS_Face& F, bool faceIsForward,
+ map<int,const SMDS_MeshNode*>& mefistoToDS);
+
+ ostream & SaveTo(ostream & save);
+ istream & LoadFrom(istream & load);
+ friend ostream & operator << (ostream & save, StdMeshers_MEFISTO_2D & hyp);
+ friend istream & operator >> (istream & load, StdMeshers_MEFISTO_2D & hyp);
+
+protected:
+ double _edgeLength;
+ double _maxElementArea;
+ const StdMeshers_MaxElementArea* _hypMaxElementArea;
+ const StdMeshers_LengthFromEdges* _hypLengthFromEdges;
+};
+
+#endif
--- /dev/null
+// SMESH SMESH : implementaion of SMESH idl descriptions
+//
+// Copyright (C) 2003 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
+// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
+//
+// This library 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.
+//
+// This library 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 this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+//
+// See http://www.opencascade.org/SALOME/ or email : webmaster.salome@opencascade.org
+//
+//
+//
+// File : StdMeshers_MaxElementArea.cxx
+// Moved here from SMESH_MaxElementArea.cxx
+// Author : Paul RASCLE, EDF
+// Module : SMESH
+// $Header$
+
+using namespace std;
+#include "StdMeshers_MaxElementArea.hxx"
+#include "utilities.h"
+
+//=============================================================================
+/*!
+ *
+ */
+//=============================================================================
+
+StdMeshers_MaxElementArea::StdMeshers_MaxElementArea(int hypId, int studyId, SMESH_Gen* gen)
+ : SMESH_Hypothesis(hypId, studyId, gen)
+{
+ _maxArea =1.;
+ _name = "MaxElementArea";
+// SCRUTE(_name);
+// SCRUTE(&_name);
+ _param_algo_dim = 2;
+}
+
+//=============================================================================
+/*!
+ *
+ */
+//=============================================================================
+
+StdMeshers_MaxElementArea::~StdMeshers_MaxElementArea()
+{
+}
+
+//=============================================================================
+/*!
+ *
+ */
+//=============================================================================
+
+void StdMeshers_MaxElementArea::SetMaxArea(double maxArea)
+ throw (SALOME_Exception)
+{
+ double oldArea = _maxArea;
+ if (maxArea <= 0)
+ throw SALOME_Exception(LOCALIZED("maxArea must be positive"));
+ _maxArea = maxArea;
+ if (_maxArea != oldArea)
+ NotifySubMeshesHypothesisModification();
+}
+
+//=============================================================================
+/*!
+ *
+ */
+//=============================================================================
+
+double StdMeshers_MaxElementArea::GetMaxArea() const
+{
+ return _maxArea;
+}
+
+//=============================================================================
+/*!
+ *
+ */
+//=============================================================================
+
+ostream & StdMeshers_MaxElementArea::SaveTo(ostream & save)
+{
+ save << this->_maxArea;
+ return save;
+}
+
+//=============================================================================
+/*!
+ *
+ */
+//=============================================================================
+
+istream & StdMeshers_MaxElementArea::LoadFrom(istream & load)
+{
+ bool isOK = true;
+ double a;
+ isOK = (load >> a);
+ if (isOK)
+ this->_maxArea = a;
+ else
+ load.clear(ios::badbit | load.rdstate());
+ return load;
+}
+
+//=============================================================================
+/*!
+ *
+ */
+//=============================================================================
+
+ostream & operator << (ostream & save, StdMeshers_MaxElementArea & hyp)
+{
+ return hyp.SaveTo( save );
+}
+
+//=============================================================================
+/*!
+ *
+ */
+//=============================================================================
+
+istream & operator >> (istream & load, StdMeshers_MaxElementArea & hyp)
+{
+ return hyp.LoadFrom( load );
+}
+
--- /dev/null
+// SMESH SMESH : implementaion of SMESH idl descriptions
+//
+// Copyright (C) 2003 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
+// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
+//
+// This library 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.
+//
+// This library 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 this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+//
+// See http://www.opencascade.org/SALOME/ or email : webmaster.salome@opencascade.org
+//
+//
+//
+// File : StdMeshers_MaxElementArea.hxx
+// Moved here from SMESH_MaxElementArea.hxx
+// Author : Paul RASCLE, EDF
+// Module : SMESH
+// $Header$
+
+#ifndef _SMESH_MAXELEMENTAREA_HXX_
+#define _SMESH_MAXELEMENTAREA_HXX_
+
+#include "SMESH_Hypothesis.hxx"
+#include "Utils_SALOME_Exception.hxx"
+
+class StdMeshers_MaxElementArea:public SMESH_Hypothesis
+{
+ public:
+ StdMeshers_MaxElementArea(int hypId, int studyId, SMESH_Gen * gen);
+ virtual ~ StdMeshers_MaxElementArea();
+
+ void SetMaxArea(double maxArea) throw(SALOME_Exception);
+
+ double GetMaxArea() const;
+
+ virtual ostream & SaveTo(ostream & save);
+ virtual istream & LoadFrom(istream & load);
+ friend ostream & operator <<(ostream & save, StdMeshers_MaxElementArea & hyp);
+ friend istream & operator >>(istream & load, StdMeshers_MaxElementArea & hyp);
+
+ protected:
+ double _maxArea;
+};
+
+#endif
--- /dev/null
+// SMESH SMESH : implementaion of SMESH idl descriptions
+//
+// Copyright (C) 2003 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
+// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
+//
+// This library 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.
+//
+// This library 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 this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+//
+// See http://www.opencascade.org/SALOME/ or email : webmaster.salome@opencascade.org
+//
+//
+//
+// File : StdMeshers_MaxElementVolume.cxx
+// Moved here from SMESH_MaxElementVolume.cxx
+// Author : Paul RASCLE, EDF
+// Module : SMESH
+// $Header$
+
+using namespace std;
+
+#include "StdMeshers_MaxElementVolume.hxx"
+#include "utilities.h"
+
+//=============================================================================
+/*!
+ *
+ */
+//=============================================================================
+
+StdMeshers_MaxElementVolume::StdMeshers_MaxElementVolume(int hypId, int studyId, SMESH_Gen* gen)
+ : SMESH_Hypothesis(hypId, studyId, gen)
+{
+ _maxVolume =1.;
+ _name = "MaxElementVolume";
+// SCRUTE(_name);
+ SCRUTE(&_name);
+ _param_algo_dim = 3;
+}
+
+//=============================================================================
+/*!
+ *
+ */
+//=============================================================================
+
+StdMeshers_MaxElementVolume::~StdMeshers_MaxElementVolume()
+{
+ MESSAGE("StdMeshers_MaxElementVolume::~StdMeshers_MaxElementVolume");
+}
+
+//=============================================================================
+/*!
+ *
+ */
+//=============================================================================
+
+void StdMeshers_MaxElementVolume::SetMaxVolume(double maxVolume)
+ throw (SALOME_Exception)
+{
+ double oldVolume = _maxVolume;
+ if (maxVolume <= 0)
+ throw SALOME_Exception(LOCALIZED("maxVolume must be positive"));
+ _maxVolume = maxVolume;
+ if (_maxVolume != oldVolume)
+ NotifySubMeshesHypothesisModification();
+}
+
+//=============================================================================
+/*!
+ *
+ */
+//=============================================================================
+
+double StdMeshers_MaxElementVolume::GetMaxVolume() const
+{
+ return _maxVolume;
+}
+
+//=============================================================================
+/*!
+ *
+ */
+//=============================================================================
+
+ostream & StdMeshers_MaxElementVolume::SaveTo(ostream & save)
+{
+ save << this->_maxVolume;
+ return save;
+}
+
+//=============================================================================
+/*!
+ *
+ */
+//=============================================================================
+
+istream & StdMeshers_MaxElementVolume::LoadFrom(istream & load)
+{
+ bool isOK = true;
+ double a;
+ isOK = (load >> a);
+ if (isOK)
+ this->_maxVolume = a;
+ else
+ load.clear(ios::badbit | load.rdstate());
+ return load;
+}
+
+//=============================================================================
+/*!
+ *
+ */
+//=============================================================================
+
+ostream & operator << (ostream & save, StdMeshers_MaxElementVolume & hyp)
+{
+ return hyp.SaveTo( save );
+}
+
+//=============================================================================
+/*!
+ *
+ */
+//=============================================================================
+
+istream & operator >> (istream & load, StdMeshers_MaxElementVolume & hyp)
+{
+ return hyp.LoadFrom( load );
+}
+
--- /dev/null
+// SMESH SMESH : implementaion of SMESH idl descriptions
+//
+// Copyright (C) 2003 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
+// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
+//
+// This library 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.
+//
+// This library 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 this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+//
+// See http://www.opencascade.org/SALOME/ or email : webmaster.salome@opencascade.org
+//
+//
+//
+// File : StdMeshers_MaxElementVolume.hxx
+// Moved here from SMESH_MaxElementVolume.hxx
+// Author : Paul RASCLE, EDF
+// Module : SMESH
+// $Header$
+
+#ifndef _SMESH_MAXELEMENTVOLUME_HXX_
+#define _SMESH_MAXELEMENTVOLUME_HXX_
+
+#include "SMESH_Hypothesis.hxx"
+#include "Utils_SALOME_Exception.hxx"
+
+class StdMeshers_MaxElementVolume:
+ public SMESH_Hypothesis
+{
+public:
+ StdMeshers_MaxElementVolume(int hypId, int studyId, SMESH_Gen* gen);
+ virtual ~StdMeshers_MaxElementVolume();
+
+ void SetMaxVolume(double maxVolume)
+ throw (SALOME_Exception);
+
+ double GetMaxVolume() const;
+
+ virtual ostream & SaveTo(ostream & save);
+ virtual istream & LoadFrom(istream & load);
+ friend ostream & operator << (ostream & save, StdMeshers_MaxElementVolume & hyp);
+ friend istream & operator >> (istream & load, StdMeshers_MaxElementVolume & hyp);
+
+protected:
+ double _maxVolume;
+};
+
+#endif
--- /dev/null
+// SMESH StdMeshers : implementaion of SMESH idl descriptions
+//
+// Copyright (C) 2003 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
+// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
+//
+// This library 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.
+//
+// This library 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 this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+//
+// See http://www.opencascade.org/SALOME/ or email : webmaster.salome@opencascade.org
+//
+//
+//
+// File : StdMeshers_NotConformAllowed.cxx
+// Author : Paul RASCLE, EDF
+// Module : SMESH
+// $Header$
+
+using namespace std;
+#include "StdMeshers_NotConformAllowed.hxx"
+#include "utilities.h"
+
+//=============================================================================
+/*!
+ *
+ */
+//=============================================================================
+
+StdMeshers_NotConformAllowed::StdMeshers_NotConformAllowed(int hypId, int studyId, SMESH_Gen* gen)
+ : SMESH_Hypothesis(hypId, studyId, gen)
+{
+ _name = "NotConformAllowed";
+ _param_algo_dim = -1;
+}
+
+//=============================================================================
+/*!
+ *
+ */
+//=============================================================================
+
+StdMeshers_NotConformAllowed::~StdMeshers_NotConformAllowed()
+{
+}
+
+//=============================================================================
+/*!
+ *
+ */
+//=============================================================================
+
+ostream & StdMeshers_NotConformAllowed::SaveTo(ostream & save)
+{
+ return save << this;
+}
+
+//=============================================================================
+/*!
+ *
+ */
+//=============================================================================
+
+istream & StdMeshers_NotConformAllowed::LoadFrom(istream & load)
+{
+ return load >> (*this);
+}
+
+//=============================================================================
+/*!
+ *
+ */
+//=============================================================================
+
+ostream & operator << (ostream & save, StdMeshers_NotConformAllowed & hyp)
+{
+ return save;
+}
+
+//=============================================================================
+/*!
+ *
+ */
+//=============================================================================
+
+istream & operator >> (istream & load, StdMeshers_NotConformAllowed & hyp)
+{
+ return load;
+}
--- /dev/null
+// SMESH StdMeshers : implementaion of SMESH idl descriptions
+//
+// Copyright (C) 2003 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
+// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
+//
+// This library 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.
+//
+// This library 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 this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+//
+// See http://www.opencascade.org/SALOME/ or email : webmaster.salome@opencascade.org
+//
+//
+//
+// File : StdMeshers_NotConformAllowed.hxx
+// Author : Paul RASCLE, EDF
+// Module : SMESH
+// $Header$
+
+#ifndef _StdMeshers_NotConformAllowed_HXX_
+#define _StdMeshers_NotConformAllowed_HXX_
+
+#include "SMESH_Hypothesis.hxx"
+#include "Utils_SALOME_Exception.hxx"
+
+class StdMeshers_NotConformAllowed:
+ public SMESH_Hypothesis
+{
+public:
+ StdMeshers_NotConformAllowed(int hypId, int studyId, SMESH_Gen* gen);
+ virtual ~StdMeshers_NotConformAllowed();
+
+ virtual ostream & SaveTo(ostream & save);
+ virtual istream & LoadFrom(istream & load);
+ friend ostream & operator << (ostream & save, StdMeshers_NotConformAllowed & hyp);
+ friend istream & operator >> (istream & load, StdMeshers_NotConformAllowed & hyp);
+};
+
+#endif
--- /dev/null
+// SMESH SMESH : implementaion of SMESH idl descriptions
+//
+// Copyright (C) 2003 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
+// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
+//
+// This library 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.
+//
+// This library 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 this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+//
+// See http://www.opencascade.org/SALOME/ or email : webmaster.salome@opencascade.org
+//
+//
+//
+// File : StdMeshers_NumberOfSegments.cxx
+// Moved here from SMESH_NumberOfSegments.cxx
+// Author : Paul RASCLE, EDF
+// Module : SMESH
+// $Header$
+
+using namespace std;
+#include "StdMeshers_NumberOfSegments.hxx"
+
+//=============================================================================
+/*!
+ *
+ */
+//=============================================================================
+
+StdMeshers_NumberOfSegments::StdMeshers_NumberOfSegments(int hypId, int studyId,
+ SMESH_Gen * gen):SMESH_Hypothesis(hypId, studyId, gen)
+{
+ _numberOfSegments = 1;
+ _scaleFactor = 1.0;
+ _name = "NumberOfSegments";
+ _param_algo_dim = 1;
+}
+
+//=============================================================================
+/*!
+ *
+ */
+//=============================================================================
+
+StdMeshers_NumberOfSegments::~StdMeshers_NumberOfSegments()
+{
+}
+
+//=============================================================================
+/*!
+ *
+ */
+//=============================================================================
+
+void StdMeshers_NumberOfSegments::SetNumberOfSegments(int segmentsNumber)
+throw(SALOME_Exception)
+{
+ int oldNumberOfSegments = _numberOfSegments;
+ if (segmentsNumber <= 0)
+ throw
+ SALOME_Exception(LOCALIZED("number of segments must be positive"));
+ _numberOfSegments = segmentsNumber;
+
+ if (oldNumberOfSegments != _numberOfSegments)
+ NotifySubMeshesHypothesisModification();
+}
+
+//=============================================================================
+/*!
+ *
+ */
+//=============================================================================
+
+int StdMeshers_NumberOfSegments::GetNumberOfSegments() const
+{
+ return _numberOfSegments;
+}
+
+//=============================================================================
+/*!
+ *
+ */
+//=============================================================================
+
+void StdMeshers_NumberOfSegments::SetScaleFactor(double scaleFactor)
+throw(SALOME_Exception)
+{
+ if (scaleFactor < 0)
+ throw SALOME_Exception(LOCALIZED("scale factor must be positive"));
+ _scaleFactor = scaleFactor;
+
+ NotifySubMeshesHypothesisModification();
+}
+
+//=============================================================================
+/*!
+ *
+ */
+//=============================================================================
+
+double StdMeshers_NumberOfSegments::GetScaleFactor() const
+{
+ return _scaleFactor;
+}
+
+//=============================================================================
+/*!
+ *
+ */
+//=============================================================================
+
+ostream & StdMeshers_NumberOfSegments::SaveTo(ostream & save)
+{
+ save << this->_numberOfSegments << " " << this->_scaleFactor;
+ return save;
+}
+
+//=============================================================================
+/*!
+ *
+ */
+//=============================================================================
+
+istream & StdMeshers_NumberOfSegments::LoadFrom(istream & load)
+{
+ bool isOK = true;
+ int a;
+ isOK = (load >> a);
+ if (isOK)
+ this->_numberOfSegments = a;
+ else
+ load.clear(ios::badbit | load.rdstate());
+ double b;
+ isOK = (load >> b);
+ if (isOK)
+ this->_scaleFactor = b;
+ else
+ load.clear(ios::badbit | load.rdstate());
+ return load;
+}
+
+//=============================================================================
+/*!
+ *
+ */
+//=============================================================================
+
+ostream & operator <<(ostream & save, StdMeshers_NumberOfSegments & hyp)
+{
+ return hyp.SaveTo( save );
+}
+
+//=============================================================================
+/*!
+ *
+ */
+//=============================================================================
+
+istream & operator >>(istream & load, StdMeshers_NumberOfSegments & hyp)
+{
+ return hyp.LoadFrom( load );
+}
--- /dev/null
+// SMESH SMESH : implementaion of SMESH idl descriptions
+//
+// Copyright (C) 2003 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
+// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
+//
+// This library 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.
+//
+// This library 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 this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+//
+// See http://www.opencascade.org/SALOME/ or email : webmaster.salome@opencascade.org
+//
+//
+//
+// File : StdMeshers_NumberOfSegments.hxx
+// Moved here from SMESH_NumberOfSegments.hxx
+// Author : Paul RASCLE, EDF
+// Module : SMESH
+// $Header$
+
+#ifndef _SMESH_NUMBEROFSEGMENTS_HXX_
+#define _SMESH_NUMBEROFSEGMENTS_HXX_
+
+#include "SMESH_Hypothesis.hxx"
+#include "Utils_SALOME_Exception.hxx"
+
+class StdMeshers_NumberOfSegments:
+ public SMESH_Hypothesis
+{
+public:
+ StdMeshers_NumberOfSegments(int hypId, int studyId, SMESH_Gen* gen);
+ virtual ~StdMeshers_NumberOfSegments();
+
+ void SetNumberOfSegments(int segmentsNumber)
+ throw (SALOME_Exception);
+
+ int GetNumberOfSegments() const;
+
+ void SetScaleFactor(double scaleFactor)
+ throw (SALOME_Exception);
+
+ double GetScaleFactor() const;
+
+ virtual ostream & SaveTo(ostream & save);
+ virtual istream & LoadFrom(istream & load);
+ friend ostream& operator << (ostream & save, StdMeshers_NumberOfSegments & hyp);
+ friend istream& operator >> (istream & load, StdMeshers_NumberOfSegments & hyp);
+
+protected:
+ int _numberOfSegments;
+ double _scaleFactor;
+};
+
+#endif
--- /dev/null
+// SMESH SMESH : implementaion of SMESH idl descriptions
+//
+// Copyright (C) 2003 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
+// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
+//
+// This library 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.
+//
+// This library 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 this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+//
+// See http://www.opencascade.org/SALOME/ or email : webmaster.salome@opencascade.org
+//
+//
+//
+// File : StdMeshers_Quadrangle_2D.cxx
+// Moved here from SMESH_Quadrangle_2D.cxx
+// Author : Paul RASCLE, EDF
+// Module : SMESH
+// $Header$
+
+using namespace std;
+#include "StdMeshers_Quadrangle_2D.hxx"
+#include "SMESH_Gen.hxx"
+#include "SMESH_Mesh.hxx"
+
+#include "SMDS_MeshElement.hxx"
+#include "SMDS_MeshNode.hxx"
+#include "SMDS_EdgePosition.hxx"
+#include "SMDS_FacePosition.hxx"
+
+#include <BRep_Tool.hxx>
+#include <BRepTools.hxx>
+#include <BRepTools_WireExplorer.hxx>
+#include <Geom_Surface.hxx>
+#include <Geom_Curve.hxx>
+#include <Geom2d_Curve.hxx>
+#include <Handle_Geom2d_Curve.hxx>
+#include <Handle_Geom_Curve.hxx>
+#include <gp_Pnt2d.hxx>
+#include <TColStd_ListIteratorOfListOfInteger.hxx>
+
+#include "utilities.h"
+#include "Utils_ExceptHandlers.hxx"
+
+
+//=============================================================================
+/*!
+ *
+ */
+//=============================================================================
+
+StdMeshers_Quadrangle_2D::StdMeshers_Quadrangle_2D(int hypId,
+ int studyId, SMESH_Gen * gen):SMESH_2D_Algo(hypId, studyId, gen)
+{
+ MESSAGE("StdMeshers_Quadrangle_2D::StdMeshers_Quadrangle_2D");
+ _name = "Quadrangle_2D";
+ // _shapeType = TopAbs_FACE;
+ _shapeType = (1 << TopAbs_FACE);
+}
+
+//=============================================================================
+/*!
+ *
+ */
+//=============================================================================
+
+StdMeshers_Quadrangle_2D::~StdMeshers_Quadrangle_2D()
+{
+ MESSAGE("StdMeshers_Quadrangle_2D::~StdMeshers_Quadrangle_2D");
+}
+
+//=============================================================================
+/*!
+ *
+ */
+//=============================================================================
+
+bool StdMeshers_Quadrangle_2D::CheckHypothesis
+ (SMESH_Mesh& aMesh,
+ const TopoDS_Shape& aShape,
+ SMESH_Hypothesis::Hypothesis_Status& aStatus)
+{
+ //MESSAGE("StdMeshers_Quadrangle_2D::CheckHypothesis");
+
+ bool isOk = true;
+ aStatus = SMESH_Hypothesis::HYP_OK;
+
+ // nothing to check
+
+ return isOk;
+}
+
+//=============================================================================
+/*!
+ *
+ */
+//=============================================================================
+
+bool StdMeshers_Quadrangle_2D::Compute(SMESH_Mesh & aMesh,
+ const TopoDS_Shape & aShape)throw(SALOME_Exception)
+{
+ Unexpect aCatch(SalomeException);
+ //MESSAGE("StdMeshers_Quadrangle_2D::Compute");
+ SMESHDS_Mesh * meshDS = aMesh.GetMeshDS();
+ SMESH_subMesh *theSubMesh = aMesh.GetSubMesh(aShape);
+
+ FaceQuadStruct *quad = CheckAnd2Dcompute(aMesh, aShape);
+ if (!quad)
+ return false;
+
+ // --- compute 3D values on points, store points & quadrangles
+
+ int nbdown = quad->nbPts[0];
+ int nbright = quad->nbPts[1];
+ int nbVertices = nbdown * nbright;
+ int nbQuad = (nbdown - 1) * (nbright - 1);
+ //SCRUTE(nbVertices);
+ //SCRUTE(nbQuad);
+
+ // const TopoDS_Face& FF = TopoDS::Face(aShape);
+ // bool faceIsForward = (FF.Orientation() == TopAbs_FORWARD);
+ // TopoDS_Face F = TopoDS::Face(FF.Oriented(TopAbs_FORWARD));
+ const TopoDS_Face & F = TopoDS::Face(aShape);
+ bool faceIsForward = (F.Orientation() == TopAbs_FORWARD);
+ Handle(Geom_Surface) S = BRep_Tool::Surface(F);
+
+ for (int i = 1; i < nbdown - 1; i++)
+ for (int j = 1; j < nbright - 1; j++) // internal points
+ {
+ int ij = j * nbdown + i;
+ double u = quad->uv_grid[ij].u;
+ double v = quad->uv_grid[ij].v;
+ gp_Pnt P = S->Value(u, v);
+ SMDS_MeshNode * node = meshDS->AddNode(P.X(), P.Y(), P.Z());
+ meshDS->SetNodeOnFace(node, F);
+ quad->uv_grid[ij].node = node;
+// Handle (SMDS_FacePosition) fpos
+// = new SMDS_FacePosition(theSubMesh->GetId(),i,j); // easier than u,v
+// node->SetPosition(fpos);
+ SMDS_FacePosition* fpos =
+ dynamic_cast<SMDS_FacePosition*>(node->GetPosition().get());
+ fpos->SetUParameter(i);
+ fpos->SetVParameter(j);
+ }
+
+ // bool isQuadForward = ( faceIsForward == quad->isEdgeForward[0]);
+ for (int i = 0; i < nbdown - 1; i++)
+ for (int j = 0; j < nbright - 1; j++) // faces
+ {
+ const SMDS_MeshNode *a, *b, *c, *d;
+ a = quad->uv_grid[j * nbdown + i].node;
+ b = quad->uv_grid[j * nbdown + i + 1].node;
+ c = quad->uv_grid[(j + 1) * nbdown + i + 1].node;
+ d = quad->uv_grid[(j + 1) * nbdown + i].node;
+ // if (isQuadForward) faceId = meshDS->AddFace(a,b,c,d);
+ // else faceId = meshDS->AddFace(a,d,c,b);
+ SMDS_MeshFace * face = meshDS->AddFace(a, b, c, d);
+ meshDS->SetMeshElementOnShape(face, F);
+ }
+
+ QuadDelete(quad);
+ bool isOk = true;
+ return isOk;
+}
+
+//=============================================================================
+/*!
+ *
+ */
+//=============================================================================
+
+FaceQuadStruct *StdMeshers_Quadrangle_2D::CheckAnd2Dcompute(SMESH_Mesh & aMesh,
+ const TopoDS_Shape & aShape)throw(SALOME_Exception)
+{
+ Unexpect aCatch(SalomeException);
+ //MESSAGE("StdMeshers_Quadrangle_2D::ComputeWithoutStore");
+
+ SMESH_subMesh *theSubMesh = aMesh.GetSubMesh(aShape);
+
+ // const TopoDS_Face& FF = TopoDS::Face(aShape);
+ // bool faceIsForward = (FF.Orientation() == TopAbs_FORWARD);
+ // TopoDS_Face F = TopoDS::Face(FF.Oriented(TopAbs_FORWARD));
+ const TopoDS_Face & F = TopoDS::Face(aShape);
+ bool faceIsForward = (F.Orientation() == TopAbs_FORWARD);
+
+ // verify 1 wire only, with 4 edges, same number of points on opposite edges
+
+ if (NumberOfWires(F) != 1)
+ {
+ MESSAGE("only 1 wire by face (quadrangles)");
+ return 0;
+ //throw SALOME_Exception(LOCALIZED("only 1 wire by face (quadrangles)"));
+ }
+ // const TopoDS_Wire WW = BRepTools::OuterWire(F);
+ // TopoDS_Wire W = TopoDS::Wire(WW.Oriented(TopAbs_FORWARD));
+ const TopoDS_Wire & W = BRepTools::OuterWire(F);
+ BRepTools_WireExplorer wexp(W, F);
+
+ FaceQuadStruct *quad = new FaceQuadStruct;
+ for (int i = 0; i < 4; i++)
+ quad->uv_edges[i] = 0;
+ quad->uv_grid = 0;
+
+ int nbEdges = 0;
+ for (wexp.Init(W, F); wexp.More(); wexp.Next())
+ {
+ // const TopoDS_Edge& EE = wexp.Current();
+ // TopoDS_Edge E = TopoDS::Edge(EE.Oriented(TopAbs_FORWARD));
+ const TopoDS_Edge & E = wexp.Current();
+ int nb = aMesh.GetSubMesh(E)->GetSubMeshDS()->NbNodes();
+ if (nbEdges < 4)
+ {
+ quad->edge[nbEdges] = E;
+ quad->nbPts[nbEdges] = nb + 2; // internal points + 2 extrema
+ }
+ nbEdges++;
+ }
+
+ if (nbEdges != 4)
+ {
+ MESSAGE("face must have 4 edges /quadrangles");
+ QuadDelete(quad);
+ return 0;
+ //throw SALOME_Exception(LOCALIZED("face must have 4 edges /quadrangles"));
+ }
+
+ if (quad->nbPts[0] != quad->nbPts[2])
+ {
+ MESSAGE("different point number-opposed edge");
+ QuadDelete(quad);
+ return 0;
+ //throw SALOME_Exception(LOCALIZED("different point number-opposed edge"));
+ }
+
+ if (quad->nbPts[1] != quad->nbPts[3])
+ {
+ MESSAGE("different point number-opposed edge");
+ QuadDelete(quad);
+ return 0;
+ //throw SALOME_Exception(LOCALIZED("different point number-opposed edge"));
+ }
+
+ // set normalized grid on unit square in parametric domain
+
+ SetNormalizedGrid(aMesh, F, quad);
+
+ return quad;
+}
+
+//=============================================================================
+/*!
+ *
+ */
+//=============================================================================
+
+void StdMeshers_Quadrangle_2D::QuadDelete(FaceQuadStruct * quad)
+{
+ //MESSAGE("StdMeshers_Quadrangle_2D::QuadDelete");
+ if (quad)
+ {
+ for (int i = 0; i < 4; i++)
+ {
+ if (quad->uv_edges[i])
+ delete[]quad->uv_edges[i];
+ quad->edge[i].Nullify();
+ }
+ if (quad->uv_grid)
+ delete[]quad->uv_grid;
+ delete quad;
+ }
+}
+
+//=============================================================================
+/*!
+ *
+ */
+//=============================================================================
+
+void StdMeshers_Quadrangle_2D::SetNormalizedGrid(SMESH_Mesh & aMesh,
+ const TopoDS_Shape & aShape, FaceQuadStruct * quad) throw(SALOME_Exception)
+{
+ Unexpect aCatch(SalomeException);
+ // Algorithme décrit dans "Génération automatique de maillages"
+ // P.L. GEORGE, MASSON, § 6.4.1 p. 84-85
+ // traitement dans le domaine paramétrique 2d u,v
+ // transport - projection sur le carré unité
+
+ const TopoDS_Face & F = TopoDS::Face(aShape);
+
+ // 1 --- find orientation of the 4 edges, by test on extrema
+
+ // max min 0 x1 1
+ // |<----north-2-------^ a3 -------------> a2
+ // | | ^1 1^
+ // west-3 east-1 =right | |
+ // | | ==> | |
+ // y0 | | y1 | |
+ // | | |0 0|
+ // v----south-0--------> a0 -------------> a1
+ // min max 0 x0 1
+ // =down
+ //
+
+ Handle(Geom2d_Curve) c2d[4];
+ gp_Pnt2d pf[4];
+ gp_Pnt2d pl[4];
+ for (int i = 0; i < 4; i++)
+ {
+ c2d[i] = BRep_Tool::CurveOnSurface(quad->edge[i],
+ F, quad->first[i], quad->last[i]);
+ pf[i] = c2d[i]->Value(quad->first[i]);
+ pl[i] = c2d[i]->Value(quad->last[i]);
+ quad->isEdgeForward[i] = false;
+ }
+
+ double eps2d = 1.e-3; // *** utiliser plutot TopExp::CommonVertex, puis
+ // distances si piece fausse
+ int i = 0;
+ if ((pf[1].Distance(pl[0]) < eps2d) || (pl[1].Distance(pl[0]) < eps2d))
+ {
+ quad->isEdgeForward[0] = true;
+ }
+ else
+ {
+ double tmp = quad->first[0];
+ quad->first[0] = quad->last[0];
+ quad->last[0] = tmp;
+ pf[0] = c2d[0]->Value(quad->first[0]);
+ pl[0] = c2d[0]->Value(quad->last[0]);
+ }
+ for (int i = 1; i < 4; i++)
+ {
+ quad->isEdgeForward[i] = (pf[i].Distance(pl[i - 1]) < eps2d);
+ if (!quad->isEdgeForward[i])
+ {
+ double tmp = quad->first[i];
+ quad->first[i] = quad->last[i];
+ quad->last[i] = tmp;
+ pf[i] = c2d[i]->Value(quad->first[i]);
+ pl[i] = c2d[i]->Value(quad->last[i]);
+ //SCRUTE(pf[i].Distance(pl[i-1]));
+ ASSERT(pf[i].Distance(pl[i - 1]) < eps2d);
+ }
+ }
+ //SCRUTE(pf[0].Distance(pl[3]));
+ ASSERT(pf[0].Distance(pl[3]) < eps2d);
+
+// for (int i=0; i<4; i++)
+// {
+// SCRUTE(quad->isEdgeForward[i]);
+// MESSAGE(" -first "<<i<<" "<<pf[i].X()<<" "<<pf[i].Y());
+// MESSAGE(" -last "<<i<<" "<<pl[i].X()<<" "<<pl[i].Y());
+// }
+
+ // 2 --- load 2d edge points (u,v) with orientation and value on unit square
+
+ for (int i = 0; i < 2; i++)
+ {
+ quad->uv_edges[i] = LoadEdgePoints(aMesh, F,
+ quad->edge[i], quad->first[i], quad->last[i]);
+
+ // quad->isEdgeForward[i]);
+ }
+ for (int i = 2; i < 4; i++)
+ {
+ quad->uv_edges[i] = LoadEdgePoints(aMesh, F,
+ quad->edge[i], quad->last[i], quad->first[i]);
+
+ // !quad->isEdgeForward[i]);
+ }
+
+ // 3 --- 2D normalized values on unit square [0..1][0..1]
+
+ int nbdown = quad->nbPts[0];
+ int nbright = quad->nbPts[1];
+ quad->uv_grid = new UVPtStruct[nbright * nbdown];
+
+ UVPtStruct *uv_grid = quad->uv_grid;
+ UVPtStruct *uv_e0 = quad->uv_edges[0];
+ UVPtStruct *uv_e1 = quad->uv_edges[1];
+ UVPtStruct *uv_e2 = quad->uv_edges[2];
+ UVPtStruct *uv_e3 = quad->uv_edges[3];
+ gp_Pnt2d a0 = pf[0];
+ gp_Pnt2d a1 = pf[1];
+ gp_Pnt2d a2 = pf[2];
+ gp_Pnt2d a3 = pf[3];
+
+ // nodes Id on edges
+
+ int j = 0;
+ for (int i = 0; i < nbdown; i++)
+ {
+ int ij = j * nbdown + i;
+ uv_grid[ij].node = uv_e0[i].node;
+ }
+ i = nbdown - 1;
+ for (int j = 0; j < nbright; j++)
+ {
+ int ij = j * nbdown + i;
+ uv_grid[ij].node = uv_e1[j].node;
+ }
+ j = nbright - 1;
+ for (int i = 0; i < nbdown; i++)
+ {
+ int ij = j * nbdown + i;
+ uv_grid[ij].node = uv_e2[i].node;
+ }
+ i = 0;
+ for (int j = 0; j < nbright; j++)
+ {
+ int ij = j * nbdown + i;
+ uv_grid[ij].node = uv_e3[j].node;
+ }
+
+ // normalized 2d values on grid
+
+ for (int i = 0; i < nbdown; i++)
+ for (int j = 0; j < nbright; j++)
+ {
+ int ij = j * nbdown + i;
+ // --- droite i cste : x = x0 + y(x1-x0)
+ double x0 = uv_e0[i].normParam; // bas - sud
+ double x1 = uv_e2[i].normParam; // haut - nord
+ // --- droite j cste : y = y0 + x(y1-y0)
+ double y0 = uv_e3[j].normParam; // gauche-ouest
+ double y1 = uv_e1[j].normParam; // droite - est
+ // --- intersection : x=x0+(y0+x(y1-y0))(x1-x0)
+ double x = (x0 + y0 * (x1 - x0)) / (1 - (y1 - y0) * (x1 - x0));
+ double y = y0 + x * (y1 - y0);
+ uv_grid[ij].x = x;
+ uv_grid[ij].y = y;
+ //MESSAGE("-xy-01 "<<x0<<" "<<x1<<" "<<y0<<" "<<y1);
+ //MESSAGE("-xy-norm "<<i<<" "<<j<<" "<<x<<" "<<y);
+ }
+
+ // 4 --- projection on 2d domain (u,v)
+
+ for (int i = 0; i < nbdown; i++)
+ for (int j = 0; j < nbright; j++)
+ {
+ int ij = j * nbdown + i;
+ double x = uv_grid[ij].x;
+ double y = uv_grid[ij].y;
+ double param_0 = uv_e0[0].param + x * (uv_e0[nbdown - 1].param - uv_e0[0].param); // sud
+ double param_2 = uv_e2[0].param + x * (uv_e2[nbdown - 1].param - uv_e2[0].param); // nord
+ double param_1 = uv_e1[0].param + y * (uv_e1[nbright - 1].param - uv_e1[0].param); // est
+ double param_3 = uv_e3[0].param + y * (uv_e3[nbright - 1].param - uv_e3[0].param); // ouest
+
+ //MESSAGE("params "<<param_0<<" "<<param_1<<" "<<param_2<<" "<<param_3);
+ gp_Pnt2d p0 = c2d[0]->Value(param_0);
+ gp_Pnt2d p1 = c2d[1]->Value(param_1);
+ gp_Pnt2d p2 = c2d[2]->Value(param_2);
+ gp_Pnt2d p3 = c2d[3]->Value(param_3);
+
+ double u =
+ (1 - y) * p0.X() + x * p1.X() + y * p2.X() + (1 - x) * p3.X();
+ double v =
+ (1 - y) * p0.Y() + x * p1.Y() + y * p2.Y() + (1 - x) * p3.Y();
+
+ u -= (1 - x) * (1 - y) * a0.X() + x * (1 - y) * a1.X() +
+ x * y * a2.X() + (1 - x) * y * a3.X();
+ v -= (1 - x) * (1 - y) * a0.Y() + x * (1 - y) * a1.Y() +
+ x * y * a2.Y() + (1 - x) * y * a3.Y();
+
+ uv_grid[ij].u = u;
+ uv_grid[ij].v = v;
+
+ //MESSAGE("-uv- "<<i<<" "<<j<<" "<<uv_grid[ij].u<<" "<<uv_grid[ij].v);
+ }
+}
+
+//=============================================================================
+/*!
+ *
+ */
+//=============================================================================
+
+UVPtStruct *StdMeshers_Quadrangle_2D::LoadEdgePoints(SMESH_Mesh & aMesh,
+ const TopoDS_Face & F, const TopoDS_Edge & E, double first, double last)
+ // bool isForward)
+{
+ //MESSAGE("StdMeshers_Quadrangle_2D::LoadEdgePoints");
+
+ SMDS_Mesh * meshDS = aMesh.GetMeshDS();
+
+ // --- IDNodes of first and last Vertex
+
+ TopoDS_Vertex VFirst, VLast;
+ TopExp::Vertices(E, VFirst, VLast); // corresponds to f and l
+
+ ASSERT(!VFirst.IsNull());
+ SMDS_NodeIteratorPtr lid= aMesh.GetSubMesh(VFirst)->GetSubMeshDS()->GetNodes();
+ const SMDS_MeshNode * idFirst = lid->next();
+
+ ASSERT(!VLast.IsNull());
+ lid=aMesh.GetSubMesh(VLast)->GetSubMeshDS()->GetNodes();
+ const SMDS_MeshNode * idLast = lid->next();
+
+ // --- edge internal IDNodes (relies on good order storage, not checked)
+
+ int nbPoints = aMesh.GetSubMesh(E)->GetSubMeshDS()->NbNodes();
+ //SCRUTE(nbPoints);
+ UVPtStruct *uvslf = new UVPtStruct[nbPoints + 2];
+
+ double f, l;
+ Handle(Geom2d_Curve) C2d = BRep_Tool::CurveOnSurface(E, F, f, l);
+
+ map<double, const SMDS_MeshNode *> params;
+ SMDS_NodeIteratorPtr ite= aMesh.GetSubMesh(E)->GetSubMeshDS()->GetNodes();
+
+ while(ite->more())
+ {
+ const SMDS_MeshNode * node = ite->next();
+ const SMDS_EdgePosition* epos =
+ static_cast<const SMDS_EdgePosition*>(node->GetPosition().get());
+ double param = epos->GetUParameter();
+ params[param] = node;
+ }
+
+ bool isForward = (((l - f) * (last - first)) > 0);
+ double paramin = 0;
+ double paramax = 0;
+ if (isForward)
+ {
+ paramin = f;
+ paramax = l;
+ gp_Pnt2d p = C2d->Value(f); // first point = Vertex Forward
+ uvslf[0].x = p.X();
+ uvslf[0].y = p.Y();
+ uvslf[0].param = f;
+ uvslf[0].node = idFirst;
+ //MESSAGE("__ f "<<f<<" "<<uvslf[0].x <<" "<<uvslf[0].y);
+ map < double, const SMDS_MeshNode* >::iterator itp = params.begin();
+ for (int i = 1; i <= nbPoints; i++) // nbPoints internal
+ {
+ double param = (*itp).first;
+ gp_Pnt2d p = C2d->Value(param);
+ uvslf[i].x = p.X();
+ uvslf[i].y = p.Y();
+ uvslf[i].param = param;
+ uvslf[i].node = (*itp).second;
+ //MESSAGE("__ "<<i<<" "<<param<<" "<<uvslf[i].x <<" "<<uvslf[i].y);
+ itp++;
+ }
+ p = C2d->Value(l); // last point = Vertex Reversed
+ uvslf[nbPoints + 1].x = p.X();
+ uvslf[nbPoints + 1].y = p.Y();
+ uvslf[nbPoints + 1].param = l;
+ uvslf[nbPoints + 1].node = idLast;
+ //MESSAGE("__ l "<<l<<" "<<uvslf[nbPoints+1].x <<" "<<uvslf[nbPoints+1].y);
+ }
+ else
+ {
+ paramin = l;
+ paramax = f;
+ gp_Pnt2d p = C2d->Value(l); // first point = Vertex Reversed
+ uvslf[0].x = p.X();
+ uvslf[0].y = p.Y();
+ uvslf[0].param = l;
+ uvslf[0].node = idLast;
+ //MESSAGE("__ l "<<l<<" "<<uvslf[0].x <<" "<<uvslf[0].y);
+ map < double, const SMDS_MeshNode* >::reverse_iterator itp = params.rbegin();
+ for (int j = nbPoints; j >= 1; j--) // nbPoints internal
+ {
+ double param = (*itp).first;
+ int i = nbPoints + 1 - j;
+ gp_Pnt2d p = C2d->Value(param);
+ uvslf[i].x = p.X();
+ uvslf[i].y = p.Y();
+ uvslf[i].param = param;
+ uvslf[i].node = (*itp).second;
+ //MESSAGE("__ "<<i<<" "<<param<<" "<<uvslf[i].x <<" "<<uvslf[i].y);
+ itp++;
+ }
+ p = C2d->Value(f); // last point = Vertex Forward
+ uvslf[nbPoints + 1].x = p.X();
+ uvslf[nbPoints + 1].y = p.Y();
+ uvslf[nbPoints + 1].param = f;
+ uvslf[nbPoints + 1].node = idFirst;
+ //MESSAGE("__ f "<<f<<" "<<uvslf[nbPoints+1].x <<" "<<uvslf[nbPoints+1].y);
+ }
+
+ ASSERT(paramin != paramax);
+ for (int i = 0; i < nbPoints + 2; i++)
+ {
+ uvslf[i].normParam = (uvslf[i].param - paramin) / (paramax - paramin);
+ //SCRUTE(uvslf[i].normParam);
+ }
+
+ return uvslf;
+}
+
+//=============================================================================
+/*!
+ *
+ */
+//=============================================================================
+
+ostream & StdMeshers_Quadrangle_2D::SaveTo(ostream & save)
+{
+ return save;
+}
+
+//=============================================================================
+/*!
+ *
+ */
+//=============================================================================
+
+istream & StdMeshers_Quadrangle_2D::LoadFrom(istream & load)
+{
+ return load;
+}
+
+//=============================================================================
+/*!
+ *
+ */
+//=============================================================================
+
+ostream & operator <<(ostream & save, StdMeshers_Quadrangle_2D & hyp)
+{
+ return hyp.SaveTo( save );
+}
+
+//=============================================================================
+/*!
+ *
+ */
+//=============================================================================
+
+istream & operator >>(istream & load, StdMeshers_Quadrangle_2D & hyp)
+{
+ return hyp.LoadFrom( load );
+}
--- /dev/null
+// SMESH SMESH : implementaion of SMESH idl descriptions
+//
+// Copyright (C) 2003 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
+// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
+//
+// This library 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.
+//
+// This library 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 this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+//
+// See http://www.opencascade.org/SALOME/ or email : webmaster.salome@opencascade.org
+//
+//
+//
+// File : StdMeshers_Quadrangle_2D.hxx
+// Moved here from SMESH_Quadrangle_2D.hxx
+// Author : Paul RASCLE, EDF
+// Module : SMESH
+// $Header$
+
+#ifndef _SMESH_QUADRANGLE_2D_HXX_
+#define _SMESH_QUADRANGLE_2D_HXX_
+
+#include "SMESH_2D_Algo.hxx"
+#include "SMESH_Mesh.hxx"
+#include "Utils_SALOME_Exception.hxx"
+
+typedef struct uvPtStruct
+{
+ double param;
+ double normParam;
+ double u; // original 2d parameter
+ double v;
+ double x; // 2d parameter, normalized [0,1]
+ double y;
+ const SMDS_MeshNode * node;
+} UVPtStruct;
+
+typedef struct faceQuadStruct
+{
+ int nbPts[4];
+ TopoDS_Edge edge[4];
+ double first[4];
+ double last[4];
+ bool isEdgeForward[4];
+ UVPtStruct* uv_edges[4];
+ UVPtStruct* uv_grid;
+} FaceQuadStruct;
+
+class StdMeshers_Quadrangle_2D:
+ public SMESH_2D_Algo
+{
+public:
+ StdMeshers_Quadrangle_2D(int hypId, int studyId, SMESH_Gen* gen);
+ virtual ~StdMeshers_Quadrangle_2D();
+
+ virtual bool CheckHypothesis(SMESH_Mesh& aMesh,
+ const TopoDS_Shape& aShape,
+ SMESH_Hypothesis::Hypothesis_Status& aStatus);
+
+ virtual bool Compute(SMESH_Mesh& aMesh,
+ const TopoDS_Shape& aShape)
+ throw (SALOME_Exception);
+
+ FaceQuadStruct* CheckAnd2Dcompute(SMESH_Mesh& aMesh,
+ const TopoDS_Shape& aShape)
+ throw (SALOME_Exception);
+
+ void QuadDelete(FaceQuadStruct* quad);
+
+ ostream & SaveTo(ostream & save);
+ istream & LoadFrom(istream & load);
+ friend ostream & operator << (ostream & save, StdMeshers_Quadrangle_2D & hyp);
+ friend istream & operator >> (istream & load, StdMeshers_Quadrangle_2D & hyp);
+
+protected:
+
+ void SetNormalizedGrid(SMESH_Mesh& aMesh,
+ const TopoDS_Shape& aShape,
+ FaceQuadStruct* quad)
+ throw (SALOME_Exception);
+
+ UVPtStruct* LoadEdgePoints(SMESH_Mesh& aMesh,
+ const TopoDS_Face& F,
+ const TopoDS_Edge& E,
+ double first,
+ double last);
+// bool isForward);
+
+// FaceQuadStruct _quadDesc;
+};
+
+#endif
--- /dev/null
+// SMESH SMESH : implementaion of SMESH idl descriptions
+//
+// Copyright (C) 2003 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
+// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
+//
+// This library 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.
+//
+// This library 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 this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+//
+// See http://www.opencascade.org/SALOME/ or email : webmaster.salome@opencascade.org
+//
+//
+//
+// File : StdMeshers_Regular_1D.cxx
+// Moved here from SMESH_Regular_1D.cxx
+// Author : Paul RASCLE, EDF
+// Module : SMESH
+// $Header$
+
+using namespace std;
+
+#include "StdMeshers_Regular_1D.hxx"
+#include "SMESH_Gen.hxx"
+#include "SMESH_Mesh.hxx"
+
+#include "StdMeshers_LocalLength.hxx"
+#include "StdMeshers_NumberOfSegments.hxx"
+
+#include "SMDS_MeshElement.hxx"
+#include "SMDS_MeshNode.hxx"
+#include "SMDS_EdgePosition.hxx"
+
+#include "utilities.h"
+
+#include <TopoDS_Edge.hxx>
+#include <TopoDS_Shape.hxx>
+#include <GeomAdaptor_Curve.hxx>
+#include <BRep_Tool.hxx>
+#include <GCPnts_AbscissaPoint.hxx>
+#include <GCPnts_UniformAbscissa.hxx>
+
+#include <string>
+#include <algorithm>
+
+//=============================================================================
+/*!
+ *
+ */
+//=============================================================================
+
+StdMeshers_Regular_1D::StdMeshers_Regular_1D(int hypId, int studyId,
+ SMESH_Gen * gen):SMESH_1D_Algo(hypId, studyId, gen)
+{
+ MESSAGE("StdMeshers_Regular_1D::StdMeshers_Regular_1D");
+ _name = "Regular_1D";
+ // _shapeType = TopAbs_EDGE;
+ _shapeType = (1 << TopAbs_EDGE);
+ _compatibleHypothesis.push_back("LocalLength");
+ _compatibleHypothesis.push_back("NumberOfSegments");
+
+ _localLength = 0;
+ _numberOfSegments = 0;
+ _hypLocalLength = NULL;
+ _hypNumberOfSegments = NULL;
+}
+
+//=============================================================================
+/*!
+ *
+ */
+//=============================================================================
+
+StdMeshers_Regular_1D::~StdMeshers_Regular_1D()
+{
+}
+
+//=============================================================================
+/*!
+ *
+ */
+//=============================================================================
+
+bool StdMeshers_Regular_1D::CheckHypothesis
+ (SMESH_Mesh& aMesh,
+ const TopoDS_Shape& aShape,
+ SMESH_Hypothesis::Hypothesis_Status& aStatus)
+{
+ //MESSAGE("StdMeshers_Regular_1D::CheckHypothesis");
+
+ list <const SMESHDS_Hypothesis * >::const_iterator itl;
+ const SMESHDS_Hypothesis *theHyp;
+
+ const list <const SMESHDS_Hypothesis * >&hyps = GetUsedHypothesis(aMesh, aShape);
+ int nbHyp = hyps.size();
+ if (!nbHyp)
+ {
+ aStatus = SMESH_Hypothesis::HYP_MISSING;
+ return false; // can't work with no hypothesis
+ }
+
+ itl = hyps.begin();
+ theHyp = (*itl); // use only the first hypothesis
+
+ string hypName = theHyp->GetName();
+ int hypId = theHyp->GetID();
+ //SCRUTE(hypName);
+
+ bool isOk = false;
+
+ if (hypName == "LocalLength")
+ {
+ _hypLocalLength = dynamic_cast <const StdMeshers_LocalLength * >(theHyp);
+ ASSERT(_hypLocalLength);
+ _localLength = _hypLocalLength->GetLength();
+ _numberOfSegments = 0;
+ isOk = true;
+ aStatus = SMESH_Hypothesis::HYP_OK;
+ }
+
+ else if (hypName == "NumberOfSegments")
+ {
+ _hypNumberOfSegments =
+ dynamic_cast <const StdMeshers_NumberOfSegments * >(theHyp);
+ ASSERT(_hypNumberOfSegments);
+ _numberOfSegments = _hypNumberOfSegments->GetNumberOfSegments();
+ _scaleFactor = _hypNumberOfSegments->GetScaleFactor();
+ _localLength = 0;
+ isOk = true;
+ aStatus = SMESH_Hypothesis::HYP_OK;
+ }
+ else
+ aStatus = SMESH_Hypothesis::HYP_INCOMPATIBLE;
+
+ //SCRUTE(_localLength);
+ //SCRUTE(_numberOfSegments);
+
+ return isOk;
+}
+
+//=============================================================================
+/*!
+ *
+ */
+//=============================================================================
+
+bool StdMeshers_Regular_1D::Compute(SMESH_Mesh & aMesh, const TopoDS_Shape & aShape)
+{
+ MESSAGE("StdMeshers_Regular_1D::Compute");
+
+ SMESHDS_Mesh * meshDS = aMesh.GetMeshDS();
+ SMESH_subMesh *theSubMesh = aMesh.GetSubMesh(aShape);
+
+ const TopoDS_Edge & EE = TopoDS::Edge(aShape);
+ TopoDS_Edge E = TopoDS::Edge(EE.Oriented(TopAbs_FORWARD));
+
+ double f, l;
+ Handle(Geom_Curve) Curve = BRep_Tool::Curve(E, f, l);
+
+ TopoDS_Vertex VFirst, VLast;
+ TopExp::Vertices(E, VFirst, VLast); // Vfirst corresponds to f and Vlast to l
+
+ double length = EdgeLength(E);
+ //SCRUTE(length);
+
+ double eltSize = 1;
+// if (_localLength > 0) eltSize = _localLength;
+ if (_localLength > 0)
+ {
+ double nbseg = ceil(length / _localLength); // integer sup
+ if (nbseg <= 0)
+ nbseg = 1; // degenerated edge
+ eltSize = length / nbseg;
+ }
+ else
+ {
+ ASSERT(_numberOfSegments > 0);
+ eltSize = length / _numberOfSegments;
+ }
+
+ ASSERT(!VFirst.IsNull());
+ SMDS_NodeIteratorPtr lid= aMesh.GetSubMesh(VFirst)->GetSubMeshDS()->GetNodes();
+ const SMDS_MeshNode * idFirst = lid->next();
+
+ ASSERT(!VLast.IsNull());
+ lid=aMesh.GetSubMesh(VLast)->GetSubMeshDS()->GetNodes();
+ const SMDS_MeshNode * idLast = lid->next();
+
+ if (!Curve.IsNull())
+ {
+ GeomAdaptor_Curve C3d(Curve);
+ GCPnts_UniformAbscissa Discret(C3d, eltSize, f, l);
+ int NbPoints = Discret.NbPoints();
+ //MESSAGE("nb points on edge : "<<NbPoints);
+
+ // edge extrema (indexes : 1 & NbPoints) already in SMDS (TopoDS_Vertex)
+ // only internal nodes receive an edge position with param on curve
+
+ const SMDS_MeshNode * idPrev = idFirst;
+ for (int i = 2; i < NbPoints; i++)
+ {
+ double param = Discret.Parameter(i);
+
+ if (_numberOfSegments > 1)
+ {
+ double epsilon = 0.001;
+ if (fabs(_scaleFactor - 1.0) > epsilon)
+ {
+ double alpha =
+ pow(_scaleFactor, 1.0 / (_numberOfSegments - 1));
+ double d =
+ length * (1 - pow(alpha, i - 1)) / (1 - pow(alpha,
+ _numberOfSegments));
+ param = d;
+ }
+ }
+
+ gp_Pnt P = Curve->Value(param);
+
+ //Add the Node in the DataStructure
+ //MESSAGE("point "<<nodeId<<" "<<P.X()<<" "<<P.Y()<<" "<<P.Z()<<" - "<<i<<" "<<param);
+ SMDS_MeshNode * node = meshDS->AddNode(P.X(), P.Y(), P.Z());
+ meshDS->SetNodeOnEdge(node, E);
+
+ // **** edgePosition associe au point = param.
+ SMDS_EdgePosition* epos =
+ dynamic_cast<SMDS_EdgePosition *>(node->GetPosition().get());
+ epos->SetUParameter(param);
+
+ SMDS_MeshEdge * edge = meshDS->AddEdge(idPrev, node);
+ meshDS->SetMeshElementOnShape(edge, E);
+ idPrev = node;
+ }
+ SMDS_MeshEdge* edge = meshDS->AddEdge(idPrev, idLast);
+ meshDS->SetMeshElementOnShape(edge, E);
+ }
+ else
+ {
+// MESSAGE ("Edge Degeneree non traitee --- arret");
+// ASSERT(0);
+ if (BRep_Tool::Degenerated(E))
+ {
+ // Edge is a degenerated Edge : We put n = 5 points on the edge.
+ int NbPoints = 5;
+ BRep_Tool::Range(E, f, l);
+ double du = (l - f) / (NbPoints - 1);
+ MESSAGE("************* Degenerated edge! *****************");
+
+ TopoDS_Vertex V1, V2;
+ TopExp::Vertices(E, V1, V2);
+ gp_Pnt P = BRep_Tool::Pnt(V1);
+
+ const SMDS_MeshNode * idPrev = idFirst;
+ for (int i = 2; i < NbPoints; i++)
+ {
+ double param = f + (i - 1) * du;
+ SMDS_MeshNode * node = meshDS->AddNode(P.X(), P.Y(), P.Z());
+ meshDS->SetNodeOnEdge(node, E);
+
+// Handle (SMDS_EdgePosition) epos
+// = new SMDS_EdgePosition(theSubMesh->GetId(),param);
+// node->SetPosition(epos);
+ SMDS_EdgePosition* epos =
+ dynamic_cast<SMDS_EdgePosition*>(node->GetPosition().get());
+ epos->SetUParameter(param);
+
+ SMDS_MeshEdge * edge = meshDS->AddEdge(idPrev, node);
+ meshDS->SetMeshElementOnShape(edge, E);
+ idPrev = node;
+ }
+ SMDS_MeshEdge * edge = meshDS->AddEdge(idPrev, idLast);
+ meshDS->SetMeshElementOnShape(edge, E);
+ }
+ else
+ ASSERT(0);
+ }
+ return true;
+}
+
+//=============================================================================
+/*!
+ *
+ */
+//=============================================================================
+
+ostream & StdMeshers_Regular_1D::SaveTo(ostream & save)
+{
+ return save;
+}
+
+//=============================================================================
+/*!
+ *
+ */
+//=============================================================================
+
+istream & StdMeshers_Regular_1D::LoadFrom(istream & load)
+{
+ return load;
+}
+
+//=============================================================================
+/*!
+ *
+ */
+//=============================================================================
+
+ostream & operator <<(ostream & save, StdMeshers_Regular_1D & hyp)
+{
+ return hyp.SaveTo( save );
+}
+
+//=============================================================================
+/*!
+ *
+ */
+//=============================================================================
+
+istream & operator >>(istream & load, StdMeshers_Regular_1D & hyp)
+{
+ return hyp.LoadFrom( load );
+}
--- /dev/null
+// SMESH SMESH : implementaion of SMESH idl descriptions
+//
+// Copyright (C) 2003 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
+// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
+//
+// This library 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.
+//
+// This library 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 this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+//
+// See http://www.opencascade.org/SALOME/ or email : webmaster.salome@opencascade.org
+//
+//
+//
+// File : StdMeshers_Regular_1D.hxx
+// Moved here from SMESH_Regular_1D.hxx
+// Author : Paul RASCLE, EDF
+// Module : SMESH
+// $Header$
+
+#ifndef _SMESH_REGULAR_1D_HXX_
+#define _SMESH_REGULAR_1D_HXX_
+
+#include "SMESH_1D_Algo.hxx"
+
+class StdMeshers_LocalLength;
+class StdMeshers_NumberOfSegments;
+
+class StdMeshers_Regular_1D:
+ public SMESH_1D_Algo
+{
+public:
+ StdMeshers_Regular_1D(int hypId, int studyId, SMESH_Gen* gen);
+ virtual ~StdMeshers_Regular_1D();
+
+ virtual bool CheckHypothesis(SMESH_Mesh& aMesh,
+ const TopoDS_Shape& aShape,
+ SMESH_Hypothesis::Hypothesis_Status& aStatus);
+
+ virtual bool Compute(SMESH_Mesh& aMesh,
+ const TopoDS_Shape& aShape);
+
+ ostream & SaveTo(ostream & save);
+ istream & LoadFrom(istream & load);
+ friend ostream & operator << (ostream & save, StdMeshers_Regular_1D & hyp);
+ friend istream & operator >> (istream & load, StdMeshers_Regular_1D & hyp);
+
+protected:
+ double _localLength;
+ int _numberOfSegments;
+ double _scaleFactor;
+ const StdMeshers_LocalLength* _hypLocalLength;
+ const StdMeshers_NumberOfSegments* _hypNumberOfSegments;
+};
+
+#endif
--- /dev/null
+# SMESH StdMeshersGUI : GUI for StdMeshers plugin
+#
+# Copyright (C) 2003 CEA
+#
+# This library 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.
+#
+# This library 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 this library; if not, write to the Free Software
+# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+#
+# See http://www.salome-platform.org or email : webmaster.salome@opencascade.org
+#
+#
+#
+# File : Makefile.in
+# Author : Julia DOROVSKIKH
+# Module : SMESH
+# $Header$
+
+top_srcdir=@top_srcdir@
+top_builddir=../..
+srcdir=@srcdir@
+VPATH=.:@srcdir@:@top_srcdir@/idl:$(top_builddir)/idl:${KERNEL_ROOT_DIR}/idl/salome:${MED_ROOT_DIR}/idl/salome
+
+
+@COMMENCE@
+
+# .po files to transform in .qm
+ PO_FILES = \
+ StdMeshers_icons.po \
+ StdMeshers_msg_en.po
+
+# Libraries targets
+LIB = libStdMeshersGUI.la
+LIB_SRC = \
+ StdMeshersGUI.cxx \
+ StdMeshersGUI_LocalLengthDlg.cxx \
+ StdMeshersGUI_NbSegmentsDlg.cxx \
+ StdMeshersGUI_MaxElementAreaDlg.cxx \
+ StdMeshersGUI_MaxElementVolumeDlg.cxx
+
+LIB_MOC = \
+ StdMeshersGUI_LocalLengthDlg.h \
+ StdMeshersGUI_NbSegmentsDlg.h \
+ StdMeshersGUI_MaxElementAreaDlg.h \
+ StdMeshersGUI_MaxElementVolumeDlg.h
+
+LIB_CLIENT_IDL = \
+ SALOME_Exception.idl \
+ SMESH_Gen.idl \
+ SMESH_Mesh.idl \
+ SMESH_Group.idl \
+ SMESH_Filter.idl \
+ SMESH_Hypothesis.idl \
+ SMESH_BasicHypothesis.idl \
+ MED.idl
+
+LIB_SERVER_IDL =
+
+# additionnal information to compil and link file
+
+CPPFLAGS += $(QT_INCLUDES) $(VTK_INCLUDES) $(OGL_INCLUDES) $(OCC_INCLUDES) $(PYTHON_INCLUDES) \
+ $(MED2_INCLUDES) -I${KERNEL_ROOT_DIR}/include/salome -I${GEOM_ROOT_DIR}/include/salome \
+ $(BOOST_CPPFLAGS)
+CXXFLAGS += -I${KERNEL_ROOT_DIR}/include/salome -I${GEOM_ROOT_DIR}/include/salome
+#$(OCC_CXXFLAGS)
+
+LDFLAGS += -lSMESHGUI $(OCC_KERNEL_LIBS) -L${KERNEL_ROOT_DIR}/lib/salome -L${GEOM_ROOT_DIR}/lib/salome
+
+@CONCLUDE@
--- /dev/null
+// SMESH StdMeshersGUI : GUI for plugged-in meshers
+//
+// Copyright (C) 2003 CEA
+//
+// This library 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.
+//
+// This library 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 this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+//
+// See http://www.salome-platform.org or email : webmaster.salome@opencascade.org
+//
+//
+//
+// File : StdMeshersGUI.cxx
+// Author : Julia DOROVSKIKH
+// Module : SMESH
+// $Header$
+
+using namespace std;
+
+#include <SALOMEconfig.h>
+#include CORBA_SERVER_HEADER(SMESH_BasicHypothesis)
+
+#include "SMESHGUI.h"
+#include "SMESHGUI_Hypotheses.h"
+
+#include "StdMeshersGUI_LocalLengthDlg.h"
+#include "StdMeshersGUI_NbSegmentsDlg.h"
+#include "StdMeshersGUI_MaxElementAreaDlg.h"
+#include "StdMeshersGUI_MaxElementVolumeDlg.h"
+
+#include "QAD_Desktop.h"
+#include "QAD_ResourceMgr.h"
+
+#include <qobject.h>
+
+//=============================================================================
+/*! class HypothesisCreator
+ *
+ */
+//=============================================================================
+class StdMeshersGUI_HypothesisCreator : public SMESHGUI_GenericHypothesisCreator
+{
+ public:
+ StdMeshersGUI_HypothesisCreator (const QString& aHypType,
+ const QString& aServerLibName,
+ SMESHGUI* aSMESHGUI)
+ : myHypType(aHypType),
+ myServerLibName(aServerLibName),
+ mySMESHGUI(aSMESHGUI) {}
+
+ virtual void CreateHypothesis (const bool isAlgo, QWidget* parent = 0);
+ virtual void EditHypothesis (SMESH::SMESH_Hypothesis_ptr theHyp);
+
+ private:
+ QString myHypType;
+ QString myServerLibName;
+ SMESHGUI* mySMESHGUI;
+};
+
+//=============================================================================
+/*! HypothesisCreator::CreateHypothesis
+ *
+ */
+//=============================================================================
+void StdMeshersGUI_HypothesisCreator::CreateHypothesis
+ (bool isAlgo, QWidget* parent)
+{
+ MESSAGE("StdMeshersGUI_HypothesisCreator::CreateHypothesis");
+
+ // Get default name for hypothesis/algorithm creation
+ char* sHypType = (char*)myHypType.latin1();
+ HypothesisData* aHypData = mySMESHGUI->GetHypothesisData(sHypType);
+ QString aHypName;
+ if (aHypData)
+ aHypName = aHypData->Label;
+ else
+ aHypName = myHypType;
+
+ // Create hypothesis/algorithm
+ if (isAlgo)
+ {
+ mySMESHGUI->CreateHypothesis(myHypType, aHypName, isAlgo);
+ }
+ else
+ {
+ // Show Dialog for hypothesis creation
+ if (myHypType == "LocalLength")
+ StdMeshersGUI_LocalLengthDlg *aDlg = new StdMeshersGUI_LocalLengthDlg(myHypType, parent, "");
+ else if (myHypType == "NumberOfSegments")
+ StdMeshersGUI_NbSegmentsDlg *aDlg = new StdMeshersGUI_NbSegmentsDlg(myHypType, parent, "");
+ else if (myHypType == "MaxElementArea")
+ StdMeshersGUI_MaxElementAreaDlg *aDlg = new StdMeshersGUI_MaxElementAreaDlg(myHypType, parent, "");
+ else if (myHypType == "MaxElementVolume")
+ StdMeshersGUI_MaxElementVolumeDlg *aDlg = new StdMeshersGUI_MaxElementVolumeDlg(myHypType, parent, "");
+ else if (myHypType == "LengthFromEdges")
+ mySMESHGUI->CreateHypothesis(myHypType, aHypName, isAlgo); // without GUI
+ else if (myHypType == "NotConformAllowed")
+ mySMESHGUI->CreateHypothesis(myHypType, aHypName, isAlgo); // without GUI
+ else ;
+ }
+}
+
+//=============================================================================
+/*! HypothesisCreator::EditHypothesis
+ *
+ */
+//=============================================================================
+void StdMeshersGUI_HypothesisCreator::EditHypothesis
+ (SMESH::SMESH_Hypothesis_ptr theHyp)
+{
+ MESSAGE("StdMeshersGUI_HypothesisCreator::EditHypothesis");
+
+ Standard_Boolean res = Standard_True;
+ SALOMEDS::Study::ListOfSObject_var listSOmesh =
+ mySMESHGUI->GetMeshesUsingAlgoOrHypothesis(theHyp);
+ QString Name = theHyp->GetName();
+ if (Name.compare("LocalLength") == 0)
+ {
+ StdMeshers::StdMeshers_LocalLength_var LL =
+ StdMeshers::StdMeshers_LocalLength::_narrow(theHyp);
+ double beforeLength = LL->GetLength() ;
+ double Length = mySMESHGUI->Parameter(res,
+ beforeLength,
+ QObject::tr("SMESH_LOCAL_LENGTH_HYPOTHESIS"),
+ QObject::tr("SMESH_VALUE"),
+ 1.0E-5, 1E6, 6);
+ if (res && Length != beforeLength)
+ {
+ LL->SetLength(Length);
+ for (int i=0; i<listSOmesh->length(); i++)
+ {
+ mySMESHGUI->GetStudyAPI().ModifiedMesh(listSOmesh[i], false);
+ }
+ }
+ }
+ else if (Name.compare("NumberOfSegments") == 0)
+ {
+ StdMeshers::StdMeshers_NumberOfSegments_var NOS =
+ StdMeshers::StdMeshers_NumberOfSegments::_narrow(theHyp);
+ int beforeNbSeg = NOS->GetNumberOfSegments() ;
+ int NbSeg = mySMESHGUI->Parameter(res,
+ beforeNbSeg,
+ QObject::tr("SMESH_NB_SEGMENTS_HYPOTHESIS"),
+ QObject::tr("SMESH_VALUE"),
+ 1, 1000000);
+ if (res && NbSeg != beforeNbSeg)
+ {
+ NOS->SetNumberOfSegments(NbSeg);
+ for (int i=0; i<listSOmesh->length(); i++)
+ {
+ SALOMEDS::SObject_var SO = listSOmesh[i] ;
+ mySMESHGUI->GetStudyAPI().ModifiedMesh(listSOmesh[i], false);
+ }
+ }
+ }
+ else if (Name.compare("MaxElementArea") == 0)
+ {
+ StdMeshers::StdMeshers_MaxElementArea_var MEA =
+ StdMeshers::StdMeshers_MaxElementArea::_narrow(theHyp);
+ double beforeMaxArea = MEA->GetMaxElementArea();
+ double MaxArea = mySMESHGUI->Parameter(res,
+ beforeMaxArea,
+ QObject::tr("SMESH_MAX_ELEMENT_AREA_HYPOTHESIS"),
+ QObject::tr("SMESH_VALUE"),
+ 1.0E-5, 1E6, 6);
+ if (res && MaxArea != beforeMaxArea)
+ {
+ MEA->SetMaxElementArea(MaxArea);
+ for (int i=0; i<listSOmesh->length(); i++)
+ {
+ mySMESHGUI->GetStudyAPI().ModifiedMesh(listSOmesh[i], false);
+ }
+ }
+ }
+ else if (Name.compare("MaxElementVolume") == 0)
+ {
+ StdMeshers::StdMeshers_MaxElementVolume_var MEV =
+ StdMeshers::StdMeshers_MaxElementVolume::_narrow(theHyp);
+ double beforeMaxVolume = MEV->GetMaxElementVolume() ;
+ double MaxVolume = mySMESHGUI->Parameter(res,
+ beforeMaxVolume,
+ QObject::tr("SMESH_MAX_ELEMENT_VOLUME_HYPOTHESIS"),
+ QObject::tr("SMESH_VALUE"),
+ 1.0E-5, 1E6, 6);
+ if (res && MaxVolume != beforeMaxVolume)
+ {
+ MEV->SetMaxElementVolume(MaxVolume);
+ for (int i=0; i<listSOmesh->length(); i++)
+ {
+ mySMESHGUI->GetStudyAPI().ModifiedMesh(listSOmesh[i], false);
+ }
+ }
+ }
+// else if (Name.compare("Regular_1D") == 0)
+// {}
+// else if (Name.compare("MEFISTO_2D") == 0)
+// {}
+ else
+ {}
+}
+
+//=============================================================================
+/*! GetHypothesisCreator
+ *
+ */
+//=============================================================================
+extern "C"
+{
+ SMESHGUI_GenericHypothesisCreator* GetHypothesisCreator
+ (QString aHypType, QString aServerLibName, SMESHGUI* aSMESHGUI)
+ {
+ return new StdMeshersGUI_HypothesisCreator
+ (aHypType, aServerLibName, aSMESHGUI);
+ }
+}
--- /dev/null
+// SMESH StdMeshersGUI : GUI for StdMeshers plugin
+//
+// Copyright (C) 2003 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
+// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
+//
+// This library 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.
+//
+// This library 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 this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+//
+// See http://www.opencascade.org/SALOME/ or email : webmaster.salome@opencascade.org
+//
+//
+//
+// File : StdMeshersGUI_LocalLengthDlg.cxx
+// Moved here from SMESHGUI_LocalLengthDlg.cxx
+// Author : Nicolas REJNERI
+// Module : SMESH
+// $Header$
+
+using namespace std;
+#include "StdMeshersGUI_LocalLengthDlg.h"
+#include "SMESHGUI.h"
+#include "SMESHGUI_SpinBox.h"
+
+#include <SALOMEconfig.h>
+#include CORBA_SERVER_HEADER(SMESH_BasicHypothesis)
+
+#include "QAD_Application.h"
+#include "QAD_Desktop.h"
+#include "utilities.h"
+
+#include "SALOMEGUI_QtCatchCorbaException.hxx"
+#include "QAD_MessageBox.h"
+#include "QAD_WaitCursor.h"
+
+// QT Includes
+#include <qgroupbox.h>
+#include <qlabel.h>
+#include <qlineedit.h>
+#include <qpushbutton.h>
+#include <qlayout.h>
+#include <qpixmap.h>
+
+//=================================================================================
+// class : StdMeshersGUI_LocalLengthDlg()
+// purpose : Constructs a StdMeshersGUI_LocalLengthDlg which is a child of 'parent', with the
+// name 'name' and widget flags set to 'f'.
+// The dialog will by default be modeless, unless you set 'modal' to
+// TRUE to construct a modal dialog.
+//=================================================================================
+StdMeshersGUI_LocalLengthDlg::StdMeshersGUI_LocalLengthDlg (const QString& hypType,
+ QWidget* parent,
+ const char* name,
+ bool modal,
+ WFlags fl)
+ : QDialog (parent, name, modal, WStyle_Customize | WStyle_NormalBorder | WStyle_Title | WStyle_SysMenu | WDestructiveClose),
+ myHypType(hypType)
+{
+ QPixmap image0(QAD_Desktop::getResourceManager()->loadPixmap( "SMESH",tr("ICON_DLG_LOCAL_LENGTH")));
+
+ if ( !name )
+ setName( "StdMeshersGUI_LocalLengthDlg" );
+ setCaption( tr( "SMESH_LOCAL_LENGTH_TITLE" ) );
+ setSizeGripEnabled( TRUE );
+ QGridLayout* StdMeshersGUI_LocalLengthDlgLayout = new QGridLayout( this );
+ StdMeshersGUI_LocalLengthDlgLayout->setSpacing( 6 );
+ StdMeshersGUI_LocalLengthDlgLayout->setMargin( 11 );
+
+ /***************************************************************/
+ iconLabel = new QLabel( this );
+ iconLabel->setPixmap( image0 );
+ iconLabel->setScaledContents( false );
+ iconLabel->setSizePolicy( QSizePolicy( QSizePolicy::Fixed, QSizePolicy::Fixed ) );
+ typeLabel = new QLabel( this );
+ typeLabel->setText( tr( "SMESH_LOCAL_LENGTH_HYPOTHESIS" ) );
+ StdMeshersGUI_LocalLengthDlgLayout->addWidget( iconLabel, 0, 0 );
+ StdMeshersGUI_LocalLengthDlgLayout->addWidget( typeLabel, 0, 1 );
+
+ /***************************************************************/
+ GroupC1 = new QGroupBox( this, "GroupC1" );
+ GroupC1->setTitle( tr( "SMESH_ARGUMENTS" ) );
+ GroupC1->setColumnLayout(0, Qt::Vertical );
+ GroupC1->layout()->setSpacing( 0 );
+ GroupC1->layout()->setMargin( 0 );
+ QGridLayout* GroupC1Layout = new QGridLayout( GroupC1->layout() );
+ GroupC1Layout->setAlignment( Qt::AlignTop );
+ GroupC1Layout->setSpacing( 6 );
+ GroupC1Layout->setMargin( 11 );
+
+ TextLabel_NameHypothesis = new QLabel( GroupC1, "TextLabel_NameHypothesis" );
+ TextLabel_NameHypothesis->setText( tr( "SMESH_NAME" ) );
+ GroupC1Layout->addWidget( TextLabel_NameHypothesis, 0, 0 );
+
+ LineEdit_NameHypothesis = new QLineEdit( GroupC1, "LineEdit_NameHypothesis" );
+ GroupC1Layout->addWidget( LineEdit_NameHypothesis, 0, 1 );
+
+ TextLabel_Length = new QLabel(GroupC1 , "TextLabel_Length" );
+ TextLabel_Length->setText( tr( "SMESH_LENGTH" ) );
+ GroupC1Layout->addWidget( TextLabel_Length, 1, 0 );
+
+ SpinBox_Length = new SMESHGUI_SpinBox( GroupC1, "SpinBox_Length" );
+ GroupC1Layout->addWidget( SpinBox_Length, 1, 1 );
+
+ StdMeshersGUI_LocalLengthDlgLayout->addMultiCellWidget(GroupC1 , 1, 1, 0, 1 );
+
+ /***************************************************************/
+ GroupButtons = new QGroupBox( this, "GroupButtons" );
+ GroupButtons->setColumnLayout(0, Qt::Vertical );
+ GroupButtons->layout()->setSpacing( 0 );
+ GroupButtons->layout()->setMargin( 0 );
+ QGridLayout* GroupButtonsLayout = new QGridLayout( GroupButtons->layout() );
+ GroupButtonsLayout->setAlignment( Qt::AlignTop );
+ GroupButtonsLayout->setSpacing( 6 );
+ GroupButtonsLayout->setMargin( 11 );
+ buttonOk = new QPushButton( GroupButtons, "buttonOk" );
+ buttonOk->setText( tr( "SMESH_BUT_OK" ) );
+ buttonOk->setAutoDefault( TRUE );
+ buttonOk->setDefault( TRUE );
+ GroupButtonsLayout->addWidget( buttonOk, 0, 0 );
+ buttonApply = new QPushButton( GroupButtons, "buttonApply" );
+ buttonApply->setText( tr( "SMESH_BUT_APPLY" ) );
+ buttonApply->setAutoDefault( TRUE );
+ GroupButtonsLayout->addWidget( buttonApply, 0, 1 );
+ QSpacerItem* spacer = new QSpacerItem( 20, 20, QSizePolicy::Expanding, QSizePolicy::Minimum );
+ GroupButtonsLayout->addItem( spacer, 0, 2 );
+ buttonCancel = new QPushButton( GroupButtons, "buttonCancel" );
+ buttonCancel->setText( tr( "SMESH_BUT_CLOSE" ) );
+ buttonCancel->setAutoDefault( TRUE );
+ GroupButtonsLayout->addWidget( buttonCancel, 0, 3 );
+ StdMeshersGUI_LocalLengthDlgLayout->addMultiCellWidget( GroupButtons, 2, 2, 0, 1 );
+
+ /***************************************************************/
+ Init() ;
+}
+
+
+//=================================================================================
+// function : ~StdMeshersGUI_LocalLengthDlg()
+// purpose : Destroys the object and frees any allocated resources
+//=================================================================================
+StdMeshersGUI_LocalLengthDlg::~StdMeshersGUI_LocalLengthDlg()
+{
+ // no need to delete child widgets, Qt does it all for us
+}
+
+
+//=================================================================================
+// function : Init()
+// purpose :
+//=================================================================================
+void StdMeshersGUI_LocalLengthDlg::Init()
+{
+ /* min, max, step and decimals for spin boxes */
+ SpinBox_Length->RangeStepAndValidator( 0.001, 999.999, 1.0, 3 ) ;
+ SpinBox_Length->SetValue( 1.0 ) ;
+
+ mySMESHGUI = SMESHGUI::GetSMESHGUI() ;
+
+ char* sHypType = (char*)myHypType.latin1();
+ HypothesisData* aHypData = mySMESHGUI->GetHypothesisData(sHypType);
+ LineEdit_NameHypothesis->setText( aHypData ? aHypData->Label : "" );
+
+ mySMESHGUI->SetActiveDialogBox( (QDialog*)this ) ;
+
+ /* signals and slots connections */
+ connect( buttonOk, SIGNAL(clicked()), this, SLOT(ClickOnOk()) );
+ connect( buttonCancel, SIGNAL(clicked()), this, SLOT(ClickOnCancel()) ) ;
+ connect( buttonApply, SIGNAL(clicked()), this, SLOT(ClickOnApply()) );
+
+ connect( mySMESHGUI, SIGNAL ( SignalDeactivateActiveDialog() ), this, SLOT( DeactivateActiveDialog() ) ) ;
+ connect( mySMESHGUI, SIGNAL ( SignalCloseAllDialogs() ), this, SLOT( ClickOnCancel() ) ) ;
+
+ /* Move widget on the botton right corner of main widget */
+ int x, y ;
+ mySMESHGUI->DefineDlgPosition( this, x, y ) ;
+ this->move( x, y ) ;
+ this->show() ; /* displays Dialog */
+}
+
+
+//=================================================================================
+// function : ClickOnOk()
+// purpose :
+//=================================================================================
+void StdMeshersGUI_LocalLengthDlg::ClickOnOk()
+{
+ if ( this->ClickOnApply() )
+ this->ClickOnCancel() ;
+}
+
+//=================================================================================
+// function : ClickOnApply()
+// purpose :
+//=================================================================================
+bool StdMeshersGUI_LocalLengthDlg::ClickOnApply()
+{
+ QString myHypName = LineEdit_NameHypothesis->text().stripWhiteSpace();
+ if ( myHypName.isEmpty() ) {
+ QAD_MessageBox::warn1( this, tr( "SMESH_WRN_WARNING" ), tr( "SMESH_WRN_EMPTY_NAME" ), tr( "SMESH_BUT_OK" ) );
+ return false;
+ }
+
+ double myLength = SpinBox_Length->GetValue();
+
+ QAD_WaitCursor wc;
+ try {
+ SMESH::SMESH_Hypothesis_var Hyp = SMESH::SMESH_Hypothesis::_narrow
+ (mySMESHGUI->CreateHypothesis(myHypType,
+ myHypName,
+ false)); // isAlgorithm
+ StdMeshers::StdMeshers_LocalLength_var LL =
+ StdMeshers::StdMeshers_LocalLength::_narrow(Hyp);
+ if (!LL->_is_nil())
+ LL->SetLength(myLength);
+ }
+ catch (const SALOME::SALOME_Exception& S_ex) {
+ wc.stop();
+ QtCatchCorbaException(S_ex);
+ return false;
+ }
+ return true;
+}
+
+
+//=================================================================================
+// function : ClickOnCancel()
+// purpose :
+//=================================================================================
+void StdMeshersGUI_LocalLengthDlg::ClickOnCancel()
+{
+ close();
+}
+
+//=================================================================================
+// function : DeactivateActiveDialog()
+// purpose :
+//=================================================================================
+void StdMeshersGUI_LocalLengthDlg::DeactivateActiveDialog()
+{
+ iconLabel->setEnabled(false) ;
+ typeLabel->setEnabled(false) ;
+ GroupC1->setEnabled(false) ;
+ GroupButtons->setEnabled(false) ;
+}
+
+
+//=================================================================================
+// function : ActivateThisDialog()
+// purpose :
+//=================================================================================
+void StdMeshersGUI_LocalLengthDlg::ActivateThisDialog()
+{
+ mySMESHGUI->EmitSignalDeactivateDialog() ;
+ iconLabel->setEnabled(true) ;
+ typeLabel->setEnabled(true) ;
+ GroupC1->setEnabled(true) ;
+ GroupButtons->setEnabled(true) ;
+}
+
+
+//=================================================================================
+// function : enterEvent()
+// purpose :
+//=================================================================================
+void StdMeshersGUI_LocalLengthDlg::enterEvent(QEvent* e)
+{
+ ActivateThisDialog() ;
+}
+
+
+//=================================================================================
+// function : closeEvent()
+// purpose :
+//=================================================================================
+void StdMeshersGUI_LocalLengthDlg::closeEvent( QCloseEvent* e )
+{
+ mySMESHGUI->ResetState();
+ QDialog::closeEvent( e );
+}
--- /dev/null
+// SMESH SMESHGUI : GUI for SMESH component
+//
+// Copyright (C) 2003 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
+// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
+//
+// This library 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.
+//
+// This library 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 this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+//
+// See http://www.opencascade.org/SALOME/ or email : webmaster.salome@opencascade.org
+//
+//
+//
+// File : StdMeshersGUI_LocalLengthDlg.h
+// Moved here from SMESHGUI_LocalLengthDlg.h
+// Author : Nicolas REJNERI
+// Module : SMESH
+// $Header$
+
+#ifndef DIALOGBOX_LOCAL_LENGTH_H
+#define DIALOGBOX_LOCAL_LENGTH_H
+
+// QT Includes
+#include <qdialog.h>
+
+class QGroupBox;
+class QLabel;
+class QLineEdit;
+class QPushButton;
+class SMESHGUI;
+class SMESHGUI_SpinBox;
+
+//=================================================================================
+// class : StdMeshersGUI_LocalLengthDlg
+// purpose :
+//=================================================================================
+class StdMeshersGUI_LocalLengthDlg : public QDialog
+{
+ Q_OBJECT
+
+public:
+ StdMeshersGUI_LocalLengthDlg (const QString& hypType,
+ QWidget* parent = 0,
+ const char* name = 0,
+ bool modal = FALSE,
+ WFlags fl = 0);
+ ~StdMeshersGUI_LocalLengthDlg ();
+
+private:
+
+ void Init() ;
+ void closeEvent( QCloseEvent* e ) ;
+ void enterEvent ( QEvent * ) ;
+
+ SMESHGUI* mySMESHGUI ;
+ QString myHypType ;
+
+ QLabel* iconLabel;
+ QLabel* typeLabel;
+ QGroupBox* GroupC1;
+ QLabel* TextLabel_NameHypothesis ;
+ QLineEdit* LineEdit_NameHypothesis ;
+ QLabel* TextLabel_Length ;
+ SMESHGUI_SpinBox* SpinBox_Length ;
+ QGroupBox* GroupButtons;
+ QPushButton* buttonOk;
+ QPushButton* buttonApply;
+ QPushButton* buttonCancel;
+
+private slots:
+
+ void ClickOnOk();
+ void ClickOnCancel();
+ bool ClickOnApply();
+ void DeactivateActiveDialog() ;
+ void ActivateThisDialog() ;
+};
+
+#endif // DIALOGBOX_LOCAL_LENGTH_H
--- /dev/null
+// SMESH SMESHGUI : GUI for SMESH component
+//
+// Copyright (C) 2003 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
+// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
+//
+// This library 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.
+//
+// This library 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 this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+//
+// See http://www.opencascade.org/SALOME/ or email : webmaster.salome@opencascade.org
+//
+//
+//
+// File : StdMeshersGUI_MaxElementAreaDlg.cxx
+// Moved here from SMESHGUI_MaxElementAreaDlg.cxx
+// Author : Nicolas REJNERI
+// Module : SMESH
+// $Header$
+
+using namespace std;
+#include "StdMeshersGUI_MaxElementAreaDlg.h"
+#include "SMESHGUI.h"
+#include "SMESHGUI_SpinBox.h"
+
+#include <SALOMEconfig.h>
+#include CORBA_SERVER_HEADER(SMESH_BasicHypothesis)
+
+#include "QAD_Application.h"
+#include "QAD_Desktop.h"
+#include "utilities.h"
+
+#include "SALOMEGUI_QtCatchCorbaException.hxx"
+#include "QAD_MessageBox.h"
+#include "QAD_WaitCursor.h"
+
+// QT Includes
+#include <qgroupbox.h>
+#include <qlabel.h>
+#include <qlineedit.h>
+#include <qpushbutton.h>
+#include <qlayout.h>
+#include <qpixmap.h>
+
+//=================================================================================
+// class : StdMeshersGUI_MaxElementAreaDlg()
+// purpose : Constructs a StdMeshersGUI_MaxElementAreaDlg which is a child of 'parent', with the
+// name 'name' and widget flags set to 'f'.
+// The dialog will by default be modeless, unless you set 'modal' to
+// TRUE to construct a modal dialog.
+//=================================================================================
+StdMeshersGUI_MaxElementAreaDlg::StdMeshersGUI_MaxElementAreaDlg (const QString& hypType,
+ QWidget* parent,
+ const char* name,
+ bool modal,
+ WFlags fl)
+ : QDialog (parent, name, modal, WStyle_Customize | WStyle_NormalBorder | WStyle_Title | WStyle_SysMenu | WDestructiveClose),
+ myHypType(hypType)
+{
+ QPixmap image0(QAD_Desktop::getResourceManager()->loadPixmap( "SMESH",tr("ICON_DLG_MAX_ELEMENT_AREA")));
+
+ if ( !name )
+ setName( "StdMeshersGUI_MaxElementAreaDlg" );
+ setCaption( tr( "SMESH_MAX_ELEMENT_AREA_TITLE" ) );
+ setSizeGripEnabled( TRUE );
+ QGridLayout* StdMeshersGUI_MaxElementAreaDlgLayout = new QGridLayout( this );
+ StdMeshersGUI_MaxElementAreaDlgLayout->setSpacing( 6 );
+ StdMeshersGUI_MaxElementAreaDlgLayout->setMargin( 11 );
+
+ /***************************************************************/
+ iconLabel = new QLabel( this );
+ iconLabel->setPixmap( image0 );
+ iconLabel->setScaledContents( false );
+ iconLabel->setSizePolicy( QSizePolicy( QSizePolicy::Fixed, QSizePolicy::Fixed ) );
+ typeLabel = new QLabel( this );
+ typeLabel->setText( tr( "SMESH_MAX_ELEMENT_AREA_HYPOTHESIS" ) );
+ StdMeshersGUI_MaxElementAreaDlgLayout->addWidget( iconLabel, 0, 0 );
+ StdMeshersGUI_MaxElementAreaDlgLayout->addWidget( typeLabel, 0, 1 );
+
+ /***************************************************************/
+ GroupC1 = new QGroupBox( this, "GroupC1" );
+ GroupC1->setTitle( tr( "SMESH_ARGUMENTS" ) );
+ GroupC1->setColumnLayout(0, Qt::Vertical );
+ GroupC1->layout()->setSpacing( 0 );
+ GroupC1->layout()->setMargin( 0 );
+ QGridLayout* GroupC1Layout = new QGridLayout( GroupC1->layout() );
+ GroupC1Layout->setAlignment( Qt::AlignTop );
+ GroupC1Layout->setSpacing( 6 );
+ GroupC1Layout->setMargin( 11 );
+
+ TextLabel_NameHypothesis = new QLabel( GroupC1, "TextLabel_NameHypothesis" );
+ TextLabel_NameHypothesis->setText( tr( "SMESH_NAME" ) );
+ GroupC1Layout->addWidget( TextLabel_NameHypothesis, 0, 0 );
+
+ LineEdit_NameHypothesis = new QLineEdit( GroupC1, "LineEdit_NameHypothesis" );
+ GroupC1Layout->addWidget( LineEdit_NameHypothesis, 0, 1 );
+
+ TextLabel_MaxElementArea = new QLabel(GroupC1 , "TextLabel_MaxElementArea" );
+ TextLabel_MaxElementArea->setText( tr( "SMESH_MAX_ELEMENT_AREA" ) );
+ GroupC1Layout->addWidget( TextLabel_MaxElementArea, 1, 0 );
+
+ SpinBox_MaxElementArea = new SMESHGUI_SpinBox( GroupC1, "SpinBox_MaxElementArea" ) ;
+ GroupC1Layout->addWidget( SpinBox_MaxElementArea, 1, 1 );
+
+ StdMeshersGUI_MaxElementAreaDlgLayout->addMultiCellWidget(GroupC1 , 1, 1, 0, 1);
+
+ /***************************************************************/
+ GroupButtons = new QGroupBox( this, "GroupButtons" );
+ GroupButtons->setColumnLayout(0, Qt::Vertical );
+ GroupButtons->layout()->setSpacing( 0 );
+ GroupButtons->layout()->setMargin( 0 );
+ QGridLayout* GroupButtonsLayout = new QGridLayout( GroupButtons->layout() );
+ GroupButtonsLayout->setAlignment( Qt::AlignTop );
+ GroupButtonsLayout->setSpacing( 6 );
+ GroupButtonsLayout->setMargin( 11 );
+ buttonOk = new QPushButton( GroupButtons, "buttonOk" );
+ buttonOk->setText( tr( "SMESH_BUT_OK" ) );
+ buttonOk->setAutoDefault( TRUE );
+ buttonOk->setDefault( TRUE );
+ GroupButtonsLayout->addWidget( buttonOk, 0, 0 );
+ buttonApply = new QPushButton( GroupButtons, "buttonApply" );
+ buttonApply->setText( tr( "SMESH_BUT_APPLY" ) );
+ buttonApply->setAutoDefault( TRUE );
+ GroupButtonsLayout->addWidget( buttonApply, 0, 1 );
+ QSpacerItem* spacer = new QSpacerItem( 20, 20, QSizePolicy::Expanding, QSizePolicy::Minimum );
+ GroupButtonsLayout->addItem( spacer, 0, 2 );
+ buttonCancel = new QPushButton( GroupButtons, "buttonCancel" );
+ buttonCancel->setText( tr( "SMESH_BUT_CLOSE" ) );
+ buttonCancel->setAutoDefault( TRUE );
+ GroupButtonsLayout->addWidget( buttonCancel, 0, 3 );
+ StdMeshersGUI_MaxElementAreaDlgLayout->addMultiCellWidget( GroupButtons, 2, 2, 0, 1 );
+
+ /***************************************************************/
+ Init() ;
+}
+
+
+//=================================================================================
+// function : ~StdMeshersGUI_MaxElementAreaDlg()
+// purpose : Destroys the object and frees any allocated resources
+//=================================================================================
+StdMeshersGUI_MaxElementAreaDlg::~StdMeshersGUI_MaxElementAreaDlg()
+{
+ // no need to delete child widgets, Qt does it all for us
+}
+
+
+//=================================================================================
+// function : Init()
+// purpose :
+//=================================================================================
+void StdMeshersGUI_MaxElementAreaDlg::Init()
+{
+ /* min, max, step and decimals for spin boxes */
+ SpinBox_MaxElementArea->setPrecision( 10 );
+ SpinBox_MaxElementArea->RangeStepAndValidator( 0.001, 999999.999, 1.0, 3 ) ;
+ SpinBox_MaxElementArea->SetValue( 1.0 ) ; /* is myMaxElementArea */
+
+ mySMESHGUI = SMESHGUI::GetSMESHGUI() ;
+
+ char* sHypType = (char*)myHypType.latin1();
+ HypothesisData* aHypData = mySMESHGUI->GetHypothesisData(sHypType);
+ LineEdit_NameHypothesis->setText( aHypData ? aHypData->Label : "" );
+
+ mySMESHGUI->SetActiveDialogBox( (QDialog*)this ) ;
+
+ /* signals and slots connections */
+ connect( buttonOk, SIGNAL(clicked()), this, SLOT(ClickOnOk()) );
+ connect( buttonCancel, SIGNAL(clicked()), this, SLOT(ClickOnCancel()) ) ;
+ connect( buttonApply, SIGNAL(clicked()), this, SLOT(ClickOnApply()) );
+
+ connect( mySMESHGUI, SIGNAL ( SignalDeactivateActiveDialog() ), this, SLOT( DeactivateActiveDialog() ) ) ;
+ connect( mySMESHGUI, SIGNAL ( SignalCloseAllDialogs() ), this, SLOT( ClickOnCancel() ) ) ;
+
+ /* Move widget on the botton right corner of main widget */
+ int x, y ;
+ mySMESHGUI->DefineDlgPosition( this, x, y ) ;
+ this->move( x, y ) ;
+ this->show() ; /* displays Dialog */
+}
+
+
+//=================================================================================
+// function : ClickOnOk()
+// purpose :
+//=================================================================================
+void StdMeshersGUI_MaxElementAreaDlg::ClickOnOk()
+{
+ if ( this->ClickOnApply() )
+ this->ClickOnCancel() ;
+}
+
+//=================================================================================
+// function : ClickOnApply()
+// purpose :
+//=================================================================================
+bool StdMeshersGUI_MaxElementAreaDlg::ClickOnApply()
+{
+ QString myHypName = LineEdit_NameHypothesis->text().stripWhiteSpace();
+ if ( myHypName.isEmpty() ) {
+ QAD_MessageBox::warn1( this, tr( "SMESH_WRN_WARNING" ), tr( "SMESH_WRN_EMPTY_NAME" ), tr( "SMESH_BUT_OK" ) );
+ return false;
+ }
+
+ double myMaxElementArea = SpinBox_MaxElementArea->GetValue();
+
+ QAD_WaitCursor wc;
+ try {
+ SMESH::SMESH_Hypothesis_var Hyp = SMESH::SMESH_Hypothesis::_narrow
+ (mySMESHGUI->CreateHypothesis(myHypType,
+ myHypName,
+ false)); // isAlgorithm
+ StdMeshers::StdMeshers_MaxElementArea_var MaxElArea =
+ StdMeshers::StdMeshers_MaxElementArea::_narrow(Hyp);
+ if (!MaxElArea->_is_nil())
+ MaxElArea->SetMaxElementArea(myMaxElementArea);
+ }
+ catch (const SALOME::SALOME_Exception& S_ex) {
+ wc.stop();
+ QtCatchCorbaException(S_ex);
+ return false;
+ }
+ return true;
+}
+
+
+//=================================================================================
+// function : ClickOnCancel()
+// purpose :
+//=================================================================================
+void StdMeshersGUI_MaxElementAreaDlg::ClickOnCancel()
+{
+ close();
+}
+
+
+//=================================================================================
+// function : DeactivateActiveDialog()
+// purpose :
+//=================================================================================
+void StdMeshersGUI_MaxElementAreaDlg::DeactivateActiveDialog()
+{
+ iconLabel->setEnabled(false) ;
+ typeLabel->setEnabled(false) ;
+ GroupC1->setEnabled(false) ;
+ GroupButtons->setEnabled(false) ;
+}
+
+
+//=================================================================================
+// function : ActivateThisDialog()
+// purpose :
+//=================================================================================
+void StdMeshersGUI_MaxElementAreaDlg::ActivateThisDialog()
+{
+ mySMESHGUI->EmitSignalDeactivateDialog() ;
+ iconLabel->setEnabled(true) ;
+ typeLabel->setEnabled(true) ;
+ GroupC1->setEnabled(true) ;
+ GroupButtons->setEnabled(true) ;
+}
+
+
+//=================================================================================
+// function : enterEvent()
+// purpose :
+//=================================================================================
+void StdMeshersGUI_MaxElementAreaDlg::enterEvent(QEvent* e)
+{
+ ActivateThisDialog() ;
+}
+
+
+//=================================================================================
+// function : closeEvent()
+// purpose :
+//=================================================================================
+void StdMeshersGUI_MaxElementAreaDlg::closeEvent( QCloseEvent* e )
+{
+ mySMESHGUI->ResetState();
+ QDialog::closeEvent( e );
+}
--- /dev/null
+// SMESH SMESHGUI : GUI for SMESH component
+//
+// Copyright (C) 2003 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
+// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
+//
+// This library 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.
+//
+// This library 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 this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+//
+// See http://www.opencascade.org/SALOME/ or email : webmaster.salome@opencascade.org
+//
+//
+//
+// File : StdMeshersGUI_MaxElementAreaDlg.h
+// Moved here from SMESHGUI_MaxElementAreaDlg.h
+// Author : Nicolas REJNERI
+// Module : SMESH
+// $Header$
+
+#ifndef DIALOGBOX_MAX_ELEMENT_AREA_H
+#define DIALOGBOX_MAX_ELEMENT_AREA_H
+
+// QT Includes
+#include <qdialog.h>
+
+class QGroupBox;
+class QLabel;
+class QLineEdit;
+class QPushButton;
+class SMESHGUI;
+class SMESHGUI_SpinBox;
+
+//=================================================================================
+// class : StdMeshersGUI_MaxElementAreaDlg
+// purpose :
+//=================================================================================
+class StdMeshersGUI_MaxElementAreaDlg : public QDialog
+{
+ Q_OBJECT
+
+public:
+ StdMeshersGUI_MaxElementAreaDlg (const QString& hypType,
+ QWidget* parent = 0,
+ const char* name = 0,
+ bool modal = FALSE,
+ WFlags fl = 0 );
+ ~StdMeshersGUI_MaxElementAreaDlg ();
+
+private:
+
+ void Init() ;
+ void closeEvent( QCloseEvent* e ) ;
+ void enterEvent ( QEvent * ) ;
+
+ SMESHGUI* mySMESHGUI ;
+ QString myHypType ;
+
+ QLabel* iconLabel;
+ QLabel* typeLabel;
+ QGroupBox* GroupC1;
+ QLabel* TextLabel_NameHypothesis ;
+ QLineEdit* LineEdit_NameHypothesis ;
+ QLabel* TextLabel_MaxElementArea ;
+ SMESHGUI_SpinBox* SpinBox_MaxElementArea ;
+ QGroupBox* GroupButtons;
+ QPushButton* buttonApply;
+ QPushButton* buttonOk;
+ QPushButton* buttonCancel;
+
+private slots:
+
+ void ClickOnOk();
+ void ClickOnCancel();
+ bool ClickOnApply();
+ void DeactivateActiveDialog() ;
+ void ActivateThisDialog() ;
+};
+
+#endif // DIALOGBOX_MAX_ELEMENT_AREA_H
--- /dev/null
+// SMESH SMESHGUI : GUI for SMESH component
+//
+// Copyright (C) 2003 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
+// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
+//
+// This library 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.
+//
+// This library 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 this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+//
+// See http://www.opencascade.org/SALOME/ or email : webmaster.salome@opencascade.org
+//
+//
+//
+// File : StdMeshersGUI_MaxElementVolumeDlg.cxx
+// Moved here from SMESHGUI_MaxElementVolumeDlg.cxx
+// Author : Nicolas REJNERI
+// Module : SMESH
+// $Header$
+
+using namespace std;
+#include "StdMeshersGUI_MaxElementVolumeDlg.h"
+#include "SMESHGUI.h"
+#include "SMESHGUI_SpinBox.h"
+
+#include <SALOMEconfig.h>
+#include CORBA_SERVER_HEADER(SMESH_BasicHypothesis)
+
+#include "QAD_Application.h"
+#include "QAD_Desktop.h"
+#include "utilities.h"
+
+#include "SALOMEGUI_QtCatchCorbaException.hxx"
+#include "QAD_MessageBox.h"
+#include "QAD_WaitCursor.h"
+
+// QT Includes
+#include <qgroupbox.h>
+#include <qlabel.h>
+#include <qlineedit.h>
+#include <qpushbutton.h>
+#include <qlayout.h>
+#include <qpixmap.h>
+
+//=================================================================================
+// class : StdMeshersGUI_MaxElementVolumeDlg()
+// purpose : Constructs a StdMeshersGUI_MaxElementVolumeDlg which is a child of 'parent', with the
+// name 'name' and widget flags set to 'f'.
+// The dialog will by default be modeless, unless you set 'modal' to
+// TRUE to construct a modal dialog.
+//=================================================================================
+StdMeshersGUI_MaxElementVolumeDlg::StdMeshersGUI_MaxElementVolumeDlg (const QString& hypType,
+ QWidget* parent,
+ const char* name,
+ bool modal, WFlags fl)
+ : QDialog (parent, name, modal, WStyle_Customize | WStyle_NormalBorder | WStyle_Title | WStyle_SysMenu | WDestructiveClose),
+ myHypType(hypType)
+{
+ QPixmap image0(QAD_Desktop::getResourceManager()->loadPixmap( "SMESH",tr("ICON_DLG_MAX_ELEMENT_VOLUME")));
+
+ if ( !name )
+ setName( "StdMeshersGUI_MaxElementVolumeDlg" );
+ setCaption( tr( "SMESH_MAX_ELEMENT_VOLUME_TITLE" ) );
+ setSizeGripEnabled( TRUE );
+ QGridLayout* StdMeshersGUI_MaxElementVolumeDlgLayout = new QGridLayout( this );
+ StdMeshersGUI_MaxElementVolumeDlgLayout->setSpacing( 6 );
+ StdMeshersGUI_MaxElementVolumeDlgLayout->setMargin( 11 );
+
+ /***************************************************************/
+ iconLabel = new QLabel( this );
+ iconLabel->setPixmap( image0 );
+ iconLabel->setScaledContents( false );
+ iconLabel->setSizePolicy( QSizePolicy( QSizePolicy::Fixed, QSizePolicy::Fixed ) );
+ typeLabel = new QLabel( this );
+ typeLabel->setText( tr( "SMESH_MAX_ELEMENT_VOLUME_HYPOTHESIS" ) );
+ StdMeshersGUI_MaxElementVolumeDlgLayout->addWidget( iconLabel, 0, 0 );
+ StdMeshersGUI_MaxElementVolumeDlgLayout->addWidget( typeLabel, 0, 1 );
+
+ /***************************************************************/
+ GroupButtons = new QGroupBox( this, "GroupButtons" );
+ GroupButtons->setColumnLayout(0, Qt::Vertical );
+ GroupButtons->layout()->setSpacing( 0 );
+ GroupButtons->layout()->setMargin( 0 );
+ QGridLayout* GroupButtonsLayout = new QGridLayout( GroupButtons->layout() );
+ GroupButtonsLayout->setAlignment( Qt::AlignTop );
+ GroupButtonsLayout->setSpacing( 6 );
+ GroupButtonsLayout->setMargin( 11 );
+ buttonOk = new QPushButton( GroupButtons, "buttonOk" );
+ buttonOk->setText( tr( "SMESH_BUT_OK" ) );
+ buttonOk->setAutoDefault( TRUE );
+ buttonOk->setDefault( TRUE );
+ GroupButtonsLayout->addWidget( buttonOk, 0, 0 );
+ buttonApply = new QPushButton( GroupButtons, "buttonApply" );
+ buttonApply->setText( tr( "SMESH_BUT_APPLY" ) );
+ buttonApply->setAutoDefault( TRUE );
+ GroupButtonsLayout->addWidget( buttonApply, 0, 1 );
+ QSpacerItem* spacer = new QSpacerItem( 20, 20, QSizePolicy::Expanding, QSizePolicy::Minimum );
+ GroupButtonsLayout->addItem( spacer, 0, 2 );
+ buttonCancel = new QPushButton( GroupButtons, "buttonCancel" );
+ buttonCancel->setText( tr( "SMESH_BUT_CLOSE" ) );
+ buttonCancel->setAutoDefault( TRUE );
+ GroupButtonsLayout->addWidget( buttonCancel, 0, 3 );
+ StdMeshersGUI_MaxElementVolumeDlgLayout->addMultiCellWidget( GroupButtons, 2, 2, 0, 1 );
+
+ /***************************************************************/
+ GroupC1 = new QGroupBox( this, "GroupC1" );
+ GroupC1->setTitle( tr( "SMESH_ARGUMENTS" ) );
+ GroupC1->setColumnLayout(0, Qt::Vertical );
+ GroupC1->layout()->setSpacing( 0 );
+ GroupC1->layout()->setMargin( 0 );
+ QGridLayout* GroupC1Layout = new QGridLayout( GroupC1->layout() );
+ GroupC1Layout->setAlignment( Qt::AlignTop );
+ GroupC1Layout->setSpacing( 6 );
+ GroupC1Layout->setMargin( 11 );
+
+ TextLabel_NameHypothesis = new QLabel( GroupC1, "TextLabel_NameHypothesis" );
+ TextLabel_NameHypothesis->setText( tr( "SMESH_NAME" ) );
+ GroupC1Layout->addWidget( TextLabel_NameHypothesis, 0, 0 );
+
+ LineEdit_NameHypothesis = new QLineEdit( GroupC1, "LineEdit_NameHypothesis" );
+ GroupC1Layout->addWidget( LineEdit_NameHypothesis, 0, 1 );
+
+ TextLabel_MaxElementVolume = new QLabel(GroupC1 , "TextLabel_MaxElementVolume" );
+ TextLabel_MaxElementVolume->setText( tr( "SMESH_MAX_ELEMENT_VOLUME" ) );
+ GroupC1Layout->addWidget( TextLabel_MaxElementVolume, 1, 0 );
+
+ SpinBox_MaxElementVolume = new SMESHGUI_SpinBox( GroupC1, "SpinBox_MaxElementVolume" ) ;
+ GroupC1Layout->addWidget( SpinBox_MaxElementVolume, 1, 1 );
+
+ StdMeshersGUI_MaxElementVolumeDlgLayout->addMultiCellWidget(GroupC1 , 1, 1, 0, 1 );
+
+ /***************************************************************/
+ Init() ;
+}
+
+
+//=================================================================================
+// function : ~StdMeshersGUI_MaxElementVolumeDlg()
+// purpose : Destroys the object and frees any allocated resources
+//=================================================================================
+StdMeshersGUI_MaxElementVolumeDlg::~StdMeshersGUI_MaxElementVolumeDlg()
+{
+ // no need to delete child widgets, Qt does it all for us
+}
+
+
+//=================================================================================
+// function : Init()
+// purpose :
+//=================================================================================
+void StdMeshersGUI_MaxElementVolumeDlg::Init()
+{
+ /* min, max, step and decimals for spin boxes */
+ SpinBox_MaxElementVolume->setPrecision( 10 );
+ SpinBox_MaxElementVolume->RangeStepAndValidator( 0.001, 999999.999, 1.0, 3 ) ;
+ SpinBox_MaxElementVolume->SetValue( 1.0 ) ; /* is myMaxElementVolume */
+
+ mySMESHGUI = SMESHGUI::GetSMESHGUI() ;
+
+ char* sHypType = (char*)myHypType.latin1();
+ HypothesisData* aHypData = mySMESHGUI->GetHypothesisData(sHypType);
+ LineEdit_NameHypothesis->setText( aHypData ? aHypData->Label : "" );
+
+ mySMESHGUI->SetActiveDialogBox( (QDialog*)this ) ;
+
+ /* signals and slots connections */
+ connect( buttonOk, SIGNAL(clicked()), this, SLOT(ClickOnOk()) );
+ connect( buttonCancel, SIGNAL(clicked()), this, SLOT(ClickOnCancel()) ) ;
+ connect( buttonApply, SIGNAL(clicked()), this, SLOT(ClickOnApply()) );
+
+ connect( mySMESHGUI, SIGNAL ( SignalDeactivateActiveDialog() ), this, SLOT( DeactivateActiveDialog() ) ) ;
+ connect( mySMESHGUI, SIGNAL ( SignalCloseAllDialogs() ), this, SLOT( ClickOnCancel() ) ) ;
+
+ /* Move widget on the botton right corner of main widget */
+ int x, y ;
+ mySMESHGUI->DefineDlgPosition( this, x, y ) ;
+ this->move( x, y ) ;
+ this->show() ; /* displays Dialog */
+}
+
+
+//=================================================================================
+// function : ClickOnOk()
+// purpose :
+//=================================================================================
+void StdMeshersGUI_MaxElementVolumeDlg::ClickOnOk()
+{
+ if ( this->ClickOnApply() )
+ this->ClickOnCancel() ;
+}
+
+//=================================================================================
+// function : ClickOnApply()
+// purpose :
+//=================================================================================
+bool StdMeshersGUI_MaxElementVolumeDlg::ClickOnApply()
+{
+ QString myHypName = LineEdit_NameHypothesis->text().stripWhiteSpace();
+ if ( myHypName.isEmpty() ) {
+ QAD_MessageBox::warn1( this, tr( "SMESH_WRN_WARNING" ), tr( "SMESH_WRN_EMPTY_NAME" ), tr( "SMESH_BUT_OK" ) );
+ return false;
+ }
+
+ double myMaxElementVolume = SpinBox_MaxElementVolume->GetValue();
+
+ QAD_WaitCursor wc;
+ try {
+ SMESH::SMESH_Hypothesis_var Hyp = SMESH::SMESH_Hypothesis::_narrow
+ (mySMESHGUI->CreateHypothesis(myHypType,
+ myHypName,
+ false)); // isAlgorithm
+ StdMeshers::StdMeshers_MaxElementVolume_var MaxElVolume =
+ StdMeshers::StdMeshers_MaxElementVolume::_narrow(Hyp);
+ if (!MaxElVolume->_is_nil())
+ MaxElVolume->SetMaxElementVolume(myMaxElementVolume);
+ }
+ catch (const SALOME::SALOME_Exception& S_ex) {
+ wc.stop();
+ QtCatchCorbaException(S_ex);
+ return false;
+ }
+ return true;
+}
+
+
+//=================================================================================
+// function : ClickOnCancel()
+// purpose :
+//=================================================================================
+void StdMeshersGUI_MaxElementVolumeDlg::ClickOnCancel()
+{
+ close();
+}
+
+
+//=================================================================================
+// function : DeactivateActiveDialog()
+// purpose :
+//=================================================================================
+void StdMeshersGUI_MaxElementVolumeDlg::DeactivateActiveDialog()
+{
+ iconLabel->setEnabled(false) ;
+ typeLabel->setEnabled(false) ;
+ GroupC1->setEnabled(false) ;
+ GroupButtons->setEnabled(false) ;
+}
+
+
+//=================================================================================
+// function : ActivateThisDialog()
+// purpose :
+//=================================================================================
+void StdMeshersGUI_MaxElementVolumeDlg::ActivateThisDialog()
+{
+ mySMESHGUI->EmitSignalDeactivateDialog() ;
+ iconLabel->setEnabled(true) ;
+ typeLabel->setEnabled(true) ;
+ GroupC1->setEnabled(true) ;
+ GroupButtons->setEnabled(true) ;
+}
+
+
+//=================================================================================
+// function : enterEvent()
+// purpose :
+//=================================================================================
+void StdMeshersGUI_MaxElementVolumeDlg::enterEvent(QEvent* e)
+{
+ ActivateThisDialog() ;
+}
+
+
+//=================================================================================
+// function : closeEvent()
+// purpose :
+//=================================================================================
+void StdMeshersGUI_MaxElementVolumeDlg::closeEvent( QCloseEvent* e )
+{
+ mySMESHGUI->ResetState();
+ QDialog::closeEvent( e );
+}
--- /dev/null
+// SMESH SMESHGUI : GUI for SMESH component
+//
+// Copyright (C) 2003 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
+// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
+//
+// This library 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.
+//
+// This library 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 this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+//
+// See http://www.opencascade.org/SALOME/ or email : webmaster.salome@opencascade.org
+//
+//
+//
+// File : StdMeshersGUI_MaxElementVolumeDlg.h
+// Moved here from SMESHGUI_MaxElementVolumeDlg.h
+// Author : Nicolas REJNERI
+// Module : SMESH
+// $Header$
+
+#ifndef DIALOGBOX_MAX_ELEMENT_VOLUME_H
+#define DIALOGBOX_MAX_ELEMENT_VOLUME_H
+
+// QT Includes
+#include <qdialog.h>
+
+class QGroupBox;
+class QLabel;
+class QLineEdit;
+class QPushButton;
+class SMESHGUI;
+class SMESHGUI_SpinBox;
+
+//=================================================================================
+// class : StdMeshersGUI_MaxElementVolumeDlg
+// purpose :
+//=================================================================================
+class StdMeshersGUI_MaxElementVolumeDlg : public QDialog
+{
+ Q_OBJECT
+
+public:
+ StdMeshersGUI_MaxElementVolumeDlg (const QString& hypType,
+ QWidget* parent = 0,
+ const char* name = 0,
+ bool modal = FALSE,
+ WFlags fl = 0 );
+ ~StdMeshersGUI_MaxElementVolumeDlg ();
+
+private:
+
+ void Init() ;
+ void closeEvent( QCloseEvent* e ) ;
+ void enterEvent ( QEvent * ) ;
+
+ SMESHGUI* mySMESHGUI ;
+ QString myHypType ;
+
+ QLabel* iconLabel;
+ QLabel* typeLabel;
+ QGroupBox* GroupButtons;
+ QPushButton* buttonApply;
+ QPushButton* buttonOk;
+ QPushButton* buttonCancel;
+ QGroupBox* GroupC1;
+ QLabel* TextLabel_NameHypothesis ;
+ QLineEdit* LineEdit_NameHypothesis ;
+ QLabel* TextLabel_MaxElementVolume ;
+ SMESHGUI_SpinBox* SpinBox_MaxElementVolume ;
+
+private slots:
+
+ void ClickOnOk();
+ void ClickOnCancel();
+ bool ClickOnApply();
+ void DeactivateActiveDialog() ;
+ void ActivateThisDialog() ;
+};
+
+#endif // DIALOGBOX_MAX_ELEMENT_VOLUME_H
--- /dev/null
+// SMESH SMESHGUI : GUI for SMESH component
+//
+// Copyright (C) 2003 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
+// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
+//
+// This library 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.
+//
+// This library 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 this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+//
+// See http://www.opencascade.org/SALOME/ or email : webmaster.salome@opencascade.org
+//
+//
+//
+// File : StdMeshersGUI_NbSegmentsDlg.cxx
+// Moved here from SMESHGUI_NbSegmentsDlg.cxx
+// Author : Nicolas REJNERI
+// Module : SMESH
+// $Header$
+
+using namespace std;
+#include "StdMeshersGUI_NbSegmentsDlg.h"
+#include "SMESHGUI.h"
+
+#include <SALOMEconfig.h>
+#include CORBA_SERVER_HEADER(SMESH_BasicHypothesis)
+
+#include "QAD_Application.h"
+#include "QAD_Desktop.h"
+#include "utilities.h"
+
+#include "SALOMEGUI_QtCatchCorbaException.hxx"
+#include "QAD_MessageBox.h"
+#include "QAD_WaitCursor.h"
+
+// QT Includes
+#include <qgroupbox.h>
+#include <qlabel.h>
+#include <qlineedit.h>
+#include <qpushbutton.h>
+#include <qlayout.h>
+#include <qpixmap.h>
+#include <qspinbox.h>
+
+//=================================================================================
+// class : StdMeshersGUI_NbSegmentsDlg()
+// purpose : Constructs a StdMeshersGUI_NbSegmentsDlg which is a child of 'parent', with the
+// name 'name' and widget flags set to 'f'.
+// The dialog will by default be modeless, unless you set 'modal' to
+// TRUE to construct a modal dialog.
+//=================================================================================
+StdMeshersGUI_NbSegmentsDlg::StdMeshersGUI_NbSegmentsDlg (const QString& hypType,
+ QWidget* parent,
+ const char* name,
+ bool modal,
+ WFlags fl)
+ : QDialog (parent, name, modal, WStyle_Customize | WStyle_NormalBorder | WStyle_Title | WStyle_SysMenu | WDestructiveClose),
+ myHypType(hypType)
+{
+ QPixmap image0(QAD_Desktop::getResourceManager()->loadPixmap( "SMESH",tr("ICON_DLG_NB_SEGMENTS")));
+
+ if ( !name )
+ setName( "StdMeshersGUI_NbSegmentsDlg" );
+ setCaption( tr( "SMESH_NB_SEGMENTS_TITLE" ) );
+ setSizeGripEnabled( TRUE );
+ QGridLayout* StdMeshersGUI_NbSegmentsDlgLayout = new QGridLayout( this );
+ StdMeshersGUI_NbSegmentsDlgLayout->setSpacing( 6 );
+ StdMeshersGUI_NbSegmentsDlgLayout->setMargin( 11 );
+
+ /***************************************************************/
+ iconLabel = new QLabel( this );
+ iconLabel->setPixmap( image0 );
+ iconLabel->setScaledContents( false );
+ iconLabel->setSizePolicy( QSizePolicy( QSizePolicy::Fixed, QSizePolicy::Fixed ) );
+ typeLabel = new QLabel( this );
+ typeLabel->setText( tr( "SMESH_NB_SEGMENTS_HYPOTHESIS" ) );
+ StdMeshersGUI_NbSegmentsDlgLayout->addWidget( iconLabel, 0, 0 );
+ StdMeshersGUI_NbSegmentsDlgLayout->addWidget( typeLabel, 0, 1 );
+
+ /***************************************************************/
+ GroupC1 = new QGroupBox( this, "GroupC1" );
+ GroupC1->setTitle( tr( "SMESH_ARGUMENTS" ) );
+ GroupC1->setColumnLayout(0, Qt::Vertical );
+ GroupC1->layout()->setSpacing( 0 );
+ GroupC1->layout()->setMargin( 0 );
+ QGridLayout* GroupC1Layout = new QGridLayout( GroupC1->layout() );
+ GroupC1Layout->setAlignment( Qt::AlignTop );
+ GroupC1Layout->setSpacing( 6 );
+ GroupC1Layout->setMargin( 11 );
+
+ LineEdit_NameHypothesis = new QLineEdit( GroupC1, "LineEdit_NameHypothesis" );
+ GroupC1Layout->addWidget( LineEdit_NameHypothesis, 0, 1 );
+
+ TextLabel_NameHypothesis = new QLabel( GroupC1, "TextLabel_NameHypothesis" );
+ TextLabel_NameHypothesis->setText( tr( "SMESH_NAME" ) );
+ GroupC1Layout->addWidget( TextLabel_NameHypothesis, 0, 0 );
+
+ TextLabel_NbSeg = new QLabel(GroupC1 , "TextLabel_NbSeg" );
+ TextLabel_NbSeg->setText( tr( "SMESH_SEGMENTS" ) );
+ GroupC1Layout->addWidget( TextLabel_NbSeg, 1, 0 );
+
+ SpinBox_NbSeg = new QSpinBox( GroupC1, "SpinBox_NbSeg" );
+ GroupC1Layout->addWidget( SpinBox_NbSeg, 1, 1 );
+
+ StdMeshersGUI_NbSegmentsDlgLayout->addMultiCellWidget(GroupC1 , 1, 1, 0, 1 );
+
+ /***************************************************************/
+ GroupButtons = new QGroupBox( this, "GroupButtons" );
+ GroupButtons->setColumnLayout(0, Qt::Vertical );
+ GroupButtons->layout()->setSpacing( 0 );
+ GroupButtons->layout()->setMargin( 0 );
+ QGridLayout* GroupButtonsLayout = new QGridLayout( GroupButtons->layout() );
+ GroupButtonsLayout->setAlignment( Qt::AlignTop );
+ GroupButtonsLayout->setSpacing( 6 );
+ GroupButtonsLayout->setMargin( 11 );
+ buttonOk = new QPushButton( GroupButtons, "buttonOk" );
+ buttonOk->setText( tr( "SMESH_BUT_OK" ) );
+ buttonOk->setAutoDefault( TRUE );
+ buttonOk->setDefault( TRUE );
+ GroupButtonsLayout->addWidget( buttonOk, 0, 0 );
+ buttonApply = new QPushButton( GroupButtons, "buttonApply" );
+ buttonApply->setText( tr( "SMESH_BUT_APPLY" ) );
+ buttonApply->setAutoDefault( TRUE );
+ GroupButtonsLayout->addWidget( buttonApply, 0, 1 );
+ QSpacerItem* spacer = new QSpacerItem( 20, 20, QSizePolicy::Expanding, QSizePolicy::Minimum );
+ GroupButtonsLayout->addItem( spacer, 0, 2 );
+ buttonCancel = new QPushButton( GroupButtons, "buttonCancel" );
+ buttonCancel->setText( tr( "SMESH_BUT_CLOSE" ) );
+ buttonCancel->setAutoDefault( TRUE );
+ GroupButtonsLayout->addWidget( buttonCancel, 0, 3 );
+ StdMeshersGUI_NbSegmentsDlgLayout->addMultiCellWidget( GroupButtons, 2, 2, 0, 1 );
+
+ /***************************************************************/
+ Init() ;
+}
+
+
+//=================================================================================
+// function : ~StdMeshersGUI_NbSegmentsDlg()
+// purpose : Destroys the object and frees any allocated resources
+//=================================================================================
+StdMeshersGUI_NbSegmentsDlg::~StdMeshersGUI_NbSegmentsDlg()
+{
+ // no need to delete child widgets, Qt does it all for us
+}
+
+
+//=================================================================================
+// function : Init()
+// purpose :
+//=================================================================================
+void StdMeshersGUI_NbSegmentsDlg::Init()
+{
+ SpinBox_NbSeg->setMinValue( 1 );
+ SpinBox_NbSeg->setMaxValue( 9999 );
+ SpinBox_NbSeg->setValue(3) ; /* myNbSeg */
+
+ mySMESHGUI = SMESHGUI::GetSMESHGUI() ;
+
+ char* sHypType = (char*)myHypType.latin1();
+ HypothesisData* aHypData = mySMESHGUI->GetHypothesisData(sHypType);
+ LineEdit_NameHypothesis->setText( aHypData ? aHypData->Label : "" );
+
+ mySMESHGUI->SetActiveDialogBox( (QDialog*)this ) ;
+
+ /* signals and slots connections */
+ connect( buttonOk, SIGNAL(clicked()), this, SLOT(ClickOnOk()) );
+ connect( buttonCancel, SIGNAL(clicked()), this, SLOT(ClickOnCancel()) ) ;
+ connect( buttonApply, SIGNAL(clicked()), this, SLOT(ClickOnApply()) );
+
+ connect( mySMESHGUI, SIGNAL ( SignalDeactivateActiveDialog() ), this, SLOT( DeactivateActiveDialog() ) ) ;
+ connect( mySMESHGUI, SIGNAL ( SignalCloseAllDialogs() ), this, SLOT( ClickOnCancel() ) ) ;
+
+ /* Move widget on the botton right corner of main widget */
+ int x, y ;
+ mySMESHGUI->DefineDlgPosition( this, x, y ) ;
+ this->move( x, y ) ;
+ this->show() ; /* displays Dialog */
+}
+
+
+//=================================================================================
+// function : ClickOnOk()
+// purpose :
+//=================================================================================
+void StdMeshersGUI_NbSegmentsDlg::ClickOnOk()
+{
+ if ( this->ClickOnApply() )
+ this->ClickOnCancel() ;
+}
+
+//=================================================================================
+// function : ClickOnApply()
+// purpose :
+//=================================================================================
+bool StdMeshersGUI_NbSegmentsDlg::ClickOnApply()
+{
+ QString myHypName = LineEdit_NameHypothesis->text().stripWhiteSpace();
+ if ( myHypName.isEmpty() ) {
+ QAD_MessageBox::warn1( this, tr( "SMESH_WRN_WARNING" ), tr( "SMESH_WRN_EMPTY_NAME" ), tr( "SMESH_BUT_OK" ) );
+ return false;
+ }
+
+ long myNbSeg = SpinBox_NbSeg->value();
+
+ QAD_WaitCursor wc;
+ try {
+ SMESH::SMESH_Hypothesis_var Hyp = SMESH::SMESH_Hypothesis::_narrow
+ (mySMESHGUI->CreateHypothesis(myHypType,
+ myHypName,
+ false)); // isAlgorithm
+ StdMeshers::StdMeshers_NumberOfSegments_var NbS =
+ StdMeshers::StdMeshers_NumberOfSegments::_narrow(Hyp);
+ if (!NbS->_is_nil())
+ NbS->SetNumberOfSegments(myNbSeg);
+ }
+ catch (const SALOME::SALOME_Exception& S_ex) {
+ wc.stop();
+ QtCatchCorbaException(S_ex);
+ return false;
+ }
+ return true;
+}
+
+
+//=================================================================================
+// function : ClickOnCancel()
+// purpose :
+//=================================================================================
+void StdMeshersGUI_NbSegmentsDlg::ClickOnCancel()
+{
+ close();
+}
+
+//=================================================================================
+// function : DeactivateActiveDialog()
+// purpose :
+//=================================================================================
+void StdMeshersGUI_NbSegmentsDlg::DeactivateActiveDialog()
+{
+ iconLabel->setEnabled(false) ;
+ typeLabel->setEnabled(false) ;
+ GroupC1->setEnabled(false) ;
+ GroupButtons->setEnabled(false) ;
+}
+
+
+//=================================================================================
+// function : ActivateThisDialog()
+// purpose :
+//=================================================================================
+void StdMeshersGUI_NbSegmentsDlg::ActivateThisDialog()
+{
+ mySMESHGUI->EmitSignalDeactivateDialog() ;
+ iconLabel->setEnabled(true) ;
+ typeLabel->setEnabled(true) ;
+ GroupC1->setEnabled(true) ;
+ GroupButtons->setEnabled(true) ;
+}
+
+
+//=================================================================================
+// function : enterEvent()
+// purpose :
+//=================================================================================
+void StdMeshersGUI_NbSegmentsDlg::enterEvent(QEvent* e)
+{
+ ActivateThisDialog() ;
+}
+
+
+//=================================================================================
+// function : closeEvent()
+// purpose :
+//=================================================================================
+void StdMeshersGUI_NbSegmentsDlg::closeEvent( QCloseEvent* e )
+{
+ mySMESHGUI->ResetState();
+ QDialog::closeEvent( e );
+}
--- /dev/null
+// SMESH SMESHGUI : GUI for SMESH component
+//
+// Copyright (C) 2003 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
+// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
+//
+// This library 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.
+//
+// This library 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 this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+//
+// See http://www.opencascade.org/SALOME/ or email : webmaster.salome@opencascade.org
+//
+//
+//
+// File : StdMeshersGUI_NbSegmentsDlg.h
+// Moved here from SMESHGUI_NbSegmentsDlg.h
+// Author : Nicolas REJNERI
+// Module : SMESH
+// $Header$
+
+#ifndef DIALOGBOX_NB_SEGMENTS_H
+#define DIALOGBOX_NB_SEGMENTS_H
+
+// QT Includes
+#include <qdialog.h>
+
+class QGroupBox;
+class QLabel;
+class QLineEdit;
+class QSpinBox;
+class QPushButton;
+class SMESHGUI;
+
+//=================================================================================
+// class : StdMeshersGUI_NbSegmentsDlg
+// purpose :
+//=================================================================================
+class StdMeshersGUI_NbSegmentsDlg : public QDialog
+{
+ Q_OBJECT
+
+public:
+ StdMeshersGUI_NbSegmentsDlg (const QString& hypType,
+ QWidget* parent = 0,
+ const char* name = 0,
+ bool modal = FALSE,
+ WFlags fl = 0);
+ ~StdMeshersGUI_NbSegmentsDlg ();
+
+private:
+
+ void Init() ;
+ void closeEvent( QCloseEvent* e ) ;
+ void enterEvent ( QEvent * ) ;
+
+ SMESHGUI* mySMESHGUI ;
+ QString myHypType ;
+
+ QLabel* iconLabel;
+ QLabel* typeLabel;
+ QGroupBox* GroupC1;
+ QLabel* TextLabel_NameHypothesis ;
+ QLineEdit* LineEdit_NameHypothesis ;
+ QLabel* TextLabel_NbSeg ;
+ QSpinBox* SpinBox_NbSeg ;
+ QGroupBox* GroupButtons;
+ QPushButton* buttonApply;
+ QPushButton* buttonOk;
+ QPushButton* buttonCancel;
+
+private slots:
+
+ void ClickOnOk();
+ void ClickOnCancel();
+ bool ClickOnApply();
+ void DeactivateActiveDialog() ;
+ void ActivateThisDialog() ;
+};
+
+#endif // DIALOGBOX_NB_SEGMENTS_H
--- /dev/null
+# This is a Qt message file in .po format. Each msgid starts with
+# a scope. This scope should *NOT* be translated - eg. "Foo::Bar"
+# would be translated to "Pub", not "Foo::Pub".
+msgid ""
+msgstr ""
+"Project-Id-Version: PROJECT VERSION\n"
+"POT-Creation-Date: 2002-05-28 10:57:43 AM CEST\n"
+"PO-Revision-Date: YYYY-MM-DD\n"
+"Last-Translator: FULLNAME <EMAIL@ADDRESS>\n"
+"Content-Type: text/plain; charset=iso-8859-1\n"
+
+
+#Select Icon
+msgid "ICON_SELECT"
+msgstr "select1.png"
+
+
+#-----------------------------------------------------------
+# Hypothesis
+#-----------------------------------------------------------
+
+#Hypo Local Length
+msgid "ICON_DLG_LOCAL_LENGTH"
+msgstr "mesh_hypo_length.png"
+
+#Hypo Nb Segments
+msgid "ICON_DLG_NB_SEGMENTS"
+msgstr "mesh_hypo_segment.png"
+
+#Hypo Max Area
+msgid "ICON_DLG_MAX_ELEMENT_AREA"
+msgstr "mesh_hypo_area.png"
+
+#Hypo Max Volume
+msgid "ICON_DLG_MAX_ELEMENT_VOLUME"
+msgstr "mesh_hypo_volume.png"
+
+
+#-----------------------------------------------------------
+# ObjectBrowser
+#-----------------------------------------------------------
+
+#mesh_tree_algo_regular
+msgid "ICON_SMESH_TREE_ALGO_Regular_1D"
+msgstr "mesh_tree_algo_regular.png"
+
+#mesh_tree_algo_hexa
+msgid "ICON_SMESH_TREE_ALGO_Hexa_3D"
+msgstr "mesh_tree_algo_hexa.png"
+
+#mesh_tree_algo_mefisto
+msgid "ICON_SMESH_TREE_ALGO_MEFISTO_2D"
+msgstr "mesh_tree_algo_mefisto.png"
+
+#mesh_tree_algo_quad
+msgid "ICON_SMESH_TREE_ALGO_Quadrangle_2D"
+msgstr "mesh_tree_algo_quad.png"
+
+#mesh_tree_hypo_area
+msgid "ICON_SMESH_TREE_HYPO_MaxElementArea"
+msgstr "mesh_tree_hypo_area.png"
+
+#mesh_tree_hypo_length
+msgid "ICON_SMESH_TREE_HYPO_LocalLength"
+msgstr "mesh_tree_hypo_length.png"
+
+#mesh_tree_hypo_segment
+msgid "ICON_SMESH_TREE_HYPO_NumberOfSegments"
+msgstr "mesh_tree_hypo_segment.png"
+
+#mesh_tree_hypo_volume
+msgid "ICON_SMESH_TREE_HYPO_MaxElementVolume"
+msgstr "mesh_tree_hypo_volume.png"
+
+#mesh_tree_hypo_length
+msgid "ICON_SMESH_TREE_HYPO_LengthFromEdges"
+msgstr "mesh_tree_hypo_length.png"
+
+#mesh_tree_hypo_nonconform
+msgid "ICON_SMESH_TREE_HYPO_NotConformAllowed"
+msgstr "mesh_tree_hypo_length.png"
--- /dev/null
+# This is a Qt message file in .po format. Each msgid starts with
+# a scope. This scope should *NOT* be translated - eg. "Foo::Bar"
+# would be translated to "Pub", not "Foo::Pub".
+msgid ""
+msgstr ""
+"Project-Id-Version: PROJECT VERSION\n"
+"POT-Creation-Date: 2002-05-28 10:46:48 AM CEST\n"
+"PO-Revision-Date: YYYY-MM-DD\n"
+"Last-Translator: FULLNAME <EMAIL@ADDRESS>\n"
+"Content-Type: text/plain; charset=iso-8859-1\n"
+
+
+# -------------- Local Length --------------
+
+msgid "SMESH_LOCAL_LENGTH_HYPOTHESIS"
+msgstr "Local Length"
+
+msgid "SMESH_LOCAL_LENGTH_TITLE"
+msgstr "Hypothesis Construction"
+
+# ----------- Number of Segments -----------
+
+msgid "SMESH_NB_SEGMENTS_HYPOTHESIS"
+msgstr "Number of Segments"
+
+msgid "SMESH_NB_SEGMENTS_TITLE"
+msgstr "Hypothesis Construction"
+
+# ----------- Max. Element Area ------------
+
+msgid "SMESH_MAX_ELEMENT_AREA"
+msgstr "Max. Area"
+
+msgid "SMESH_MAX_ELEMENT_AREA_HYPOTHESIS"
+msgstr "Max. Element Area"
+
+msgid "SMESH_MAX_ELEMENT_AREA_TITLE"
+msgstr "Hypothesis Construction"
+
+# ---------- Max. Element Volume -----------
+
+msgid "SMESH_MAX_ELEMENT_VOLUME"
+msgstr "Max. Volume"
+
+msgid "SMESH_MAX_ELEMENT_VOLUME_HYPOTHESIS"
+msgstr "Max. Element Volume"
+
+msgid "SMESH_MAX_ELEMENT_VOLUME_TITLE"
+msgstr "Hypothesis Construction"
--- /dev/null
+# SMESH StdMeshers_I : idl implementation based on 'StdMeshersPlugin' unit's classes
+#
+# Copyright (C) 2003 CEA
+#
+# This library 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.
+#
+# This library 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 this library; if not, write to the Free Software
+# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+#
+# See http://www.salome-platform.org or email : webmaster.salome@opencascade.org
+#
+#
+#
+# File : Makefile.in
+# Author : Julia DOROVSKIKH
+# Module : SMESH
+# $Header$
+
+top_srcdir=@top_srcdir@
+top_builddir=../..
+srcdir=@srcdir@
+VPATH=.:@srcdir@:@top_srcdir@/idl:$(top_builddir)/idl
+
+
+@COMMENCE@
+
+# EXPORT_PYSCRIPTS = smeshpy.py SMESH_test.py
+
+# Libraries targets
+
+LIB= libStdMeshersEngine.la
+
+LIB_SRC = \
+ StdMeshers_i.cxx \
+ StdMeshers_LocalLength_i.cxx \
+ StdMeshers_LengthFromEdges_i.cxx \
+ StdMeshers_MaxElementArea_i.cxx \
+ StdMeshers_MaxElementVolume_i.cxx \
+ StdMeshers_NumberOfSegments_i.cxx \
+ StdMeshers_NotConformAllowed_i.cxx \
+ StdMeshers_Regular_1D_i.cxx \
+ StdMeshers_Quadrangle_2D_i.cxx \
+ StdMeshers_MEFISTO_2D_i.cxx \
+ StdMeshers_Hexa_3D_i.cxx
+
+LIB_SERVER_IDL = SMESH_BasicHypothesis.idl
+
+LIB_CLIENT_IDL = \
+ SALOMEDS.idl SALOME_Exception.idl \
+ GEOM_Gen.idl GEOM_Shape.idl MED.idl SALOMEDS_Attributes.idl \
+ SMESH_Gen.idl SMESH_Hypothesis.idl SMESH_Group.idl
+
+# Executables targets
+BIN =
+BIN_SRC =
+
+# additionnal information to compil and link file
+CPPFLAGS+= $(OCC_INCLUDES) $(HDF5_INCLUDES) -I${KERNEL_ROOT_DIR}/include/salome \
+ -I${GEOM_ROOT_DIR}/include/salome $(BOOST_CPPFLAGS)
+CXXFLAGS+= $(OCC_CXXFLAGS) $(HDF5_INCLUDES) -I${KERNEL_ROOT_DIR}/include/salome -I${GEOM_ROOT_DIR}/include/salome
+
+#IDLCXXFLAGS+= -Wbtp
+
+#LDFLAGS+= $(HDF5_LIBS) -lStdMeshers -lSMESHEngine -lSalomeLifeCycleCORBA -L${KERNEL_ROOT_DIR}/lib/salome -L${GEOM_ROOT_DIR}/lib/salome -lSalomeGenericObj
+LDFLAGS+= $(HDF5_LIBS) -lStdMeshers -lSMESHEngine -L${KERNEL_ROOT_DIR}/lib/salome
+
+@CONCLUDE@
--- /dev/null
+// SMESH SMESH_I : idl implementation based on 'SMESH' unit's calsses
+//
+// Copyright (C) 2003 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
+// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
+//
+// This library 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.
+//
+// This library 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 this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+//
+// See http://www.opencascade.org/SALOME/ or email : webmaster.salome@opencascade.org
+//
+//
+//
+// File : StdMeshers_Hexa_3D_i.cxx
+// Moved here from SMESH_Hexa_3D_i.cxx
+// Author : Paul RASCLE, EDF
+// Module : SMESH
+// $Header$
+
+using namespace std;
+#include "StdMeshers_Hexa_3D_i.hxx"
+#include "SMESH_Gen.hxx"
+
+#include "Utils_CorbaException.hxx"
+#include "utilities.h"
+
+//=============================================================================
+/*!
+ * StdMeshers_Hexa_3D_i::StdMeshers_Hexa_3D_i
+ *
+ * Constructor
+ */
+//=============================================================================
+
+StdMeshers_Hexa_3D_i::StdMeshers_Hexa_3D_i( PortableServer::POA_ptr thePOA,
+ int theStudyId,
+ ::SMESH_Gen* theGenImpl )
+ : SALOME::GenericObj_i( thePOA ),
+ SMESH_Hypothesis_i( thePOA ),
+ SMESH_Algo_i( thePOA ),
+ SMESH_3D_Algo_i( thePOA )
+{
+ MESSAGE( "StdMeshers_Hexa_3D_i::StdMeshers_Hexa_3D_i" );
+ myBaseImpl = new ::StdMeshers_Hexa_3D( theGenImpl->GetANewId(),
+ theStudyId,
+ theGenImpl );
+}
+
+//=============================================================================
+/*!
+ * StdMeshers_Hexa_3D_i::~StdMeshers_Hexa_3D_i
+ *
+ * Destructor
+ */
+//=============================================================================
+
+StdMeshers_Hexa_3D_i::~StdMeshers_Hexa_3D_i()
+{
+ MESSAGE( "StdMeshers_Hexa_3D_i::~StdMeshers_Hexa_3D_i" );
+}
+
+//=============================================================================
+/*!
+ * StdMeshers_Hexa_3D_i::GetImpl
+ *
+ * Get implementation
+ */
+//=============================================================================
+
+::StdMeshers_Hexa_3D* StdMeshers_Hexa_3D_i::GetImpl()
+{
+ MESSAGE( "StdMeshers_Hexa_3D_i::GetImpl" );
+ return ( ::StdMeshers_Hexa_3D* )myBaseImpl;
+}
--- /dev/null
+// SMESH SMESH_I : idl implementation based on 'SMESH' unit's calsses
+//
+// Copyright (C) 2003 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
+// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
+//
+// This library 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.
+//
+// This library 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 this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+//
+// See http://www.opencascade.org/SALOME/ or email : webmaster.salome@opencascade.org
+//
+//
+//
+// File : StdMeshers_Hexa_3D_i.hxx
+// Moved here from SMESH_Hexa_3D_i.hxx
+// Author : Paul RASCLE, EDF
+// Module : SMESH
+// $Header$
+
+#ifndef _SMESH_HEXA_3D_I_HXX_
+#define _SMESH_HEXA_3D_I_HXX_
+
+#include <SALOMEconfig.h>
+#include CORBA_SERVER_HEADER(SMESH_BasicHypothesis)
+
+#include "SMESH_3D_Algo_i.hxx"
+#include "StdMeshers_Hexa_3D.hxx"
+
+class SMESH_Gen;
+
+// ======================================================
+// Hexaedron 3d algorithm
+// ======================================================
+class StdMeshers_Hexa_3D_i:
+ public virtual POA_StdMeshers::StdMeshers_Hexa_3D,
+ public virtual SMESH_3D_Algo_i
+{
+public:
+ // Constructor
+ StdMeshers_Hexa_3D_i( PortableServer::POA_ptr thePOA,
+ int theStudyId,
+ ::SMESH_Gen* theGenImpl );
+
+ // Destructor
+ virtual ~StdMeshers_Hexa_3D_i();
+
+ // Get implementation
+ ::StdMeshers_Hexa_3D* GetImpl();
+};
+
+#endif
--- /dev/null
+// SMESH SMESH_I : idl implementation based on 'SMESH' unit's calsses
+//
+// Copyright (C) 2003 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
+// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
+//
+// This library 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.
+//
+// This library 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 this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+//
+// See http://www.opencascade.org/SALOME/ or email : webmaster.salome@opencascade.org
+//
+//
+//
+// File : StdMeshers_LengthFromEdges_i.cxx
+// Moved here from SMESH_LengthFromEdges_i.cxx
+// Author : Nadir BOUHAMOU CEA/DEN, Paul RASCLE, EDF
+// Module : SMESH
+// $Header$
+
+using namespace std;
+#include "StdMeshers_LengthFromEdges_i.hxx"
+#include "SMESH_Gen.hxx"
+
+#include "Utils_CorbaException.hxx"
+#include "utilities.h"
+
+//=============================================================================
+/*!
+ * StdMeshers_LengthFromEdges_i::StdMeshers_LengthFromEdges_i
+ *
+ * Constructor
+ */
+//=============================================================================
+
+StdMeshers_LengthFromEdges_i::StdMeshers_LengthFromEdges_i( PortableServer::POA_ptr thePOA,
+ int theStudyId,
+ ::SMESH_Gen* theGenImpl )
+ : SALOME::GenericObj_i( thePOA ),
+ SMESH_Hypothesis_i( thePOA )
+{
+ MESSAGE( "StdMeshers_LengthFromEdges_i::StdMeshers_LengthFromEdges_i" );
+ myBaseImpl = new ::StdMeshers_LengthFromEdges( theGenImpl->GetANewId(),
+ theStudyId,
+ theGenImpl );
+}
+
+//=============================================================================
+/*!
+ * StdMeshers_LengthFromEdges_i::~StdMeshers_LengthFromEdges_i
+ *
+ * Destructor
+ */
+//=============================================================================
+
+StdMeshers_LengthFromEdges_i::~StdMeshers_LengthFromEdges_i()
+{
+ MESSAGE( "StdMeshers_LengthFromEdges_i::~StdMeshers_LengthFromEdges_i" );
+}
+
+//=============================================================================
+/*!
+ * StdMeshers_LengthFromEdges_i::SetMode
+ *
+ * Set mode
+ */
+//=============================================================================
+
+void StdMeshers_LengthFromEdges_i::SetMode( CORBA::Long theMode )
+ throw (SALOME::SALOME_Exception)
+{
+ MESSAGE( "StdMeshers_LengthFromEdges_i::SetMode" );
+ ASSERT( myBaseImpl );
+ try {
+ this->GetImpl()->SetMode( theMode );
+ }
+ catch ( SALOME_Exception& S_ex ) {
+ THROW_SALOME_CORBA_EXCEPTION( S_ex.what(),
+ SALOME::BAD_PARAM );
+ }
+}
+
+//=============================================================================
+/*!
+ * StdMeshers_LengthFromEdges_i::GetMode
+ *
+ * Get mode
+ */
+//=============================================================================
+
+CORBA::Long StdMeshers_LengthFromEdges_i::GetMode()
+{
+ MESSAGE( "StdMeshers_LengthFromEdges_i::GetMode" );
+ ASSERT( myBaseImpl );
+ return this->GetImpl()->GetMode();
+}
+
+
+//=============================================================================
+/*!
+ * StdMeshers_LengthFromEdges_i::GetImpl
+ *
+ * Get implementation
+ */
+//=============================================================================
+
+::StdMeshers_LengthFromEdges* StdMeshers_LengthFromEdges_i::GetImpl()
+{
+ MESSAGE( "StdMeshers_LengthFromEdges_i::GetImpl" );
+ return ( ::StdMeshers_LengthFromEdges* )myBaseImpl;
+}
+
--- /dev/null
+// SMESH SMESH_I : idl implementation based on 'SMESH' unit's calsses
+//
+// Copyright (C) 2003 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
+// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
+//
+// This library 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.
+//
+// This library 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 this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+//
+// See http://www.opencascade.org/SALOME/ or email : webmaster.salome@opencascade.org
+//
+//
+//
+// File : StdMeshers_LengthFromEdges_i.hxx
+// Moved here from SMESH_LengthFromEdges_i.hxx
+// Author : Nadir BOUHAMOU CEA/DEN, Paul RASCLE, EDF
+// Module : SMESH
+// $Header$
+
+#ifndef _SMESH_LENGTHFROMEDGES_I_HXX_
+#define _SMESH_LENGTHFROMEDGES_I_HXX_
+
+#include <SALOMEconfig.h>
+#include CORBA_SERVER_HEADER(SMESH_BasicHypothesis)
+
+#include "SMESH_Hypothesis_i.hxx"
+#include "StdMeshers_LengthFromEdges.hxx"
+
+// ======================================================
+// Length from edges hypothesis
+// ======================================================
+class StdMeshers_LengthFromEdges_i:
+ public virtual POA_StdMeshers::StdMeshers_LengthFromEdges,
+ public virtual SMESH_Hypothesis_i
+{
+public:
+ // Constructor
+ StdMeshers_LengthFromEdges_i( PortableServer::POA_ptr thePOA,
+ int theStudyId,
+ ::SMESH_Gen* theGenImpl );
+ // Destructor
+ virtual ~StdMeshers_LengthFromEdges_i();
+
+ // Set mode
+ void SetMode( CORBA::Long theMode )
+ throw ( SALOME::SALOME_Exception );
+ // Get mode
+ CORBA::Long GetMode();
+
+ // Get implementation
+ ::StdMeshers_LengthFromEdges* GetImpl();
+};
+
+#endif
+
--- /dev/null
+// SMESH SMESH_I : idl implementation based on 'SMESH' unit's calsses
+//
+// Copyright (C) 2003 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
+// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
+//
+// This library 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.
+//
+// This library 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 this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+//
+// See http://www.opencascade.org/SALOME/ or email : webmaster.salome@opencascade.org
+//
+//
+//
+// File : StdMeshers_LocalLength_i.cxx
+// Moved here from SMESH_LocalLength_i.cxx
+// Author : Paul RASCLE, EDF
+// Module : SMESH
+// $Header$
+
+using namespace std;
+#include "StdMeshers_LocalLength_i.hxx"
+#include "SMESH_Gen.hxx"
+
+#include "Utils_CorbaException.hxx"
+#include "utilities.h"
+
+//=============================================================================
+/*!
+ * StdMeshers_LocalLength_i::StdMeshers_LocalLength_i
+ *
+ * Constructor
+ */
+//=============================================================================
+
+StdMeshers_LocalLength_i::StdMeshers_LocalLength_i( PortableServer::POA_ptr thePOA,
+ int theStudyId,
+ ::SMESH_Gen* theGenImpl )
+ : SALOME::GenericObj_i( thePOA ),
+ SMESH_Hypothesis_i( thePOA )
+{
+ MESSAGE( "StdMeshers_LocalLength_i::StdMeshers_LocalLength_i" );
+ myBaseImpl = new ::StdMeshers_LocalLength( theGenImpl->GetANewId(),
+ theStudyId,
+ theGenImpl );
+}
+
+//=============================================================================
+/*!
+ * StdMeshers_LocalLength_i::~StdMeshers_LocalLength_i
+ *
+ * Destructor
+ */
+//=============================================================================
+
+StdMeshers_LocalLength_i::~StdMeshers_LocalLength_i()
+{
+ MESSAGE( "StdMeshers_LocalLength_i::~StdMeshers_LocalLength_i" );
+}
+
+//=============================================================================
+/*!
+ * StdMeshers_LocalLength_i::SetLength
+ *
+ * Set length
+ */
+//=============================================================================
+
+void StdMeshers_LocalLength_i::SetLength( CORBA::Double theLength )
+ throw ( SALOME::SALOME_Exception )
+{
+ MESSAGE( "StdMeshers_LocalLength_i::SetLength" );
+ ASSERT( myBaseImpl );
+ try {
+ this->GetImpl()->SetLength( theLength );
+ }
+ catch ( SALOME_Exception& S_ex ) {
+ THROW_SALOME_CORBA_EXCEPTION( S_ex.what(),
+ SALOME::BAD_PARAM );
+ }
+}
+
+//=============================================================================
+/*!
+ * StdMeshers_LocalLength_i::GetLength
+ *
+ * Get length
+ */
+//=============================================================================
+
+CORBA::Double StdMeshers_LocalLength_i::GetLength()
+{
+ MESSAGE( "StdMeshers_LocalLength_i::GetLength" );
+ ASSERT( myBaseImpl );
+ return this->GetImpl()->GetLength();
+}
+
+//=============================================================================
+/*!
+ * StdMeshers_LocalLength_i::GetImpl
+ *
+ * Get implementation
+ */
+//=============================================================================
+
+::StdMeshers_LocalLength* StdMeshers_LocalLength_i::GetImpl()
+{
+ MESSAGE( "StdMeshers_LocalLength_i::GetImpl" );
+ return ( ::StdMeshers_LocalLength* )myBaseImpl;
+}
--- /dev/null
+// SMESH SMESH_I : idl implementation based on 'SMESH' unit's calsses
+//
+// Copyright (C) 2003 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
+// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
+//
+// This library 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.
+//
+// This library 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 this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+//
+// See http://www.opencascade.org/SALOME/ or email : webmaster.salome@opencascade.org
+//
+//
+//
+// File : StdMeshers_LocalLength_i.hxx
+// Moved here from SMESH_LocalLength_i.hxx
+// Author : Paul RASCLE, EDF
+// Module : SMESH
+// $Header$
+
+#ifndef _SMESH_LOCALLENGTH_I_HXX_
+#define _SMESH_LOCALLENGTH_I_HXX_
+
+#include <SALOMEconfig.h>
+#include CORBA_SERVER_HEADER(SMESH_BasicHypothesis)
+
+#include "SMESH_Hypothesis_i.hxx"
+#include "StdMeshers_LocalLength.hxx"
+
+class SMESH_Gen;
+
+// ======================================================
+// Local Length hypothesis
+// ======================================================
+class StdMeshers_LocalLength_i:
+ public virtual POA_StdMeshers::StdMeshers_LocalLength,
+ public virtual SMESH_Hypothesis_i
+{
+public:
+ // Constructor
+ StdMeshers_LocalLength_i( PortableServer::POA_ptr thePOA,
+ int theStudyId,
+ ::SMESH_Gen* theGenImpl );
+ // Destructor
+ virtual ~StdMeshers_LocalLength_i();
+
+ // Set length
+ void SetLength( CORBA::Double theLength )
+ throw ( SALOME::SALOME_Exception );
+ // Get length
+ CORBA::Double GetLength();
+
+ // Get implementation
+ ::StdMeshers_LocalLength* GetImpl();
+};
+
+#endif
+
--- /dev/null
+// SMESH SMESH_I : idl implementation based on 'SMESH' unit's calsses
+//
+// Copyright (C) 2003 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
+// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
+//
+// This library 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.
+//
+// This library 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 this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+//
+// See http://www.opencascade.org/SALOME/ or email : webmaster.salome@opencascade.org
+//
+//
+//
+// File : StdMeshers_MEFISTO_2D_i.cxx
+// Moved here from SMESH_MEFISTO_2D_i.cxx
+// Author : Paul RASCLE, EDF
+// Module : SMESH
+// $Header$
+
+using namespace std;
+#include "StdMeshers_MEFISTO_2D_i.hxx"
+#include "SMESH_Gen.hxx"
+
+#include "Utils_CorbaException.hxx"
+#include "utilities.h"
+
+//=============================================================================
+/*!
+ * StdMeshers_MEFISTO_2D_i::StdMeshers_MEFISTO_2D_i
+ *
+ * Constructor
+ */
+//=============================================================================
+
+StdMeshers_MEFISTO_2D_i::StdMeshers_MEFISTO_2D_i( PortableServer::POA_ptr thePOA,
+ int theStudyId,
+ ::SMESH_Gen* theGenImpl )
+ : SALOME::GenericObj_i( thePOA ),
+ SMESH_Hypothesis_i( thePOA ),
+ SMESH_Algo_i( thePOA ),
+ SMESH_2D_Algo_i( thePOA )
+{
+ MESSAGE( "StdMeshers_MEFISTO_2D_i::StdMeshers_MEFISTO_2D_i" );
+ myBaseImpl = new ::StdMeshers_MEFISTO_2D( theGenImpl->GetANewId(),
+ theStudyId,
+ theGenImpl );
+}
+
+//=============================================================================
+/*!
+ * StdMeshers_MEFISTO_2D_i::~StdMeshers_MEFISTO_2D_i
+ *
+ * Destructor
+ */
+//=============================================================================
+
+StdMeshers_MEFISTO_2D_i::~StdMeshers_MEFISTO_2D_i()
+{
+ MESSAGE( "StdMeshers_MEFISTO_2D_i::~StdMeshers_MEFISTO_2D_i" );
+}
+
+//=============================================================================
+/*!
+ * StdMeshers_MEFISTO_2D_i::GetImpl
+ *
+ * Get implementation
+ */
+//=============================================================================
+
+::StdMeshers_MEFISTO_2D* StdMeshers_MEFISTO_2D_i::GetImpl()
+{
+ MESSAGE( "StdMeshers_MEFISTO_2D_i::GetImpl" );
+ return ( ::StdMeshers_MEFISTO_2D* )myBaseImpl;
+}
+
--- /dev/null
+// SMESH SMESH_I : idl implementation based on 'SMESH' unit's calsses
+//
+// Copyright (C) 2003 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
+// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
+//
+// This library 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.
+//
+// This library 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 this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+//
+// See http://www.opencascade.org/SALOME/ or email : webmaster.salome@opencascade.org
+//
+//
+//
+// File : StdMeshers_MEFISTO_2D_i.hxx
+// Moved here from SMESH_MEFISTO_2D_i.hxx
+// Author : Paul RASCLE, EDF
+// Module : SMESH
+// $Header$
+
+#ifndef _StdMeshers_MEFISTO_2D_I_HXX_
+#define _StdMeshers_MEFISTO_2D_I_HXX_
+
+#include <SALOMEconfig.h>
+#include CORBA_SERVER_HEADER(SMESH_BasicHypothesis)
+
+#include "SMESH_2D_Algo_i.hxx"
+#include "StdMeshers_MEFISTO_2D.hxx"
+
+class SMESH_Gen;
+
+// ======================================================
+// Triangle (MEFISTO) 2d algorithm
+// ======================================================
+class StdMeshers_MEFISTO_2D_i:
+ public virtual POA_StdMeshers::StdMeshers_MEFISTO_2D,
+ public virtual SMESH_2D_Algo_i
+{
+public:
+ // Constructor
+ StdMeshers_MEFISTO_2D_i( PortableServer::POA_ptr thePOA,
+ int theStudyId,
+ ::SMESH_Gen* theGenImpl );
+
+ // Destructor
+ virtual ~StdMeshers_MEFISTO_2D_i();
+
+ // Get implementation
+ ::StdMeshers_MEFISTO_2D* GetImpl();
+};
+
+#endif
--- /dev/null
+// SMESH SMESH_I : idl implementation based on 'SMESH' unit's calsses
+//
+// Copyright (C) 2003 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
+// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
+//
+// This library 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.
+//
+// This library 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 this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+//
+// See http://www.opencascade.org/SALOME/ or email : webmaster.salome@opencascade.org
+//
+//
+//
+// File : StdMeshers_MaxElementArea_i.cxx
+// Moved here from SMESH_MaxElementArea_i.cxx
+// Author : Paul RASCLE, EDF
+// Module : SMESH
+// $Header$
+
+using namespace std;
+#include "StdMeshers_MaxElementArea_i.hxx"
+#include "SMESH_Gen.hxx"
+
+#include "Utils_CorbaException.hxx"
+#include "utilities.h"
+
+//=============================================================================
+/*!
+ * StdMeshers_MaxElementArea_i::StdMeshers_MaxElementArea_i
+ *
+ * Constructor
+ */
+//=============================================================================
+
+StdMeshers_MaxElementArea_i::StdMeshers_MaxElementArea_i( PortableServer::POA_ptr thePOA,
+ int theStudyId,
+ ::SMESH_Gen* theGenImpl )
+ : SALOME::GenericObj_i( thePOA ),
+ SMESH_Hypothesis_i( thePOA )
+{
+ MESSAGE( "StdMeshers_MaxElementArea_i::StdMeshers_MaxElementArea_i" );
+ myBaseImpl = new ::StdMeshers_MaxElementArea( theGenImpl->GetANewId(),
+ theStudyId,
+ theGenImpl );
+}
+
+//=============================================================================
+/*!
+ * StdMeshers_MaxElementArea_i::~StdMeshers_MaxElementArea_i
+ *
+ * Destructor
+ */
+//=============================================================================
+
+StdMeshers_MaxElementArea_i::~StdMeshers_MaxElementArea_i()
+{
+ MESSAGE( "StdMeshers_MaxElementArea_i::~StdMeshers_MaxElementArea_i" );
+}
+
+//=============================================================================
+/*!
+ * StdMeshers_MaxElementArea_i::SetMaxElementArea
+ *
+ * Set maximum element area
+ */
+//=============================================================================
+
+void StdMeshers_MaxElementArea_i::SetMaxElementArea( CORBA::Double theArea )
+ throw ( SALOME::SALOME_Exception )
+{
+ MESSAGE( "StdMeshers_MaxElementArea_i::SetMaxElementArea" );
+ ASSERT( myBaseImpl );
+ try {
+ this->GetImpl()->SetMaxArea( theArea );
+ }
+ catch (SALOME_Exception& S_ex) {
+ THROW_SALOME_CORBA_EXCEPTION( S_ex.what(),
+ SALOME::BAD_PARAM );
+ }
+}
+
+//=============================================================================
+/*!
+ * StdMeshers_MaxElementArea_i::GetMaxElementArea
+ *
+ * Get maximum element area
+ */
+//=============================================================================
+
+CORBA::Double StdMeshers_MaxElementArea_i::GetMaxElementArea()
+{
+ MESSAGE( "StdMeshers_MaxElementArea_i::GetMaxElementArea" );
+ ASSERT( myBaseImpl );
+ return this->GetImpl()->GetMaxArea();
+}
+
+//=============================================================================
+/*!
+ * StdMeshers_MaxElementArea_i::GetImpl
+ *
+ * Get implementation
+ */
+//=============================================================================
+
+::StdMeshers_MaxElementArea* StdMeshers_MaxElementArea_i::GetImpl()
+{
+ MESSAGE( "StdMeshers_MaxElementArea_i::GetImpl" );
+ return ( ::StdMeshers_MaxElementArea* )myBaseImpl;
+}
--- /dev/null
+// SMESH SMESH_I : idl implementation based on 'SMESH' unit's calsses
+//
+// Copyright (C) 2003 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
+// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
+//
+// This library 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.
+//
+// This library 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 this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+//
+// See http://www.opencascade.org/SALOME/ or email : webmaster.salome@opencascade.org
+//
+//
+//
+// File : StdMeshers_MaxElementArea_i.hxx
+// Moved here from SMESH_MaxElementArea_i.hxx
+// Author : Paul RASCLE, EDF
+// Module : SMESH
+// $Header$
+
+#ifndef _SMESH_MAXELEMENTAREA_I_HXX_
+#define _SMESH_MAXELEMENTAREA_I_HXX_
+
+#include <SALOMEconfig.h>
+#include CORBA_SERVER_HEADER(SMESH_BasicHypothesis)
+
+#include "SMESH_Hypothesis_i.hxx"
+#include "StdMeshers_MaxElementArea.hxx"
+
+// ======================================================
+// Maximum Element Area hypothesis
+// ======================================================
+class StdMeshers_MaxElementArea_i:
+ public virtual POA_StdMeshers::StdMeshers_MaxElementArea,
+ public virtual SMESH_Hypothesis_i
+{
+public:
+ // Constructor
+ StdMeshers_MaxElementArea_i( PortableServer::POA_ptr thePOA,
+ int theStudyId,
+ ::SMESH_Gen* theGenImpl );
+ // Destructor
+ virtual ~StdMeshers_MaxElementArea_i();
+
+ // Set maximum element area
+ void SetMaxElementArea( CORBA::Double theArea )
+ throw ( SALOME::SALOME_Exception );
+ // Get maximum element area
+ CORBA::Double GetMaxElementArea();
+
+ // Get implementation
+ ::StdMeshers_MaxElementArea* GetImpl();
+};
+
+#endif
--- /dev/null
+// SMESH SMESH_I : idl implementation based on 'SMESH' unit's calsses
+//
+// Copyright (C) 2003 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
+// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
+//
+// This library 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.
+//
+// This library 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 this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+//
+// See http://www.opencascade.org/SALOME/ or email : webmaster.salome@opencascade.org
+//
+//
+//
+// File : StdMeshers_MaxElementVolume_i.cxx
+// Moved here from SMESH_MaxElementVolume_i.cxx
+// Author : Paul RASCLE, EDF
+// Module : SMESH
+// $Header$
+
+using namespace std;
+#include "StdMeshers_MaxElementVolume_i.hxx"
+#include "SMESH_Gen.hxx"
+
+#include "Utils_CorbaException.hxx"
+#include "utilities.h"
+
+//=============================================================================
+/*!
+ * StdMeshers_MaxElementVolume_i::StdMeshers_MaxElementVolume_i
+ *
+ * Constructor
+ */
+//=============================================================================
+
+StdMeshers_MaxElementVolume_i::StdMeshers_MaxElementVolume_i( PortableServer::POA_ptr thePOA,
+ int theStudyId,
+ ::SMESH_Gen* theGenImpl )
+ : SALOME::GenericObj_i( thePOA ),
+ SMESH_Hypothesis_i( thePOA )
+{
+ MESSAGE( "StdMeshers_MaxElementVolume_i::StdMeshers_MaxElementVolume_i" );
+ myBaseImpl = new ::StdMeshers_MaxElementVolume( theGenImpl->GetANewId(),
+ theStudyId,
+ theGenImpl );
+}
+
+//=============================================================================
+/*!
+ * StdMeshers_MaxElementVolume_i::~StdMeshers_MaxElementVolume_i
+ *
+ * Destructor
+ */
+//=============================================================================
+
+StdMeshers_MaxElementVolume_i::~StdMeshers_MaxElementVolume_i()
+{
+ MESSAGE( "StdMeshers_MaxElementVolume_i::~StdMeshers_MaxElementVolume_i()" );
+}
+
+//=============================================================================
+/*!
+ * StdMeshers_MaxElementVolume_i::SetMaxElementVolume
+ *
+ * Set maximum element volume
+ */
+//=============================================================================
+
+void StdMeshers_MaxElementVolume_i::SetMaxElementVolume( CORBA::Double theVolume )
+ throw ( SALOME::SALOME_Exception )
+{
+ MESSAGE( "StdMeshers_MaxElementVolume_i::SetMaxElementVolume" );
+ ASSERT( myBaseImpl );
+ try {
+ this->GetImpl()->SetMaxVolume( theVolume );
+ }
+ catch (SALOME_Exception& S_ex) {
+ THROW_SALOME_CORBA_EXCEPTION( S_ex.what(),
+ SALOME::BAD_PARAM );
+ }
+}
+
+//=============================================================================
+/*!
+ * StdMeshers_MaxElementVolume_i::GetMaxElementVolume
+ *
+ * Get maximum element volume
+ */
+//=============================================================================
+
+CORBA::Double StdMeshers_MaxElementVolume_i::GetMaxElementVolume()
+{
+ MESSAGE( "StdMeshers_MaxElementVolume_i::GetMaxElementVolume" );
+ ASSERT( myBaseImpl );
+ return this->GetImpl()->GetMaxVolume();
+}
+
+//=============================================================================
+/*!
+ * StdMeshers_MaxElementVolume_i::GetImpl
+ *
+ * Get implementation
+ */
+//=============================================================================
+
+::StdMeshers_MaxElementVolume* StdMeshers_MaxElementVolume_i::GetImpl()
+{
+ MESSAGE( "StdMeshers_MaxElementVolume_i::GetImpl" );
+ return ( ::StdMeshers_MaxElementVolume* )myBaseImpl;
+}
+
--- /dev/null
+// SMESH SMESH_I : idl implementation based on 'SMESH' unit's calsses
+//
+// Copyright (C) 2003 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
+// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
+//
+// This library 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.
+//
+// This library 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 this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+//
+// See http://www.opencascade.org/SALOME/ or email : webmaster.salome@opencascade.org
+//
+//
+//
+// File : StdMeshers_MaxElementVolume_i.hxx
+// Moved here from SMESH_MaxElementVolume_i.hxx
+// Author : Paul RASCLE, EDF
+// Module : SMESH
+// $Header$
+
+#ifndef _SMESH_MAXELEMENTVOLUME_I_HXX_
+#define _SMESH_MAXELEMENTVOLUME_I_HXX_
+
+#include <SALOMEconfig.h>
+#include CORBA_SERVER_HEADER(SMESH_BasicHypothesis)
+
+#include "SMESH_Hypothesis_i.hxx"
+#include "StdMeshers_MaxElementVolume.hxx"
+
+// ======================================================
+// Maximum Element Volume hypothesis
+// ======================================================
+class StdMeshers_MaxElementVolume_i:
+ public virtual POA_StdMeshers::StdMeshers_MaxElementVolume,
+ public virtual SMESH_Hypothesis_i
+{
+public:
+ // Constructor
+ StdMeshers_MaxElementVolume_i( PortableServer::POA_ptr thePOA,
+ int theStudyId,
+ ::SMESH_Gen* theGenImpl );
+ // Destructor
+ virtual ~StdMeshers_MaxElementVolume_i();
+
+ // Set maximum element volume
+ void SetMaxElementVolume( CORBA::Double theVolume )
+ throw (SALOME::SALOME_Exception);
+ // Get maximum element volume
+ CORBA::Double GetMaxElementVolume();
+
+ // Get implementation
+ ::StdMeshers_MaxElementVolume* GetImpl();
+};
+
+#endif
--- /dev/null
+// SMESH StdMeshers_I : idl implementation based on 'SMESH' unit's classes
+//
+// Copyright (C) 2003 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
+// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
+//
+// This library 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.
+//
+// This library 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 this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+//
+// See http://www.opencascade.org/SALOME/ or email : webmaster.salome@opencascade.org
+//
+//
+//
+// File : StdMeshers_NotConformAllowed_i.cxx
+// Author : Paul RASCLE, EDF
+// Module : SMESH
+// $Header$
+
+using namespace std;
+using namespace std;
+#include "StdMeshers_NotConformAllowed_i.hxx"
+#include "SMESH_Gen.hxx"
+
+#include "utilities.h"
+
+//=============================================================================
+/*!
+ * Constructor:
+ * _name is related to the class name: prefix = SMESH_ ; suffix = _i .
+ */
+//=============================================================================
+
+StdMeshers_NotConformAllowed_i::StdMeshers_NotConformAllowed_i
+ (PortableServer::POA_ptr thePOA,
+ int studyId,
+ ::SMESH_Gen* genImpl)
+ : SALOME::GenericObj_i( thePOA ),
+ SMESH_Hypothesis_i( thePOA )
+{
+ MESSAGE("StdMeshers_NotConformAllowed_i::StdMeshers_NotConformAllowed_i");
+ myBaseImpl = new ::StdMeshers_NotConformAllowed(genImpl->GetANewId(),
+ studyId,
+ genImpl);
+}
+
+//=============================================================================
+/*!
+ *
+ */
+//=============================================================================
+
+StdMeshers_NotConformAllowed_i::~StdMeshers_NotConformAllowed_i()
+{
+}
--- /dev/null
+// SMESH StdMeshers_I : idl implementation based on 'SMESH' unit's classes
+//
+// Copyright (C) 2003 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
+// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
+//
+// This library 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.
+//
+// This library 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 this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+//
+// See http://www.opencascade.org/SALOME/ or email : webmaster.salome@opencascade.org
+//
+//
+//
+// File : StdMeshers_NotConformAllowed_i.hxx
+// Author : Paul RASCLE, EDF
+// Module : SMESH
+// $Header$
+
+#ifndef _StdMeshers_NotConformAllowed_I_HXX_
+#define _StdMeshers_NotConformAllowed_I_HXX_
+
+#include <SALOMEconfig.h>
+#include CORBA_SERVER_HEADER(SMESH_BasicHypothesis)
+
+#include "SMESH_Hypothesis_i.hxx"
+
+#include "StdMeshers_NotConformAllowed.hxx"
+
+class StdMeshers_NotConformAllowed_i:
+ public POA_StdMeshers::StdMeshers_NotConformAllowed,
+ public SMESH_Hypothesis_i
+{
+public:
+ StdMeshers_NotConformAllowed_i(PortableServer::POA_ptr thePOA,
+ int studyId,
+ ::SMESH_Gen* genImpl);
+ virtual ~StdMeshers_NotConformAllowed_i();
+
+protected:
+ ::StdMeshers_NotConformAllowed* _impl;
+};
+
+#endif
+
--- /dev/null
+// SMESH SMESH_I : idl implementation based on 'SMESH' unit's calsses
+//
+// Copyright (C) 2003 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
+// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
+//
+// This library 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.
+//
+// This library 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 this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+//
+// See http://www.opencascade.org/SALOME/ or email : webmaster.salome@opencascade.org
+//
+//
+//
+// File : StdMeshers_NumberOfSegments_i.cxx
+// Moved here from SMESH_NumberOfSegments_i.cxx
+// Author : Paul RASCLE, EDF
+// Module : SMESH
+// $Header$
+
+using namespace std;
+#include "StdMeshers_NumberOfSegments_i.hxx"
+#include "SMESH_Gen.hxx"
+
+#include "Utils_CorbaException.hxx"
+#include "utilities.h"
+
+//=============================================================================
+/*!
+ * StdMeshers_NumberOfSegments_i::StdMeshers_NumberOfSegments_i
+ *
+ * Constructor
+ */
+//=============================================================================
+
+StdMeshers_NumberOfSegments_i::StdMeshers_NumberOfSegments_i( PortableServer::POA_ptr thePOA,
+ int theStudyId,
+ ::SMESH_Gen* theGenImpl )
+ : SALOME::GenericObj_i( thePOA ),
+ SMESH_Hypothesis_i( thePOA )
+{
+ MESSAGE( "StdMeshers_NumberOfSegments_i::StdMeshers_NumberOfSegments_i" );
+ myBaseImpl = new ::StdMeshers_NumberOfSegments( theGenImpl->GetANewId(),
+ theStudyId,
+ theGenImpl );
+}
+
+//=============================================================================
+/*!
+ * StdMeshers_NumberOfSegments_i::~StdMeshers_NumberOfSegments_i
+ *
+ * Destructor
+ */
+//=============================================================================
+
+StdMeshers_NumberOfSegments_i::~StdMeshers_NumberOfSegments_i()
+{
+ MESSAGE( "StdMeshers_NumberOfSegments_i::~StdMeshers_NumberOfSegments_i" );
+}
+
+//=============================================================================
+/*!
+ * StdMeshers_NumberOfSegments_i::SetNumberOfSegments
+ *
+ * Set number of segments
+ */
+//=============================================================================
+
+void StdMeshers_NumberOfSegments_i::SetNumberOfSegments( CORBA::Long theSegmentsNumber )
+ throw ( SALOME::SALOME_Exception )
+{
+ MESSAGE( "StdMeshers_NumberOfSegments_i::SetNumberOfSegments" );
+ ASSERT( myBaseImpl );
+ try {
+ this->GetImpl()->SetNumberOfSegments( theSegmentsNumber );
+ }
+ catch (SALOME_Exception& S_ex) {
+ THROW_SALOME_CORBA_EXCEPTION( S_ex.what(),
+ SALOME::BAD_PARAM );
+ }
+}
+
+//=============================================================================
+/*!
+ * StdMeshers_NumberOfSegments_i::GetNumberOfSegments
+ *
+ * Get number of segments
+ */
+//=============================================================================
+
+CORBA::Long StdMeshers_NumberOfSegments_i::GetNumberOfSegments()
+{
+ MESSAGE( "StdMeshers_NumberOfSegments_i::GetNumberOfSegments" );
+ ASSERT( myBaseImpl );
+ return this->GetImpl()->GetNumberOfSegments();
+}
+
+//=============================================================================
+/*!
+ * StdMeshers_NumberOfSegments_i::SetScaleFactor
+ *
+ * Set scalar factor
+ */
+//=============================================================================
+
+void StdMeshers_NumberOfSegments_i::SetScaleFactor( CORBA::Double theScaleFactor )
+ throw ( SALOME::SALOME_Exception )
+{
+ MESSAGE( "StdMeshers_NumberOfSegments_i::SetScaleFactor" );
+ ASSERT( myBaseImpl );
+ try {
+ this->GetImpl()->SetScaleFactor( theScaleFactor );
+ }
+ catch ( SALOME_Exception& S_ex ) {
+ THROW_SALOME_CORBA_EXCEPTION( S_ex.what(),
+ SALOME::BAD_PARAM );
+ }
+}
+
+//=============================================================================
+/*!
+ * StdMeshers_NumberOfSegments_i::GetScaleFactor
+ *
+ * Get scalar factor
+ */
+//=============================================================================
+
+CORBA::Double StdMeshers_NumberOfSegments_i::GetScaleFactor()
+{
+ MESSAGE( "StdMeshers_NumberOfSegments_i::GetScaleFactor" );
+ ASSERT( myBaseImpl );
+ return this->GetImpl()->GetScaleFactor();
+}
+
+//=============================================================================
+/*!
+ * StdMeshers_NumberOfSegments_i::GetImpl
+ *
+ * Get implementation
+ */
+//=============================================================================
+
+::StdMeshers_NumberOfSegments* StdMeshers_NumberOfSegments_i::GetImpl()
+{
+ MESSAGE( "StdMeshers_NumberOfSegments_i::GetImpl" );
+ return ( ::StdMeshers_NumberOfSegments* )myBaseImpl;
+}
+
--- /dev/null
+// SMESH SMESH_I : idl implementation based on 'SMESH' unit's calsses
+//
+// Copyright (C) 2003 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
+// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
+//
+// This library 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.
+//
+// This library 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 this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+//
+// See http://www.opencascade.org/SALOME/ or email : webmaster.salome@opencascade.org
+//
+//
+//
+// File : StdMeshers_NumberOfSegments_i.hxx
+// Moved here from SMESH_NumberOfSegments_i.hxx
+// Author : Paul RASCLE, EDF
+// Module : SMESH
+// $Header$
+
+#ifndef _SMESH_NUMBEROFSEGMENTS_I_HXX_
+#define _SMESH_NUMBEROFSEGMENTS_I_HXX_
+
+#include <SALOMEconfig.h>
+#include CORBA_SERVER_HEADER(SMESH_BasicHypothesis)
+
+#include "SMESH_Hypothesis_i.hxx"
+#include "StdMeshers_NumberOfSegments.hxx"
+
+// ======================================================
+// Number of segments hypothesis
+// ======================================================
+class StdMeshers_NumberOfSegments_i:
+ public virtual POA_StdMeshers::StdMeshers_NumberOfSegments,
+ public virtual SMESH_Hypothesis_i
+{
+public:
+ // Constructor
+ StdMeshers_NumberOfSegments_i( PortableServer::POA_ptr thePOA,
+ int theStudyId,
+ ::SMESH_Gen* theGenImpl );
+ // Destructor
+ virtual ~StdMeshers_NumberOfSegments_i();
+
+ // Set number of segments
+ void SetNumberOfSegments( CORBA::Long theSegmentsNumber )
+ throw ( SALOME::SALOME_Exception );
+ // Get number of segments
+ CORBA::Long GetNumberOfSegments();
+
+ // Set scalar factor
+ void SetScaleFactor( CORBA::Double theScaleFactor )
+ throw ( SALOME::SALOME_Exception );
+ // Get scalar factor
+ CORBA::Double GetScaleFactor();
+
+ // Get implementation
+ ::StdMeshers_NumberOfSegments* GetImpl();
+};
+
+#endif
--- /dev/null
+// SMESH SMESH_I : idl implementation based on 'SMESH' unit's calsses
+//
+// Copyright (C) 2003 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
+// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
+//
+// This library 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.
+//
+// This library 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 this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+//
+// See http://www.opencascade.org/SALOME/ or email : webmaster.salome@opencascade.org
+//
+//
+//
+// File : StdMeshers_Quadrangle_2D_i.cxx
+// Moved here from SMESH_Quadrangle_2D_i.cxx
+// Author : Paul RASCLE, EDF
+// Module : SMESH
+// $Header$
+
+using namespace std;
+#include "StdMeshers_Quadrangle_2D_i.hxx"
+#include "SMESH_Gen.hxx"
+
+#include "Utils_CorbaException.hxx"
+#include "utilities.h"
+
+//=============================================================================
+/*!
+ * StdMeshers_Quadrangle_2D_i::StdMeshers_Quadrangle_2D_i
+ *
+ * Constructor
+ */
+//=============================================================================
+
+StdMeshers_Quadrangle_2D_i::StdMeshers_Quadrangle_2D_i( PortableServer::POA_ptr thePOA,
+ int theStudyId,
+ ::SMESH_Gen* theGenImpl )
+ : SALOME::GenericObj_i( thePOA ),
+ SMESH_Hypothesis_i( thePOA ),
+ SMESH_Algo_i( thePOA ),
+ SMESH_2D_Algo_i( thePOA )
+{
+ MESSAGE( "StdMeshers_Quadrangle_2D_i::StdMeshers_Quadrangle_2D_i" );
+ myBaseImpl = new ::StdMeshers_Quadrangle_2D( theGenImpl->GetANewId(),
+ theStudyId,
+ theGenImpl );
+}
+
+//=============================================================================
+/*!
+ * StdMeshers_Quadrangle_2D_i::~StdMeshers_Quadrangle_2D_i
+ *
+ * Destructor
+ *
+ */
+//=============================================================================
+
+StdMeshers_Quadrangle_2D_i::~StdMeshers_Quadrangle_2D_i()
+{
+ MESSAGE( "StdMeshers_Quadrangle_2D_i::~StdMeshers_Quadrangle_2D_i" );
+}
+
+//=============================================================================
+/*!
+ * StdMeshers_Quadrangle_2D_i::GetImpl
+ *
+ * Get implementation
+ */
+//=============================================================================
+
+::StdMeshers_Quadrangle_2D* StdMeshers_Quadrangle_2D_i::GetImpl()
+{
+ MESSAGE( "StdMeshers_Quadrangle_2D_i::GetImpl" );
+ return ( ::StdMeshers_Quadrangle_2D* )myBaseImpl;
+}
+
--- /dev/null
+// SMESH SMESH_I : idl implementation based on 'SMESH' unit's calsses
+//
+// Copyright (C) 2003 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
+// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
+//
+// This library 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.
+//
+// This library 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 this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+//
+// See http://www.opencascade.org/SALOME/ or email : webmaster.salome@opencascade.org
+//
+//
+//
+// File : StdMeshers_Quadrangle_2D_i.hxx
+// Moved here from SMESH_Quadrangle_2D_i.hxx
+// Author : Paul RASCLE, EDF
+// Module : SMESH
+// $Header$
+
+#ifndef _SMESH_QUADRANGLE_2D_I_HXX_
+#define _SMESH_QUADRANGLE_2D_I_HXX_
+
+#include <SALOMEconfig.h>
+#include CORBA_SERVER_HEADER(SMESH_BasicHypothesis)
+
+#include "SMESH_2D_Algo_i.hxx"
+#include "StdMeshers_Quadrangle_2D.hxx"
+
+class SMESH_Gen;
+
+// ======================================================
+// Quadrangle (Mapping) 2d algorithm
+// ======================================================
+class StdMeshers_Quadrangle_2D_i:
+ public virtual POA_StdMeshers::StdMeshers_Quadrangle_2D,
+ public virtual SMESH_2D_Algo_i
+{
+public:
+ // Constructor
+ StdMeshers_Quadrangle_2D_i( PortableServer::POA_ptr thePOA,
+ int theStudyId,
+ ::SMESH_Gen* theGenImpl );
+
+ // Destructor
+ virtual ~StdMeshers_Quadrangle_2D_i();
+
+ // Get implementation
+ ::StdMeshers_Quadrangle_2D* GetImpl();
+};
+
+#endif
--- /dev/null
+// SMESH SMESH_I : idl implementation based on 'SMESH' unit's calsses
+//
+// Copyright (C) 2003 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
+// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
+//
+// This library 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.
+//
+// This library 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 this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+//
+// See http://www.opencascade.org/SALOME/ or email : webmaster.salome@opencascade.org
+//
+//
+//
+// File : StdMeshers_Regular_1D_i.cxx
+// Moved here from SMESH_Regular_1D_i.cxx
+// Author : Paul RASCLE, EDF
+// Module : SMESH
+// $Header$
+
+using namespace std;
+#include "StdMeshers_Regular_1D_i.hxx"
+#include "SMESH_Gen.hxx"
+
+#include "Utils_CorbaException.hxx"
+#include "utilities.h"
+
+//=============================================================================
+/*!
+ * StdMeshers_Regular_1D_i::StdMeshers_Regular_1D_i
+ *
+ * Constructor
+ */
+//=============================================================================
+
+StdMeshers_Regular_1D_i::StdMeshers_Regular_1D_i( PortableServer::POA_ptr thePOA,
+ int theStudyId,
+ ::SMESH_Gen* theGenImpl )
+ : SALOME::GenericObj_i( thePOA ),
+ SMESH_Hypothesis_i( thePOA ),
+ SMESH_Algo_i( thePOA ),
+ SMESH_1D_Algo_i( thePOA )
+{
+ MESSAGE( "StdMeshers_Regular_1D_i::StdMeshers_Regular_1D_i" );
+ myBaseImpl = new ::StdMeshers_Regular_1D( theGenImpl->GetANewId(),
+ theStudyId,
+ theGenImpl );
+}
+
+//=============================================================================
+/*!
+ * StdMeshers_Regular_1D_i::~StdMeshers_Regular_1D_i
+ *
+ * Destructor
+ */
+//=============================================================================
+
+StdMeshers_Regular_1D_i::~StdMeshers_Regular_1D_i()
+{
+ MESSAGE( "StdMeshers_Regular_1D_i::~StdMeshers_Regular_1D_i" );
+}
+
+//=============================================================================
+/*!
+ * StdMeshers_Regular_1D_i::GetImpl
+ *
+ * Get implementation
+ */
+//=============================================================================
+
+::StdMeshers_Regular_1D* StdMeshers_Regular_1D_i::GetImpl()
+{
+ MESSAGE( "StdMeshers_Regular_1D_i::GetImpl" );
+ return ( ::StdMeshers_Regular_1D* )myBaseImpl;
+}
+
--- /dev/null
+// SMESH SMESH_I : idl implementation based on 'SMESH' unit's calsses
+//
+// Copyright (C) 2003 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
+// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
+//
+// This library 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.
+//
+// This library 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 this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+//
+// See http://www.opencascade.org/SALOME/ or email : webmaster.salome@opencascade.org
+//
+//
+//
+// File : StdMeshers_Regular_1D_i.hxx
+// Moved here from SMESH_Regular_1D_i.hxx
+// Author : Paul RASCLE, EDF
+// Module : SMESH
+// $Header$
+
+#ifndef _SMESH_REGULAR_1D_I_HXX_
+#define _SMESH_REGULAR_1D_I_HXX_
+
+#include <SALOMEconfig.h>
+#include CORBA_SERVER_HEADER(SMESH_BasicHypothesis)
+
+#include "SMESH_1D_Algo_i.hxx"
+#include "StdMeshers_Regular_1D.hxx"
+
+// ======================================================
+// Wire Discretization 1d algorithm
+// ======================================================
+class StdMeshers_Regular_1D_i:
+ public virtual POA_StdMeshers::StdMeshers_Regular_1D,
+ public virtual SMESH_1D_Algo_i
+{
+public:
+ // Constructor
+ StdMeshers_Regular_1D_i( PortableServer::POA_ptr thePOA,
+ int theStudyId,
+ ::SMESH_Gen* theGenImpl );
+ // Destructor
+ virtual ~StdMeshers_Regular_1D_i();
+
+ // Get implementation
+ ::StdMeshers_Regular_1D* GetImpl();
+};
+
+#endif
--- /dev/null
+// SMESH StdMeshers : implementaion of SMESH idl descriptions
+//
+// Copyright (C) 2003 CEA
+//
+// This library 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.
+//
+// This library 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 this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+//
+// See http://www.salome-platform.org or email : webmaster.salome@opencascade.org
+//
+//
+//
+// File : StdMeshers_i.cxx
+// Author : Julia DOROVSKIKH
+// Module : SMESH
+// $Header$
+
+using namespace std;
+#include "SMESH_Gen_i.hxx"
+
+#include "utilities.h"
+
+#include "StdMeshers_LocalLength_i.hxx"
+#include "StdMeshers_LengthFromEdges_i.hxx"
+#include "StdMeshers_NotConformAllowed_i.hxx"
+#include "StdMeshers_NumberOfSegments_i.hxx"
+#include "StdMeshers_MaxElementArea_i.hxx"
+#include "StdMeshers_MaxElementVolume_i.hxx"
+
+#include "StdMeshers_Regular_1D_i.hxx"
+#include "StdMeshers_MEFISTO_2D_i.hxx"
+#include "StdMeshers_Quadrangle_2D_i.hxx"
+#include "StdMeshers_Hexa_3D_i.hxx"
+
+//=============================================================================
+/*!
+ *
+ */
+//=============================================================================
+
+extern "C"
+{
+ GenericHypothesisCreator_i* GetHypothesisCreator (const char* aHypName)
+ {
+ MESSAGE("Get HypothesisCreator for " << aHypName);
+
+ GenericHypothesisCreator_i* aCreator = 0;
+
+ // Hypotheses
+ if (strcmp(aHypName, "LocalLength") == 0)
+ aCreator = new HypothesisCreator_i<StdMeshers_LocalLength_i>;
+ else if (strcmp(aHypName, "NumberOfSegments") == 0)
+ aCreator = new HypothesisCreator_i<StdMeshers_NumberOfSegments_i>;
+ else if (strcmp(aHypName, "LengthFromEdges") == 0)
+ aCreator = new HypothesisCreator_i<StdMeshers_LengthFromEdges_i>;
+ else if (strcmp(aHypName, "NotConformAllowed") == 0)
+ aCreator = new HypothesisCreator_i<StdMeshers_NotConformAllowed_i>;
+ else if (strcmp(aHypName, "MaxElementArea") == 0)
+ aCreator = new HypothesisCreator_i<StdMeshers_MaxElementArea_i>;
+ else if (strcmp(aHypName, "MaxElementVolume") == 0)
+ aCreator = new HypothesisCreator_i<StdMeshers_MaxElementVolume_i>;
+
+ // Algorithms
+ else if (strcmp(aHypName, "Regular_1D") == 0)
+ aCreator = new HypothesisCreator_i<StdMeshers_Regular_1D_i>;
+ else if (strcmp(aHypName, "MEFISTO_2D") == 0)
+ aCreator = new HypothesisCreator_i<StdMeshers_MEFISTO_2D_i>;
+ else if (strcmp(aHypName, "Quadrangle_2D") == 0)
+ aCreator = new HypothesisCreator_i<StdMeshers_Quadrangle_2D_i>;
+ else if (strcmp(aHypName, "Hexa_3D") == 0)
+ aCreator = new HypothesisCreator_i<StdMeshers_Hexa_3D_i>;
+ else ;
+
+ return aCreator;
+ }
+}