ifrit-3.4.2/0000755000175700010010000000000012167404501011202 5ustar HomeNoneifrit-3.4.2/build/0000755000175700010010000000000012167404403012302 5ustar HomeNoneifrit-3.4.2/build/CMakeLists.txt0000755000175700010010000002203612167404403015050 0ustar HomeNone# # Copyright (c) 2002-2007 Nick Gnedin # All rights reserved. # # This file may be distributed and/or modified under the terms of the # GNU General Public License version 2 as published by the Free Software # Foundation and appearing in the file LICENSE.GPL included in the # packaging of this file. # CMAKE_MINIMUM_REQUIRED(VERSION 2.0) IF(COMMAND cmake_policy) cmake_policy(SET CMP0003 NEW) ENDIF(COMMAND cmake_policy) SET(src ..) SET(target ifrit) PROJECT(${target}) SET(Option:OffScreen 0 CACHE BOOL "Compile IFrIT for off-screen rendering (needs VTK with Mesa libraries)") SET(Option:StereoSupport 1 CACHE BOOL "Enable OpenGL support for displaying stereo (disable this option if you see flicker)") # # Portability options # SET(Port:SearchOGL 0 CACHE BOOL "Search for OpenGL (normally should be found automatically)") SET(Port:SearchX11 0 CACHE BOOL "Search for X11 (normally should be found automatically)") SET(Port:NoLongLong 0 CACHE BOOL "Do not use long long type") MARK_AS_ADVANCED(Port:SearchOGL Port:SearchX11 Port:NoLongLong) IF(NOT CMAKE_BUILD_TYPE) SET(CMAKE_BUILD_TYPE Release CACHE STRING "Choose the type of build, options are: None(CMAKE_CXX_FLAGS or CMAKE_C_FLAGS used) Debug Release RelWithDebInfo MinSizeRel." FORCE) ENDIF(NOT CMAKE_BUILD_TYPE) # # --------------------------------------------------------------------------- # # Configuration # # --------------------------------------------------------------------------- # # Shells # IF(WIN32) OPTION(Shell:CL "Include command-line shell" OFF) ELSE(WIN32) OPTION(Shell:CL "Include command-line shell" ON) ENDIF(WIN32) OPTION(Shell:QT "Include Qt-based GUI shell" ON) SET(nsh) SET(gsh) IF(Shell:CL) SET(nsh ${nsh} cl) ENDIF(Shell:CL) IF(Shell:QT) SET(gsh ${gsh} qt) ENDIF(Shell:QT) IF(NOT nsh AND NOT gsh) MESSAGE(FATAL_ERROR "At least one shell must be selected.") ENDIF(NOT nsh AND NOT gsh) # # Find max extension flag # SET(maxNum 1) FILE(READ ${src}/configure/iextensiondefines.h f) STRING(REGEX MATCHALL "#define IEXTENSION_[A-Z0-9_]*[ \t]*[0-9]*" m ${f}) IF(m) STRING(REGEX REPLACE "#define IEXTENSION_[A-Z0-9_]*[ \t]*([0-9]*)" "\\1;" num ${m}) SET(num ${num}0) FOREACH(n ${num}) IF(n GREATER ${maxNum}) SET(maxNum ${n}) ENDIF(n GREATER ${maxNum}) ENDFOREACH(n ${num}) ENDIF(m) # # Configure extensions # SET(ext) FILE(GLOB dir ${src}/configure/.CMake.*.def) IF(dir) FOREACH(s ${dir}) STRING(REGEX REPLACE ".*\\.CMake\\.([A-Z0-9_]*)\\.def" "\\1" e ${s}) IF(e STREQUAL MV) OPTION(Extension:MultiView "Include MultiView extension" OFF) IF(Extension:MultiView) set(ext ${ext} ${e}) ENDIF(Extension:MultiView) ELSE(e STREQUAL MV) OPTION(Extension:${e} "Include ${e} extension" ON) IF(Extension:${e}) set(ext ${ext} ${e}) ENDIF(Extension:${e}) # # Check that the define for this extension has been set already. # STRING(REGEX MATCH "#define IEXTENSION_${e}[ \t]*[0-9]*" m ${f}) IF(NOT m) MESSAGE("Extension ${e} has not been defined in configure/iextensiondefines.h.\n I will define it for you.") SET(maxNum 2*${maxNum}) FILE(APPEND ${src}/configure/iextensiondefines.h "#define IEXTENSION_${e} ${maxNum}\n") ENDIF(NOT m) ENDIF(e STREQUAL MV) ENDFOREACH(s ${dir}) ENDIF(dir) # # --------------------------------------------------------------------------- # # Find dependencies # # --------------------------------------------------------------------------- # SET(EXECUTABLE_OUTPUT_PATH ..) MARK_AS_ADVANCED(CMAKE_BACKWARDS_COMPATIBILITY CMAKE_INSTALL_PREFIX LIBRARY_OUTPUT_PATH QT_QMAKE_EXECUTABLE) # Find curses IF(Shell:CL) INCLUDE(${CMAKE_ROOT}/Modules/FindCurses.cmake) IF(UNIX AND CURSES_LIBRARY) ADD_DEFINITIONS(-DI_USE_CURSES) ENDIF(UNIX AND CURSES_LIBRARY) ENDIF(Shell:CL) # Find VTK SET(VTK_DIR $ENV{VTKDIR}) INCLUDE(${CMAKE_ROOT}/Modules/FindVTK.cmake) IF(NOT VTK_FOUND) MESSAGE(FATAL_ERROR "VTK is not found. Please check that VTKDIR variables is set properly.") ENDIF(NOT VTK_FOUND) INCLUDE(${VTK_USE_FILE}) IF(VTK_USE_VOLUMEPRO AND VTK_HAVE_VP1000) OPTION(CustomVP1000 "Include custom support for VP1000" ON) ENDIF(VTK_USE_VOLUMEPRO AND VTK_HAVE_VP1000) # Find OpenGL IF(Port:SearchOGL) INCLUDE(${CMAKE_ROOT}/Modules/FindOpenGL.cmake) IF(NOT OPENGL_FOUND) MESSAGE(FATAL_ERROR "OpenGL is not found. Please set advanced variables OPENGL_INCLUDE_DIR and OPENGL_LIBRARIES.") ENDIF(NOT OPENGL_FOUND) INCLUDE_DIRECTORIES(${OPENGL_INCLUDE_DIR}) ENDIF(Port:SearchOGL) # Find X11 IF(UNIX AND Port:SearchX11) INCLUDE(${CMAKE_ROOT}/Modules/FindX11.cmake) IF(NOT X11_FOUND) MESSAGE(FATAL_ERROR "X11 is not found. Please set advanced variables X11_X11_INCLUDE_PATH and X11_LIBRARIES.") ENDIF(NOT X11_FOUND) INCLUDE_DIRECTORIES(${X11_X11_INCLUDE_PATH}) ENDIF(UNIX AND Port:SearchX11) IF(Shell:QT) # Find Qt SET(QT_REQUIRED 1) INCLUDE(${CMAKE_ROOT}/Modules/FindQt.cmake) INCLUDE_DIRECTORIES(${QT_INCLUDE_DIR}) IF(QT4_INSTALLED) INCLUDE_DIRECTORIES(${QT_INCLUDE_DIR}/Qt ${QT_QTCORE_INCLUDE_DIR}) ENDIF(QT4_INSTALLED) ADD_DEFINITIONS(${QT_DEFINITIONS}) ENDIF(Shell:QT) # # --------------------------------------------------------------------------- # # Create the project # # --------------------------------------------------------------------------- # SET(shell 0) SET(exten 0) # # Core # FILE(GLOB sources ${src}/configure/*.cpp ${src}/core/*.cpp ${src}/help/*.cpp) INCLUDE_DIRECTORIES(${src}/configure ${src}/core ${src}/help ${src}/docs) # # Shells # IF(gsh) FILE(GLOB tmp ${src}/shells/configure/*.cpp ${src}/shells/generic/*.cpp ${src}/shells/base/*.cpp) IF(tmp) SET(sources ${sources} ${tmp}) INCLUDE_DIRECTORIES(${src}/shells/configure ${src}/shells/generic ${src}/shells/base) ENDIF(tmp) ENDIF(gsh) FOREACH(s ${nsh} ${gsh}) FILE(GLOB tmp ${src}/shells/${s}/*.cpp) IF(tmp) SET(sources ${sources} ${tmp}) INCLUDE_DIRECTORIES(${src}/shells/${s}) STRING(TOUPPER ${s} us) SET(shell ${shell}+ISHELL_${us}) ENDIF(tmp) ENDFOREACH(s) # # Extensions # FOREACH(e ${ext}) SET(exten ${exten}+IEXTENSION_${e}) ENDFOREACH(e) # # Special # IF(Shell:QT) SET(qtdir ${src}/shells/qt) SET(qthdr ${qtdir}/iqtwidgettexteditorsubject.h ${qtdir}/iqtwidgethelper.h ${qtdir}/iqtrenderwindowsubject.h ${qtdir}/iqtmenuwindowsubject.h ${qtdir}/iqtmainwindowsubject.h ${qtdir}/iqtframesubject.h) SET(tmp) QT_WRAP_CPP(dummy tmp ${qthdr}) SET(sources ${sources} ${tmp}) ENDIF(Shell:QT) IF(CustomVP1000) FILE(GLOB tmp ${src}/special/vp1000/*.cpp) IF(tmp) SET(sources ${sources} ${tmp}) INCLUDE_DIRECTORIES(${src}/special/vp1000) ADD_DEFINITIONS(-DI_CUSTOM_VP1000) ENDIF(tmp) ENDIF(CustomVP1000) IF(Extension:ART) FILE(GLOB tmp ${src}/special/artio/*.c) IF(tmp) SET(sources ${sources} ${tmp}) INCLUDE_DIRECTORIES(${src}/special/artio) ENDIF(tmp) ENDIF(Extension:ART) # # Create target # IF(nsh) ADD_EXECUTABLE(${target} ${sources}) ELSE(nsh) ADD_EXECUTABLE(${target} WIN32 ${sources}) ENDIF(nsh) ADD_DEFINITIONS(-DI_EXTERNAL_CONFIGURATION -DI_CHECK1) IF(CMAKE_BUILD_TYPE MATCHES "Debug") ADD_DEFINITIONS(-DI_DEBUG -DI_CHECK2) ENDIF(CMAKE_BUILD_TYPE MATCHES "Debug") IF(Option:OffScreen) ADD_DEFINITIONS(-DI_OFFSCREEN) ENDIF(Option:OffScreen) # # Edition # FILE(GLOB tmp ${src}/configure/edition*.cpp) IF(tmp) ADD_DEFINITIONS(-DI_EDITION) ENDIF(tmp) FILE(GLOB tmp ${src}/configure/iconfiguresettings.ext) CONFIGURE_FILE(${tmp} ${tmp}.h @ONLY) IF(NOT Option:StereoSupport) ADD_DEFINITIONS(-DI_NO_STEREO) ENDIF(NOT Option:StereoSupport) # # Portability # IF(Port:NoLongLong) ADD_DEFINITIONS(-DI_NO_LONG_LONG) ENDIF(Port:NoLongLong) # # Add libraries # TARGET_LINK_LIBRARIES(${target} vtkFiltering vtkHybrid vtkRendering) # # Optional libraries # IF(VTK_KITS MATCHES "PARALLEL") TARGET_LINK_LIBRARIES(${target} vtkParallel) ENDIF(VTK_KITS MATCHES "PARALLEL") IF(VTK_KITS MATCHES "PATENTED") TARGET_LINK_LIBRARIES(${target} vtkPatented) ENDIF(VTK_KITS MATCHES "PATENTED") # # VTK 5 libraries # IF(VTK_KITS MATCHES "WIDGETS") TARGET_LINK_LIBRARIES(${target} vtkWidgets) ENDIF(VTK_KITS MATCHES "WIDGETS") IF(VTK_KITS MATCHES "VOLUMERENDERING") TARGET_LINK_LIBRARIES(${target} vtkVolumeRendering) ENDIF(VTK_KITS MATCHES "VOLUMERENDERING") IF(AddOGL) TARGET_LINK_LIBRARIES(${target} ${OPENGL_LIBRARIES}) ENDIF(AddOGL) IF(UNIX AND AddX11) TARGET_LINK_LIBRARIES(${target} ${X11_LIBRARIES}) ENDIF(UNIX AND AddX11) IF(Shell:QT) IF(QT_LIBRARIES) TARGET_LINK_LIBRARIES(${target} ${QT_LIBRARIES}) ENDIF(QT_LIBRARIES) IF(QT4_INSTALLED) TARGET_LINK_LIBRARIES(${target} ${QT_QTCORE_LIBRARY} ${QT_QTGUI_LIBRARY} ${QT_QT3SUPPORT_LIBRARY} ${QT_QTOPENGL_LIBRARY}) IF (WIN32) FIND_LIBRARY(QT_QTMAIN_LIBRARY qtmain ${QT_LIBRARY_DIR} DOC "This Library is only needed by and included with Qt on MSWindows. It should be NOTFOUND, undefined or IGNORE otherwise.") IF(QT_QTMAIN_LIBRARY) TARGET_LINK_LIBRARIES(${target} ${QT_QTMAIN_LIBRARY}) ELSE(QT_QTMAIN_LIBRARY) MESSAGE(FATAL_ERROR "Qt Main library qtmain.lib is not found.") ENDIF(QT_QTMAIN_LIBRARY) ENDIF (WIN32) ENDIF(QT4_INSTALLED) ENDIF(Shell:QT) IF(Shell:CL) IF(UNIX AND CURSES_LIBRARY) TARGET_LINK_LIBRARIES(${target} curses) ENDIF(UNIX AND CURSES_LIBRARY) ENDIF(Shell:CL) ifrit-3.4.2/configure/0000755000175700010010000000000012167404501013163 5ustar HomeNoneifrit-3.4.2/configure/iconfigure.h0000755000175700010010000000471612167404403015502 0ustar HomeNone/*========================================================================= Program: Ionization FRont Interactive Tool (IFRIT) Language: C++ Copyright (c) 2002-2012 Nick Gnedin All rights reserved. This file may be distributed and/or modified under the terms of the GNU General Public License version 2 as published by the Free Software Foundation and appearing in the file LICENSE.GPL included in the packaging of this file. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHORS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. =========================================================================*/ // // Main configuration parameters and macros for working with them // #ifndef ICONFIGURE_H #define ICONFIGURE_H // // Supported extensions // #define IEXTENSION_NONE 0 #define IEXTENSION_MV 0x80000000 #include "iextensiondefines.h" // // Supported shells // #define ISHELL_CL 1 #define ISHELL_GG 0xFFFFFFFE #define ISHELL_QT 2 //#define ISHELL_FX 4 // // Multiple extensions can be included, they are not exclusive // #define IEXTENSION_INCLUDED(_Type_) ((IEXTENSION & _Type_) != 0) // // Multiple shells can be included, they are not exclusive // #define ISHELL_INCLUDED(_Type_) ((ISHELL & _Type_) != 0) // // ****************************************************************************** // // Set the parameters that define shell and extension. // #ifdef I_EXTERNAL_CONFIGURATION #include "iconfiguresettings.ext.h" #else #define IEXTENSION 0xFFFFFFFF #define ISHELL 0xFFFFFFFF #endif // // ****************************************************************************** // #if !defined(IEXTENSION) #error Misconfiguration: extension (IEXTENSION) is not set. !TERMINATE! #endif #if !defined(ISHELL) || (ISHELL == 0) #error Misconfiguration: shell (ISHELL) is not set. !TERMINATE! #endif #endif // ICONFIGURE_H ifrit-3.4.2/configure/iconfiguresettings.ext0000755000175700010010000000244612167404404017633 0ustar HomeNone/*========================================================================= Program: Ionization FRont Interactive Tool (IFRIT) Language: C++ Copyright (c) 2002-2012 Nick Gnedin All rights reserved. This file may be distributed and/or modified under the terms of the GNU General Public License version 2 as published by the Free Software Foundation and appearing in the file LICENSE.GPL included in the packaging of this file. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHORS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. =========================================================================*/ #define IEXTENSION @exten@ #define ISHELL @shell@ ifrit-3.4.2/configure/iedition.cpp0000755000175700010010000000342212167404404015501 0ustar HomeNone/*========================================================================= Program: Ionization FRont Interactive Tool (IFRIT) Language: C++ Copyright (c) 2002-2012 Nick Gnedin All rights reserved. This file may be distributed and/or modified under the terms of the GNU General Public License version 2 as published by the Free Software Foundation and appearing in the file LICENSE.GPL included in the packaging of this file. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHORS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. =========================================================================*/ #include "iconfigure.h" #include "iedition.h" #include "iobject.h" #include "istring.h" void iEdition::ApplySettings(iObject *obj, const iObjectType &type) { if(obj == 0) return; iString ws = iEdition::GetObjectSettings(type); if(!ws.IsEmpty()) { obj->ReportMissingKeys(false); obj->UnPackCompleteState(ws); obj->ReportMissingKeys(true); } } #ifndef I_EDITION const iString iEdition::GetObjectSettings(const iObjectType &) { return ""; } const iString iEdition::GetEditionName() { return "Standard Edition"; } #endif ifrit-3.4.2/configure/iedition.h0000755000175700010010000000316712167404403015153 0ustar HomeNone/*========================================================================= Program: Ionization FRont Interactive Tool (IFRIT) Language: C++ Copyright (c) 2002-2012 Nick Gnedin All rights reserved. This file may be distributed and/or modified under the terms of the GNU General Public License version 2 as published by the Free Software Foundation and appearing in the file LICENSE.GPL included in the packaging of this file. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHORS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. =========================================================================*/ // // This class encapsulates edition-specific settings // #ifndef IEDITION_H #define IEDITION_H class iObject; class iObjectType; class iString; class iEdition { public: static void ApplySettings(iObject *obj, const iObjectType &type); static const iString GetEditionName(); private: static const iString GetObjectSettings(const iObjectType &type); }; #endif // IEDITION_H ifrit-3.4.2/configure/iextensionbuilder.cpp0000755000175700010010000000722412167404404017435 0ustar HomeNone/*========================================================================= Program: Ionization FRont Interactive Tool (IFRIT) Language: C++ Copyright (c) 2002-2012 Nick Gnedin All rights reserved. This file may be distributed and/or modified under the terms of the GNU General Public License version 2 as published by the Free Software Foundation and appearing in the file LICENSE.GPL included in the packaging of this file. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHORS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. =========================================================================*/ #include "iextensionbuilder.h" #ifdef I_BUILD_EXTENSIONS_EXPLICITLY #include "iconfigure.h" // // --------------- Core extensions --------------------- // // // ART extension // #if IEXTENSION_INCLUDED(IEXTENSION_ART) #include "hextension.h" #endif // // VTK extension // #if IEXTENSION_INCLUDED(IEXTENSION_VTK) #include "vtkextension.h" #endif // // GADGET extension // #if IEXTENSION_INCLUDED(IEXTENSION_GADGET) #include "gextension.h" #endif // // ************************************************************************* // // DESCRIPTION: // Add the include to your core extension header here. The include // needs to be wrapped around in #if/#endif clause. // // ************************************************************************* // #if ISHELL_INCLUDED(ISHELL_GG) // --------------- Generic GUI extensions --------------------- // // ART extension // #if IEXTENSION_INCLUDED(IEXTENSION_ART) #include "hggextension.h" #endif // // VTK extension // #if IEXTENSION_INCLUDED(IEXTENSION_VTK) #include "vtkggextension.h" #endif // // GADGET extension // #if IEXTENSION_INCLUDED(IEXTENSION_GADGET) #include "gggextension.h" #endif // // ************************************************************************* // // DESCRIPTION: // Add the include to your GUI shell extension header here. The include // needs to be wrapped around in #if/#endif clause. // // ************************************************************************* // #endif // --------------- Generic GUI extensions --------------------- void iExtensionBuilder::Build() { // // ART extension // #if IEXTENSION_INCLUDED(IEXTENSION_ART) hExtension::Build(); #if ISHELL_INCLUDED(ISHELL_GG) hggExtension::Build(); #endif #endif // // VTK extension // #if IEXTENSION_INCLUDED(IEXTENSION_VTK) vtkExtension::Build(); #if ISHELL_INCLUDED(ISHELL_GG) vtkggExtension::Build(); #endif #endif // // GADGET extension // #if IEXTENSION_INCLUDED(IEXTENSION_GADGET) gExtension::Build(); #if ISHELL_INCLUDED(ISHELL_GG) gggExtension::Build(); #endif #endif // // ************************************************************************* // // DESCRIPTION: // Add calls to Build function for your extension here. The calls // need to be wrapped around in #if/#endif clause. // // ************************************************************************* // } #else void iExtensionBuilder::Build() { } #endif ifrit-3.4.2/configure/iextensionbuilder.h0000755000175700010010000000261312167404403017076 0ustar HomeNone/*========================================================================= Program: Ionization FRont Interactive Tool (IFRIT) Language: C++ Copyright (c) 2002-2012 Nick Gnedin All rights reserved. This file may be distributed and/or modified under the terms of the GNU General Public License version 2 as published by the Free Software Foundation and appearing in the file LICENSE.GPL included in the packaging of this file. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHORS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. =========================================================================*/ #ifndef IEXTENSIONBUILDER_H #define IEXTENSIONBUILDER_H class iExtensionBuilder { public: static void Build(); }; #endif // IEXTENSIONBUILDER_H ifrit-3.4.2/configure/iextensiondefines.h0000755000175700010010000000306112167404403017063 0ustar HomeNone/*========================================================================= Program: Ionization FRont Interactive Tool (IFRIT) Language: C++ Copyright (c) 2002-2012 Nick Gnedin All rights reserved. This file may be distributed and/or modified under the terms of the GNU General Public License version 2 as published by the Free Software Foundation and appearing in the file LICENSE.GPL included in the packaging of this file. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHORS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. =========================================================================*/ // // Supported extensions // // DESCRIPTION: // Extensions in IFRIT must be associated with power-of-two ids, so that they can be ORed together. // #define IEXTENSION_ART 1 #define IEXTENSION_VTK 2 #define IEXTENSION_GADGET 4 // // Keep adding new defines here, but, please, do not change the existing ones. // ifrit-3.4.2/configure/iextensionfactory.cpp0000755000175700010010000000324612167404404017456 0ustar HomeNone/*========================================================================= Program: Ionization FRont Interactive Tool (IFRIT) Language: C++ Copyright (c) 2002-2012 Nick Gnedin All rights reserved. This file may be distributed and/or modified under the terms of the GNU General Public License version 2 as published by the Free Software Foundation and appearing in the file LICENSE.GPL included in the packaging of this file. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHORS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. =========================================================================*/ #include "iconfigure.h" #include "iextensionfactory.h" // // This file is documented only partially. // #include "ianimatorscript.h" #include "irendertool.h" #if IEXTENSION_INCLUDED(IEXTENSION_MV) #include "imultiviewrendertool.h" #endif iRenderTool* iExtensionFactory::CreateRenderTool(iViewModule *vm) { #if IEXTENSION_INCLUDED(IEXTENSION_MV) return new iMultiViewRenderTool(vm); #else return new iRenderTool(vm); #endif } ifrit-3.4.2/configure/iextensionfactory.h0000755000175700010010000000273012167404404017120 0ustar HomeNone/*========================================================================= Program: Ionization FRont Interactive Tool (IFRIT) Language: C++ Copyright (c) 2002-2012 Nick Gnedin All rights reserved. This file may be distributed and/or modified under the terms of the GNU General Public License version 2 as published by the Free Software Foundation and appearing in the file LICENSE.GPL included in the packaging of this file. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHORS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. =========================================================================*/ #ifndef IEXTENSIONFACTORY_H #define IEXTENSIONFACTORY_H class iRenderTool; class iViewModule; class iExtensionFactory { public: static iRenderTool* CreateRenderTool(iViewModule *vm); }; #endif // IEXTENSIONFACTORY_H ifrit-3.4.2/configure/ifrit.cpp0000755000175700010010000000362712167404404015021 0ustar HomeNone/*========================================================================= Program: Ionization FRont Interactive Tool (IFRIT) Language: C++ Copyright (c) 2002-2012 Nick Gnedin All rights reserved. This file may be distributed and/or modified under the terms of the GNU General Public License version 2 as published by the Free Software Foundation and appearing in the file LICENSE.GPL included in the packaging of this file. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHORS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. =========================================================================*/ // // The IFrIT logo has been created using: // 1. Microsoft Agent software and Microsoft Agent character "Genie"; copyright (c) 1996-1998 Microsoft Corporation. All rights reserved. // 2. ACS Viewer 1.1, build 12; copyright (c) 2005 Grigory Filatov. // #include "iconfigure.h" #include "iextensionbuilder.h" #include "ishell.h" int main(int argc, char **argv) { iString ds; #if ISHELL_INCLUDED(ISHELL_QT) ds = "qt"; #elif ISHELL_INCLUDED(ISHELL_FX) ds = "fx"; #elif ISHELL_INCLUDED(ISHELL_CL) ds = "cl"; #endif // // Build extensions if needed // iExtensionBuilder::Build(); // // Run application // iShell::RunApplication(ds,argc,argv); return 0; } ifrit-3.4.2/configure/iopengl.h0000755000175700010010000000321612167404404015000 0ustar HomeNone/*========================================================================= Program: Ionization FRont Interactive Tool (IFRIT) Language: C++ Copyright (c) 2002-2012 Nick Gnedin All rights reserved. This file may be distributed and/or modified under the terms of the GNU General Public License version 2 as published by the Free Software Foundation and appearing in the file LICENSE.GPL included in the packaging of this file. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHORS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. =========================================================================*/ // // Specify defines that control which OpenGL libraries we use // #ifndef IOPENGL_H #define IOPENGL_H #include // Apple OSX stuff #if defined(VTK_USE_CARBON) || defined(VTK_USE_COCOA) || defined(VTK_USE_OGLR) #define IOPENGL_X11 #else #define IOPENGL_WIN #endif #ifndef IVTK_H #include "ivtk.h" #endif #ifndef VTK_IMPLEMENT_MESA_CXX # include "vtkOpenGL.h" #endif #endif // IOPENGL_H ifrit-3.4.2/configure/ishellfactory.cpp0000755000175700010010000001663212167404404016554 0ustar HomeNone/*========================================================================= Program: Ionization FRont Interactive Tool (IFRIT) Language: C++ Copyright (c) 2002-2012 Nick Gnedin All rights reserved. This file may be distributed and/or modified under the terms of the GNU General Public License version 2 as published by the Free Software Foundation and appearing in the file LICENSE.GPL included in the packaging of this file. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHORS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. =========================================================================*/ #include "iconfigure.h" #if defined(ISHELL) && defined(IEXTENSION) #include "ishellfactory.h" #include "icontrolmodule.h" #include "iimagecomposer.h" #include "irendertool.h" #include "iviewmodule.h" #include "ishell.h" #include #include #include // // Include shell-specific headers // #if ISHELL_INCLUDED(ISHELL_GG) #include "iggcommoneventobservers.h" #include "iggcontrolscript.h" #include "iggrenderwindow.h" #include "iggrenderwindowinteractor.h" #include "iggshell.h" #endif #if ISHELL_INCLUDED(ISHELL_CL) #include "iclcommoneventobservers.h" #include "iclcontrolscript.h" #include "iclshell.h" #endif const iString iShellFactory::qt = "qt"; const iString iShellFactory::cl = "cl"; const iString iShellFactory::fx = "fx"; void iShellFactory::GetSupportedShells(iString &list, iString &help) { list.Clear(); help.Clear(); #if ISHELL_INCLUDED(ISHELL_QT) list += "qt/"; help += "Shell based on Qt Grapical User Interface Toolkit/"; #endif #if ISHELL_INCLUDED(ISHELL_CL) list += "cl/"; help += "Command-line based shell/"; #endif #if ISHELL_INCLUDED(ISHELL_FX) list += "fx/"; help += "Shell based on FOX Grapical User Interface Toolkit/"; #endif } iShell* iShellFactory::CreateShell(const iString &type, int argc, char **argv) { if(type == qt) { #if ISHELL_INCLUDED(ISHELL_QT) return new iggShell(qt,argc,argv); #else return 0; #endif } if(type == cl) { #if ISHELL_INCLUDED(ISHELL_CL) return new iclShell(argc,argv); #else return 0; #endif } if(type == fx) { #if ISHELL_INCLUDED(ISHELL_FX) return new iggShell(fx,argc,argv); #else return 0; #endif } return 0; } iEventObserver* iShellFactory::CreateEventObserver(const iString &type, iControlModule *cm) { if(cm==0 || cm->GetShell()==0) return 0; iShell *shell = cm->GetShell(); if(type == "ParallelUpdate") { if(shell->Type() == qt) { #if ISHELL_INCLUDED(ISHELL_QT) return new iggParallelUpdateEventObserver(cm); #else return 0; #endif } if(shell->Type() == cl) { #if ISHELL_INCLUDED(ISHELL_CL) return new iclParallelUpdateEventObserver(cm); #else return 0; #endif } if(shell->Type() == fx) { #if ISHELL_INCLUDED(ISHELL_FX) return new iggParallelUpdateEventObserver(cm); #else return 0; #endif } } return 0; } iEventObserver* iShellFactory::CreateEventObserver(const iString &type, iViewModule *vm) { if(vm==0 || vm->GetControlModule()==0 || vm->GetControlModule()->GetShell()==0) return 0; iShell *shell = vm->GetControlModule()->GetShell(); if(type == "Progress") { if(shell->Type() == qt) { #if ISHELL_INCLUDED(ISHELL_QT) return new iggProgressEventObserver(vm); #else return 0; #endif } if(shell->Type() == cl) { #if ISHELL_INCLUDED(ISHELL_CL) return new iclProgressEventObserver(vm); #else return 0; #endif } if(shell->Type() == fx) { #if ISHELL_INCLUDED(ISHELL_FX) return new iggProgressEventObserver(vm); #else return 0; #endif } } if(type == "AbortRender") { if(shell->Type() == qt) { #if ISHELL_INCLUDED(ISHELL_QT) return new iggAbortRenderEventObserver(vm); #else return 0; #endif } if(shell->Type() == cl) { #if ISHELL_INCLUDED(ISHELL_CL) return new iclAbortRenderEventObserver(vm); #else return 0; #endif } if(shell->Type() == fx) { #if ISHELL_INCLUDED(ISHELL_FX) return new iggAbortRenderEventObserver(vm); #else return 0; #endif } } if(type == "Pick") { if(shell->Type() == qt) { #if ISHELL_INCLUDED(ISHELL_QT) return new iggPickEventObserver(vm); #else return 0; #endif } if(shell->Type() == cl) { #if ISHELL_INCLUDED(ISHELL_CL) return new iclPickEventObserver(vm); #else return 0; #endif } if(shell->Type() == fx) { #if ISHELL_INCLUDED(ISHELL_FX) return new iggPickEventObserver(vm); #else return 0; #endif } } if(type == "Animator") { if(shell->Type() == qt) { #if ISHELL_INCLUDED(ISHELL_QT) return new iggAnimatorEventObserver(vm); #else return 0; #endif } if(shell->Type() == cl) { #if ISHELL_INCLUDED(ISHELL_CL) return new iclAnimatorEventObserver(vm); #else return 0; #endif } if(shell->Type() == fx) { #if ISHELL_INCLUDED(ISHELL_FX) return new iggAnimatorEventObserver(vm); #else return 0; #endif } } return 0; } iControlScript* iShellFactory::CreateControlScript(iControlModule *cm, iScript *parent) { if(cm==0 || cm->GetShell()==0) return 0; iShell *shell = cm->GetShell(); if(shell->Type() == qt) { #if ISHELL_INCLUDED(ISHELL_QT) return new iggControlScript(cm,parent); #else return 0; #endif } if(shell->Type() == cl) { #if ISHELL_INCLUDED(ISHELL_CL) return new iclControlScript(cm,parent); #else return 0; #endif } if(shell->Type() == fx) { #if ISHELL_INCLUDED(ISHELL_FX) return new iggControlScript(cm,parent); #else return 0; #endif } return 0; } vtkRenderWindow* iShellFactory::CreateRenderWindow(iRenderTool *rv) { if(rv==0 || rv->GetViewModule()==0 || rv->GetViewModule()->GetControlModule()==0 || rv->GetViewModule()->GetControlModule()->GetShell()==0) return 0; iShell *shell = rv->GetViewModule()->GetControlModule()->GetShell(); if(shell->Type() == qt) { #if ISHELL_INCLUDED(ISHELL_QT) return new iggRenderWindow(rv->GetViewModule()); #else return 0; #endif } if(shell->Type() == cl) { #if ISHELL_INCLUDED(ISHELL_CL) return vtkRenderWindow::New(); #else return 0; #endif } if(shell->Type() == fx) { #if ISHELL_INCLUDED(ISHELL_FX) return vtkRenderWindow::New(); #else return 0; #endif } return 0; } vtkRenderWindowInteractor* iShellFactory::CreateRenderWindowInteractor(iRenderTool *rv) { if(rv==0 || rv->GetViewModule()==0 || rv->GetViewModule()->GetControlModule()==0 || rv->GetViewModule()->GetControlModule()->GetShell()==0) return 0; iShell *shell = rv->GetViewModule()->GetControlModule()->GetShell(); if(shell->Type() == qt) { #if ISHELL_INCLUDED(ISHELL_QT) return new iggRenderWindowInteractor(shell); #else return 0; #endif } if(shell->Type() == cl) { #if ISHELL_INCLUDED(ISHELL_CL) return vtkRenderWindowInteractor::New(); #else return 0; #endif } if(shell->Type() == fx) { #if ISHELL_INCLUDED(ISHELL_FX) return vtkRenderWindowInteractor::New(); #else return 0; #endif } return 0; } #endif ifrit-3.4.2/configure/ishellfactory.h0000755000175700010010000000504712167404404016217 0ustar HomeNone/*========================================================================= Program: Ionization FRont Interactive Tool (IFRIT) Language: C++ Copyright (c) 2002-2012 Nick Gnedin All rights reserved. This file may be distributed and/or modified under the terms of the GNU General Public License version 2 as published by the Free Software Foundation and appearing in the file LICENSE.GPL included in the packaging of this file. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHORS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. =========================================================================*/ #ifndef ISHELLFACTORY_H #define ISHELLFACTORY_H #include "istring.h" class iControlModule; class iControlScript; class iEventObserver; class iRenderTool; class iScript; class iShell; class iString; class iViewModule; class vtkRenderWindow; class vtkRenderWindowInteractor; class iShellFactory { friend class iAbortRenderEventObserver; friend class iAnimatorEventObserver; friend class iAnimatorScript; friend class iControlScript; friend class iFileLoader; friend class iMarkerEventObserver; friend class iParallelUpdateEventObserver; friend class iPickEventObserver; friend class iProgressEventObserver; friend class iRenderTool; friend class iShell; friend class hDataReader; public: static void GetSupportedShells(iString &list, iString &help); protected: static iShell* CreateShell(const iString &type, int argc, char **argv); static iEventObserver* CreateEventObserver(const iString &type, iControlModule *cm); static iEventObserver* CreateEventObserver(const iString &type, iViewModule *vm); static iControlScript* CreateControlScript(iControlModule *cm, iScript *parent); static vtkRenderWindow* CreateRenderWindow(iRenderTool *rv); static vtkRenderWindowInteractor* CreateRenderWindowInteractor(iRenderTool *rv); private: static const iString qt, cl, fx; }; #endif // ISHELLFACTORY_H ifrit-3.4.2/configure/iversion.cpp0000755000175700010010000002314412167404404015536 0ustar HomeNone/*========================================================================= Program: Ionization FRont Interactive Tool (IFRIT) Language: C++ Copyright (c) 2002-2012 Nick Gnedin All rights reserved. This file may be distributed and/or modified under the terms of the GNU General Public License version 2 as published by the Free Software Foundation and appearing in the file LICENSE.GPL included in the packaging of this file. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHORS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. =========================================================================*/ #include "iconfigure.h" #include "iversion.h" // // IFrIT version // #define IVERSION_BASE "3.4.2" #define IVERSION_EXT_ART "2.4.1" #define IVERSION_EXT_MV "1.2.1" #define IVERSION_EXT_VTK "1.1.0" #define IVERSION_EXT_GADGET "1.1.0" // // History // // 060608 Base-3.0.0b1 ART-2.0.0b1 MV-1.0.0b1 -- First beta release // 060609 Base-3.0.0b2 ART-2.0.0b2 MV-1.0.0b2 -- Added special locations in CrossSectionViewSubject // 060622 Base-3.0.0b3 ART-2.0.0b3 MV-1.0.0b3 -- Added coordinate system switch for ART extension // 060701 Base-3.0.0b4 ART-2.0.0b4 MV-1.0.0b4 -- Added abstract/generic filters for porting, cleaned up class names // 060707 Base-3.0.0b5 ART-2.0.0b5 MV-1.0.0b5 -- Completed Script Debugger // 060721 Base-3.0.0b6 ART-2.0.0b6 MV-1.0.0b6 -- Completed port to Qt4 // 060728 Base-3.0.0b7 ART-2.0.0b7 MV-1.0.0b7 -- Internal changes, docking fixed (?) // 060815 Base-3.0.0b8 ART-2.0.0b8 MV-1.0.0b8 -- New icons, docking now really fixed, x-section in texture mode on multiple processors is fixed // Includes 3D texture model for volume rendering and direct MPEG/AVI movie creation // 060817 Base-3.0.0 ART-2.0.0 MV-1.0.0 -- First release: basic things seem to work now. // 060830 Base-3.0.1 ART-2.0.1 MV-1.0.0 -- Some bug fixes // 060926 Base-3.0.2 ART-2.0.2 MV-1.0.0 -- Refactored for simplified extensions (ViewSubjects etc) // 060930 Base-3.0.3 ART-2.0.3 MV-1.0.0 -- Need to re-release, created a branch in CVS too early by mistake // 061003 Base-3.0.4 ART-2.0.4 MV-1.0.0 -- Added special brightness palette, fixed iArray out-of-boundary bug, fixed DataExplorer bug // 061010 Base-3.0.5 ART-2.0.5 MV-1.0.0 -- fixed Interactor bug, ART isosurface bugs(?), more iArray out-of-boundary bugs // 061119 Base-3.0.6 ART-2.0.6 MV-1.0.0 -- fixed DataLimits+clones bug, RulerDialog bug, parallel stitch bug, added window list idalog, x-section placement enhancements // 061120 Base-3.0.7 ART-2.0.7 MV-1.0.0 -- work around vtkMarchingContourFilter multi-threaded bug. // 061221 Base-3.0.8 ART-2.0.8 MV-1.0.1 -- internal changes, pseudo-color composing in ImageComposer, minor GUI modifications, bug fixes. // 070203 Base-3.0.9 ART-2.0.9 MV-1.0.1 -- internal changes to particle masking, new masking modes, bug fixes // // 070325 Base-3.1.0 ART-2.1.0 MV-1.0.2 VTK-1.0.0b0 GADGET-1.0.0b0 // split DataSubject into DataSubject proper and DataFileLoader // added VTK & GADGET extensions // fixed MultiView full-screen mode bugs // // 070422 Base-3.1.1 ART-2.1.2 MV-1.0.2 VTK-1.0.0b0 GADGET-1.0.0b1 // fixed marker Create/Delete panel bug // other stylistic bug fixes // redone volume rendering interface // ART 2D & 3D texture volume rendering by uniform resampling // // 070502 Base-3.1.2 ART-2.1.3 MV-1.0.3 VTK-1.0.0b0 GADGET-1.0.0b2 // C-style casting replaced whereever possible // ViewModule::LabelOffset property added // Fixed bugs in iDataExplorer // Fixed bugs in recognizing animatable filename without a suffix // // 070508 Base-3.1.3 ART-2.1.3 MV-1.0.3 VTK-1.0.0b0 GADGET-1.0.0b2 // Fixed bugs with saving markers and animation not stopping on error // New markers are placed in the camera focal point // // 070527 Base-3.1.4 ART-2.1.4 MV-1.0.4 VTK-1.0.0b1 GADGET-1.0.0b2 // Added external image as a background // Fixed batch mode and channeling output // Fixed shifting // // 070618 Base-3.1.5 ART-2.1.5 MV-1.0.4 VTK-1.0.0b1 GADGET-1.0.0b2 // Added zooms in Composer // Fixed particle picking // Added particle auto-scaling // Fixed offscreen mode with Mesa libraries // // 070710 Base-3.1.6 ART-2.1.5 MV-1.0.4 VTK-1.0.0b1 GADGET-1.0.0b2 // Composer bug fixes // // 070826 Base-3.2.0 ART-2.1.5 MV-1.0.4 VTK-1.0.0b1 GADGET-1.0.0b2 // VTK-style iExpressionParser replaced with iCalculator // scripts are completely re-written and expanded // // 070916 Base-3.2.1 ART-2.1.5 MV-1.0.4 VTK-1.0.0b1 GADGET-1.0.0b2 // Bug fixes // // 071018 Base-3.2.2 ART-2.1.6 MV-1.0.4 VTK-1.0.0b1 GADGET-1.0.0b2 // Abundances/densities switch for species in ART extension // Bug fixes // // 080112 Base-3.2.3 ART-2.1.6 MV-1.0.4 VTK-1.0.0b1 GADGET-1.0.0b2 // Bug fixes in iOrthoSlicer and iBoundedPolyDataSource // // 080510 Base-3.2.4 ART-2.1.7 MV-1.0.4 VTK-1.0.0 GADGET-1.0.0 // Minor bug fixes // // 080510 Base-3.2.5 ART-2.1.8 MV-1.0.4 VTK-1.0.0 GADGET-1.0.0 // Color bar size, minor bug fixes, including finite cross-section bar in ART edition // // 080824 Base-3.2.6 ART-2.1.8 MV-1.0.4 VTK-1.0.0 GADGET-1.0.0 // Depth search option as a way to fix VTK artifacts, refresh button on FileSet dialog // // 081019 Base-3.2.7 ART-2.1.8 MV-1.1.0 VTK-1.0.0 GADGET-1.0.0 // MultiView extension redone, port to VTK 5.2, fixed overlays // // 090822 Base-3.2.8 ART-2.2.0 MV-1.1.0 VTK-1.0.0 GADGET-1.0.0 // Fixed isosurface making for left/right coordinate systems in ART extension // Renamed HART extension into ART extension and added support for CART // // 091210 Base-3.2.9 ART-2.2.1 MV-1.1.0 VTK-1.0.0 GADGET-1.0.0 // Added double precision particle positions reading for CART // Fixed a few minor bugs // // 100222 Base-3.3.0 ART-2.3.0 MV-1.2.0 VTK-1.1.0 GADGET-1.1.0 // Removed last vestiges of Qt3 when using Qt4 - Qt3Support is not needed any more // Ported to 64-bin windows // // 100315 Base-3.3.1 ART-2.3.0 MV-1.2.0 VTK-1.1.0 GADGET-1.1.0 // Emergency release: removed support for VTK 5.4 due to its performance bug // // 100503 Base-3.3.2 ART-2.3.1 MV-1.2.1 VTK-1.1.0 GADGET-1.1.0 // Fixed bug with ART streamlines, fixed anti-aliasiang bug in docking, blocked // all extraneous functions in iggRenderWindow, re-factored the stereo mode to // fix the flicker reported by Doug and stereo non-recongnition reported by Patrick. // // 100722 Base-3.3.3 ART-2.3.1 MV-1.2.1 VTK-1.1.0 GADGET-1.1.0 // Fixed a bug with Qt4 under Unix // // 100818 Base-3.3.4 ART-2.3.1 MV-1.2.1 VTK-1.1.0 GADGET-1.1.0 // Fixed a bug with crashes in cross section, reported by Robyn // Ported to VTK 5.6.1, added GPU Volume rendering support // Removed Event Recorder as it caused compilation errors on some compilers // // 120320 Base-3.3.5 ART-2.3.2 MV-1.2.1 VTK-1.1.0 GADGET-1.1.0 // A few bug fixes. // Ported to VTK 5.8.0, added GPU Volume rendering support // // 120809 Base-3.4.0 ART-2.4.0 MV-1.2.1 VTK-1.1.0 GADGET-1.1.0 // Mioved to Mercurial SC // ARTIO and CART io support // Some widget modification (FileName, Color) // Removed CameraPath Animator mode, fixed title page and logo // // 121219 Base-3.4.1 ART-2.4.0 MV-1.2.1 VTK-1.1.0 GADGET-1.1.0 // Minor bug fix // // 130710 Base-3.4.2 ART-2.4.1 MV-1.2.1 VTK-1.1.0 GADGET-1.1.0 // Added support for selecting sub-volume of the ART mesh, other minor fixes // // // ToDo (major additions) // // 1. Point sprats for particles // 2. Multiple images in Composer (do we need this???) // #if ISHELL_INCLUDED(ISHELL_QT) #include "iqt.h" #endif const iString iVersion::GetVersion() { return IVERSION_BASE; } const iString iVersion::GetIncludedExtensions() { iString tmp; #if IEXTENSION_INCLUDED(IEXTENSION_ART) tmp += iString("ART extension v") + IVERSION_EXT_ART +";"; #endif #if IEXTENSION_INCLUDED(IEXTENSION_MV) tmp += iString("MultiView extension v") + IVERSION_EXT_MV +";"; #endif #if IEXTENSION_INCLUDED(IEXTENSION_GADGET) tmp += iString("GADGET extension v") + IVERSION_EXT_GADGET +";"; #endif #if IEXTENSION_INCLUDED(IEXTENSION_VTK) tmp += iString("Native-VTK extension v") + IVERSION_EXT_VTK +";"; #endif return tmp; } const iString iVersion::GetIncludedShells() { iString tmp; #if ISHELL_INCLUDED(ISHELL_CL) tmp += iString("Command-line shell") + ";"; #endif #if ISHELL_INCLUDED(ISHELL_QT) tmp += iString("Qt-based GUI shell (Qt ") + QT_VERSION_STR + ");"; #endif #if ISHELL_INCLUDED(ISHELL_FX) tmp += iString("FOX-based GUI shell") + ";"; #endif return tmp; } ifrit-3.4.2/configure/iversion.h0000755000175700010010000000300612167404404015176 0ustar HomeNone/*========================================================================= Program: Ionization FRont Interactive Tool (IFRIT) Language: C++ Copyright (c) 2002-2012 Nick Gnedin All rights reserved. This file may be distributed and/or modified under the terms of the GNU General Public License version 2 as published by the Free Software Foundation and appearing in the file LICENSE.GPL included in the packaging of this file. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHORS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. =========================================================================*/ // // IFrIT version and build // #ifndef IVERSION_H #define IVERSION_H #include "istring.h" class iVersion { public: static const iString GetVersion(); static const iString GetIncludedExtensions(); static const iString GetIncludedShells(); }; #endif // IVERSION_H ifrit-3.4.2/configure/ivtk.h0000755000175700010010000000477212167404404014330 0ustar HomeNone/*========================================================================= Program: Ionization FRont Interactive Tool (IFRIT) Language: C++ Copyright (c) 2002-2012 Nick Gnedin All rights reserved. This file may be distributed and/or modified under the terms of the GNU General Public License version 2 as published by the Free Software Foundation and appearing in the file LICENSE.GPL included in the packaging of this file. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHORS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. =========================================================================*/ // // VTK version and build (porting helper) // #ifndef IVTK_H #define IVTK_H #include #include #if (VTK_MAJOR_VERSION < 5) #error "This version of VTK is too old and is no longer supported." #endif #if (VTK_MAJOR_VERSION==5 && VTK_MINOR_VERSION==0) #define IVTK_50 #if (VTK_BUILD_VERSION < 2) #define IVTK_501 #endif #endif #if (VTK_MAJOR_VERSION==5 && VTK_MINOR_VERSION==2) #define IVTK_52 #endif #if (VTK_MAJOR_VERSION==5 && VTK_MINOR_VERSION<2) #define IVTK_PRE52 #endif #if (VTK_MAJOR_VERSION==5 && VTK_MINOR_VERSION==4) #define IVTK_54 #error "VTK 5.4 is not supported at present due to a severe performance bug." #endif #if (VTK_MAJOR_VERSION==5 && VTK_MINOR_VERSION<4) #define IVTK_PRE54 #endif #if (VTK_MAJOR_VERSION==5 && VTK_MINOR_VERSION==6) #define IVTK_56 #endif #if (VTK_MAJOR_VERSION==5 && VTK_MINOR_VERSION<6) #define IVTK_PRE56 #endif #if defined(IVTK_PRE56) || (VTK_MAJOR_VERSION==5 && VTK_MINOR_VERSION==6 && VTK_BUILD_VERSION==0) #define IVTK_PRE561 #endif #define IVTK_QUAD_ORDER 3 #ifdef VTK_USE_VIDEO_FOR_WINDOWS #define IVTK_SUPPORTS_AVI #endif #ifdef VTK_USE_MPEG2_ENCODER #define IVTK_SUPPORTS_MPEG #endif #ifdef VTK_PRE56 #define vtkSwitch(s) ((s)?1:0) #else #define vtkSwitch(s) (s) #endif #endif // IVTK_H ifrit-3.4.2/core/0000755000175700010010000000000012167404440012134 5ustar HomeNoneifrit-3.4.2/core/iabstractextension.cpp0000755000175700010010000001013612167404424016557 0ustar HomeNone/*========================================================================= Program: Ionization FRont Interactive Tool (IFRIT) Language: C++ Copyright (c) 2002-2012 Nick Gnedin All rights reserved. This file may be distributed and/or modified under the terms of the GNU General Public License version 2 as published by the Free Software Foundation and appearing in the file LICENSE.GPL included in the packaging of this file. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHORS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. =========================================================================*/ #include "iabstractextension.h" #include "icrosssectionviewsubject.h" #include "ierror.h" #include "iobjectfactory.h" #include "iparticlesviewsubject.h" #include "isurfaceviewsubject.h" #include "itensorfieldviewsubject.h" #include "ivectorfieldviewsubject.h" #include "ivolumeviewsubject.h" int iAbstractExtension::DefineToId(int n) { int id = -1; unsigned int k = (unsigned int)n; while(k != 0U) { id++; k = k >> 1; } return id; } iAbstractExtension::iAbstractExtension(int n, const iString& name) : mId(iAbstractExtension::DefineToId(n)), mName(name), mSubjectCounter(0) { // // Check that we configured correctly // if(n != (1<GetId(); } \ static int SubjectId(int n = -1){ return (1+Self()->GetId())*1000 + (n == -1 ? Self()->GetSubjectCounter() : n); } \ static const iString& Name(){ return Self()->GetName(); } \ private: \ _class_(); \ static int mAutoBuild; \ static const iAbstractExtension* Self() #define IEXTENSION_DEFINE(_name_,_class_) \ int _class_::mAutoBuild = Self()->GetId(); \ const iAbstractExtension* _class_::Self() \ { \ static iAbstractExtension* self = new _class_; \ return self; \ } \ int _class_::Build() \ { \ return Self()->GetId() - mAutoBuild; \ } \ _class_::_class_() : iAbstractExtension(IEXTENSION_##_name_,#_name_){} #define IEXTENSION_DECLARE_CLASS(_prefix_) \ class _prefix_##Extension : public iAbstractExtension \ { \ IEXTENSION_DECLARE(_prefix_##Extension); \ private: \ virtual iDataReaderExtension* CreateDataReaderExtension(iDataReader *reader) const; \ virtual iCrossSectionViewSubject* CreateCrossSectionSubject(iViewModule *vm, int index) const; \ virtual iParticlesViewSubject* CreateParticlesSubject(iViewModule *vm, int index) const; \ virtual iSurfaceViewSubject* CreateSurfaceSubject(iViewModule *vm, int index) const; \ virtual iTensorFieldViewSubject* CreateTensorFieldSubject(iViewModule *vm, int index) const; \ virtual iVectorFieldViewSubject* CreateVectorFieldSubject(iViewModule *vm, int index) const; \ virtual iVolumeViewSubject* CreateVolumeSubject(iViewModule *vm, int index) const; \ } #define IEXTENSION_DEFINE_CLASS(_name_,_prefix_,_stype_,_vtype_,_ttype_,_ptype_) \ IEXTENSION_DEFINE(_name_,_prefix_##Extension); \ iCrossSectionViewSubject* _prefix_##Extension::CreateCrossSectionSubject(iViewModule *vm, int index) const \ { \ if(index == 0) return this->NewCrossSectionSubject(vm,_stype_::DataType()); else return 0; \ } \ iParticlesViewSubject* _prefix_##Extension::CreateParticlesSubject(iViewModule *vm, int index) const \ { \ if(index == 0) return this->NewParticlesSubject(vm,_ptype_::DataType(),_ptype_::DataType().GetTextName()); else return 0; \ } \ iSurfaceViewSubject* _prefix_##Extension::CreateSurfaceSubject(iViewModule *vm, int index) const \ { \ if(index == 0) return this->NewSurfaceSubject(vm,_stype_::DataType()); else return 0; \ } \ iTensorFieldViewSubject* _prefix_##Extension::CreateTensorFieldSubject(iViewModule *vm, int index) const \ { \ if(index == 0) return this->NewTensorFieldSubject(vm,_ttype_::DataType(),_stype_::DataType()); else return 0; \ } \ iVectorFieldViewSubject* _prefix_##Extension::CreateVectorFieldSubject(iViewModule *vm, int index) const \ { \ if(index == 0) return this->NewVectorFieldSubject(vm,_vtype_::DataType(),_stype_::DataType()); else return 0; \ } \ iVolumeViewSubject* _prefix_##Extension::CreateVolumeSubject(iViewModule *vm, int index) const \ { \ if(index == 0) return this->NewVolumeSubject(vm,_stype_::DataType()); else return 0; \ } \ iDataReaderExtension* _prefix_##Extension::CreateDataReaderExtension(iDataReader *reader) const \ { \ return new _prefix_##DataReaderExtension(reader,this->GetName()); \ } #endif // IABSTRACTEXTENSION_H ifrit-3.4.2/core/iactor.cpp0000755000175700010010000002131112167404424014124 0ustar HomeNone/*========================================================================= Program: Ionization FRont Interactive Tool (IFRIT) Language: C++ Copyright (c) 2002-2012 Nick Gnedin All rights reserved. This file may be distributed and/or modified under the terms of the GNU General Public License version 2 as published by the Free Software Foundation and appearing in the file LICENSE.GPL included in the packaging of this file. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHORS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. =========================================================================*/ #include "iactor.h" #include "iartifactcorrector.h" #include "idatalimits.h" #include "ierror.h" #include "ilookuptable.h" #include "ipalette.h" #include #include #include #include #include #include #include #include #include // // Templates // #include "iarraytemplate.h" // // Actor class // iActor* iActor::New(bool scaled) { return new iActor(scaled); } iActor::iActor(bool scaled) { mBasicScale = mAxisScale[0] = mAxisScale[1] = mAxisScale[2] = 1.0; mScaled = scaled; mCurrentSubject = 0; mDummySubject = new iActorSubject(this,0); IERROR_ASSERT(mDummySubject); mDummySubjectPointer = mDummySubject; mCorrector = 0; mDefaultMapper = vtkPolyDataMapper::New(); IERROR_ASSERT(mDefaultMapper); this->SetMapper(mDefaultMapper); mDefaultMapper->Delete(); mLookupTable = iLookupTable::New(); IERROR_ASSERT(mLookupTable); mDefaultMapper->SetLookupTable(mLookupTable); mDefaultMapper->UseLookupTableScalarRangeOn(); this->CreateOwnLODs(); mDefaultLODMappers = this->LODMappers; // saving for proper deletion vtkMapper *m; mDefaultLODMappers->InitTraversal(); while((m = mDefaultLODMappers->GetNextItem()) != 0) { m->SetLookupTable(mLookupTable); m->UseLookupTableScalarRangeOn(); } } iActor::~iActor() { while(mSubjects.Size() > 0) this->ReleaseGraphicsResources(mSubjects.Last()->mWindow); delete mDummySubject; if(mCorrector != 0) mCorrector->UnRegister(this); mLookupTable->Delete(); this->Mapper = mDefaultMapper; this->LODMappers = mDefaultLODMappers; } void iActor::InstallArtifactCorrector(iArtifactCorrector *c) { if(c == mCorrector) return; if(mCorrector != 0) mCorrector->UnRegister(this); mCorrector = c; mCorrector->Register(this); } bool iActor::SetCurrentWindow(vtkWindow *win) { int i; #ifdef I_CHECK1 IERROR_ASSERT(win); #endif if(mCurrentSubject!=0 && mCurrentSubject->mWindow==win) return true; // already current // // Find this window // mDummySubject->mWindow = win; i = mSubjects.Find(mDummySubjectPointer); if(i<0 || i>=mSubjects.Size()) return false; mCurrentSubject = mSubjects[i].Pointer(); this->Mapper = mCurrentSubject->mMapper; this->LODMappers = mCurrentSubject->mLODMappers; return true; } void iActor::ReleaseGraphicsResources(vtkWindow *win) { if(win==0 || !this->SetCurrentWindow(win)) return; // already released this->vtkLODActor::ReleaseGraphicsResources(win); if(mSubjects.Remove(mCurrentSubject)) delete mCurrentSubject; mCurrentSubject = 0; this->Mapper = mDefaultMapper; this->LODMappers = mDefaultLODMappers; } void iActor::Render(vtkRenderer *ren, vtkMapper * /*m*/) { vtkWindow *win = ren->GetVTKWindow(); if(win == 0) return; // nothing to do if(!this->SetCurrentWindow(win)) { // // This window has not been attached yet // mCurrentSubject = new iActorSubject(this,win); IERROR_ASSERT(mCurrentSubject); mSubjects.Add(mCurrentSubject); mCurrentSubject->mMapper->SetInput(mDefaultMapper->GetInput()); this->Mapper = mCurrentSubject->mMapper; this->LODMappers = mCurrentSubject->mLODMappers; } if(mScaled) { vtkCamera *c = ren->GetActiveCamera(); double ps; if(c->GetParallelProjection() == 0) { vtkCamera *cam = ren->GetActiveCamera(); ps = cam->GetDistance()*tan(cam->GetViewAngle()/2.0*0.017453292)/1.6; } else { ps = c->GetParallelScale()/1.6; } ps *= mBasicScale; this->SetScale(ps*mAxisScale[0],ps*mAxisScale[1],ps*mAxisScale[2]); } else { this->SetScale(mAxisScale[0],mAxisScale[1],mAxisScale[2]); } if(mCorrector != 0) { vtkPolyDataMapper *m = vtkPolyDataMapper::SafeDownCast(this->Mapper); if(m != 0) mCorrector->CorrectArtifacts(ren,this->GetProperty(),m,this->AllocatedRenderTime); } // // Fix VTK bug // if(this->GetProperty()->GetMTime() > this->Mapper->GetMTime()) { this->Mapper->Modified(); } vtkLODActor::Render(ren,this->Mapper); } void iActor::SetScaled(bool s) { if(s != mScaled) { mScaled = s; this->Modified(); } } void iActor::SetBasicScale(double s) { if(s > 0.0) { mBasicScale = s; this->Modified(); } } void iActor::SetAxisScale(double sx, double sy, double sz) { if(sx>0.0 && sy>0.0 && sz>0.0) { mAxisScale[0] = sx; mAxisScale[1] = sy; mAxisScale[2] = sz; this->Modified(); } } // // Mapper functionality // void iActor::SetInput(vtkPolyData *data) { mDefaultMapper->SetInput(data); vtkMapper *save = this->Mapper; this->Mapper = mDefaultMapper; this->UpdateOwnLODs(); this->Mapper = save; vtkPolyDataMapper *m = vtkPolyDataMapper::SafeDownCast(this->Mapper); if(m != 0) m->SetInput(data); } void iActor::SetScalarVisibility(bool s) { int i; mDefaultMapper->SetScalarVisibility(s?1:0); for(i=0; imMapper->SetScalarVisibility(s?1:0); } void iActor::SetScalarRange(float min, float max) { int i; if(mDefaultMapper->GetUseLookupTableScalarRange() == 0) { mDefaultMapper->SetScalarRange(min,max); for(i=0; imMapper->SetScalarRange(min,max); } mLookupTable->SetTableRange(min,max); } void iActor::SyncWithLimits(iDataLimits *l, int v, float scale) { if(l!=0 && scale>0.0f && v>=0 && vGetNumVars()) { mLookupTable->SetStretch(iDataStretch::Linear); this->SetScalarRange(l->GetLowerLimit(v)/scale,l->GetUpperLimit(v)/scale); mLookupTable->SetStretch(l->GetStretch(v)); } } void iActor::AddMapperObserver(unsigned long event, vtkCommand *obs) { int i; mDefaultMapper->AddObserver(event,obs); for(i=0; imMapper->AddObserver(event,obs); } void iActor::AddClippingPlane(vtkPlane *plane) { int i; mDefaultMapper->AddClippingPlane(plane); for(i=0; imMapper->AddClippingPlane(plane); } void iActor::RemoveClippingPlane(vtkPlane *plane) { int i; mDefaultMapper->RemoveClippingPlane(plane); for(i=0; imMapper->RemoveClippingPlane(plane); } void iActor::ColorByArrayComponent(int arrayNum, int component) { int i; mDefaultMapper->ColorByArrayComponent(arrayNum,component); for(i=0; imMapper->ColorByArrayComponent(arrayNum,component); } // // Helper classes // iActorSubject::iActorSubject(iActor *parent, vtkWindow *win) { IERROR_ASSERT(parent); mWindow = win; if(win == 0) // dummy { mMapper = 0; mLODMappers = 0; } else { mMapper = vtkPolyDataMapper::New(); IERROR_ASSERT(mMapper); mMapper->ShallowCopy(parent->GetMapper()); mLODMappers = vtkMapperCollection::New(); IERROR_ASSERT(mLODMappers); vtkMapper *m1; vtkPolyDataMapper *m2; vtkMapperCollection *pm = parent->GetLODMappers(); pm->InitTraversal(); while((m1 = pm->GetNextItem()) != 0) { m2 = vtkPolyDataMapper::New(); IERROR_ASSERT(m2); m2->ShallowCopy(m1); mLODMappers->AddItem(m2); m2->Delete(); } } } iActorSubject::~iActorSubject() { if(mMapper != 0) mMapper->Delete(); if(mLODMappers != 0) mLODMappers->Delete(); } iActorSubjectPointer::iActorSubjectPointer(iActorSubject *subject) { mPointer = subject; } void iActorSubjectPointer::operator=(iActorSubject *p) { mPointer = p; } void iActorSubjectPointer::operator=(const iActorSubjectPointer &p) { mPointer = p.mPointer; } bool iActorSubjectPointer::operator==(const iActorSubjectPointer &p) const { if(mPointer!=0 && p.mPointer!=0) { return (mPointer->mWindow == p.mPointer->mWindow); } else return (mPointer == p.mPointer); } ifrit-3.4.2/core/iactor.h0000755000175700010010000000765012167404405013602 0ustar HomeNone/*========================================================================= Program: Ionization FRont Interactive Tool (IFRIT) Language: C++ Copyright (c) 2002-2012 Nick Gnedin All rights reserved. This file may be distributed and/or modified under the terms of the GNU General Public License version 2 as published by the Free Software Foundation and appearing in the file LICENSE.GPL included in the packaging of this file. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHORS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. =========================================================================*/ // // A combined class for ALL IFrIT actors & mappers - they must be the same so that renderers // can be copied. Thus, it is the most general scaled LOD actor. // This actor will render itself efficiently in multiple windows. // // #ifndef IACTOR_H #define IACTOR_H #include #include "iarray.h" class iActor; class iArtifactCorrector; class iDataLimits; class iLookupTable; class iPalette; class vtkPlane; class vtkPolyData; class vtkPolyDataMapper; class iActorSubject { // // It is really just a struct... // friend class iActor; friend class iActorSubjectPointer; private: iActorSubject(iActor *parent, vtkWindow *win); virtual ~iActorSubject(); vtkWindow *mWindow; vtkPolyDataMapper *mMapper; vtkMapperCollection *mLODMappers; }; class iActorSubjectPointer { public: iActorSubjectPointer(iActorSubject *subject); iActorSubjectPointer(){ mPointer = 0; } inline iActorSubject* Pointer() const { return mPointer; } inline iActorSubject* operator->() const { return mPointer; } void operator=(iActorSubject *p); void operator=(const iActorSubjectPointer &p); bool operator==(const iActorSubjectPointer &p) const; private: iActorSubject *mPointer; }; class iActor: public vtkLODActor { public: vtkTypeMacro(iActor,vtkLODActor); static iActor* New(bool scaled = false); virtual void ReleaseGraphicsResources(vtkWindow *win); virtual void Render(vtkRenderer *ren, vtkMapper *m); inline bool GetScaled(){ return mScaled; } void SetScaled(bool s); inline double GetBasicScale(){ return mBasicScale; } void SetBasicScale(double s); inline const double* GetAxisScale(){ return mAxisScale; } void SetAxisScale(double sx, double sy, double sz); // // Mapper functionality // void SetInput(vtkPolyData *data); void SetScalarVisibility(bool s); void SetScalarRange(float min, float max); void SyncWithLimits(iDataLimits *l, int v, float scale = 1.0f); inline iLookupTable* GetLookupTable() const { return mLookupTable; } void AddMapperObserver(unsigned long event, vtkCommand *obs); void AddClippingPlane(vtkPlane *plane); void RemoveClippingPlane(vtkPlane *plane); void ColorByArrayComponent(int arrayNum, int component); void InstallArtifactCorrector(iArtifactCorrector *c); protected: iActor(bool scaled = false); virtual ~iActor(); private: bool SetCurrentWindow(vtkWindow *win); double mBasicScale, mAxisScale[3]; bool mScaled; iSearchableArray mSubjects; iActorSubject *mDummySubject, *mCurrentSubject; iActorSubjectPointer mDummySubjectPointer; vtkPolyDataMapper *mDefaultMapper; vtkMapperCollection *mDefaultLODMappers; iLookupTable *mLookupTable; iArtifactCorrector *mCorrector; }; #endif // IACTOR_H ifrit-3.4.2/core/iactorcollection.cpp0000755000175700010010000000364312167404424016210 0ustar HomeNone/*========================================================================= Program: Ionization FRont Interactive Tool (IFRIT) Language: C++ Copyright (c) 2002-2012 Nick Gnedin All rights reserved. This file may be distributed and/or modified under the terms of the GNU General Public License version 2 as published by the Free Software Foundation and appearing in the file LICENSE.GPL included in the packaging of this file. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHORS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. =========================================================================*/ #include "iactorcollection.h" #include "iactor.h" // // Templates // #include "iarraytemplate.h" iActorCollection* iActorCollection::New() { return new iActorCollection(); } iActorCollection::iActorCollection() { } iActorCollection::~iActorCollection() { int i; for(i=0; iUnRegister(this); } void iActorCollection::SetVisibility(int s) { int i; for(i=0; iSetVisibility(s); } void iActorCollection::AddActor(iActor *a) { if(a != 0) { mActors.AddUnique(a); a->Register(this); } } void iActorCollection::RemoveActor(iActor *a) { if(a != 0) { if(mActors.Remove(a)) a->UnRegister(this); } } ifrit-3.4.2/core/iactorcollection.h0000755000175700010010000000355512167404405015656 0ustar HomeNone/*========================================================================= Program: Ionization FRont Interactive Tool (IFRIT) Language: C++ Copyright (c) 2002-2012 Nick Gnedin All rights reserved. This file may be distributed and/or modified under the terms of the GNU General Public License version 2 as published by the Free Software Foundation and appearing in the file LICENSE.GPL included in the packaging of this file. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHORS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. =========================================================================*/ // // A simple collection of iActors // #ifndef IACTORCOLLECTION_H #define IACTORCOLLECTION_H #include #include "iarray.h" class iActor; class iActorCollection : public vtkObject { public: vtkTypeMacro(iActorCollection,vtkObject); static iActorCollection* New(); void SetVisibility(int s); inline void VisibilityOn(){ this->SetVisibility(1); } inline void VisibilityOff(){ this->SetVisibility(0); } void AddActor(iActor *a); void RemoveActor(iActor *a); protected: virtual ~iActorCollection(); private: iActorCollection(); iPointerArray mActors; }; #endif // IACTORCOLLECTION_H ifrit-3.4.2/core/ianimator.cpp0000755000175700010010000006005312167404424014634 0ustar HomeNone/*========================================================================= Program: Ionization FRont Interactive Tool (IFRIT) Language: C++ Copyright (c) 2002-2012 Nick Gnedin All rights reserved. This file may be distributed and/or modified under the terms of the GNU General Public License version 2 as published by the Free Software Foundation and appearing in the file LICENSE.GPL included in the packaging of this file. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHORS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. =========================================================================*/ // // Implementation of ianimator.h // #include "ianimator.h" #include "ianimatorscript.h" #include "icommoneventobservers.h" #include "icontrolmodule.h" #include "icrosssectionviewsubject.h" #include "idatareader.h" #include "idirectory.h" #include "ierror.h" #include "ierrorstatus.h" #include "ifile.h" #include "iimagecomposer.h" #include "imath.h" #include "ishell.h" #include "ishellfactory.h" #include "isystem.h" #include "iviewmodule.h" #include "iviewobject.h" #include "iviewobjectfamily.h" #include #include #include #include #include #include #include using namespace iParameter; // // Templates // #include "iarraytemplate.h" #define REN this->GetViewModule()->GetRenderer() #define DATAREADER this->GetViewModule()->GetReader() #define CAM this->GetViewModule()->GetRenderer()->GetActiveCamera() #define XSECTION this->GetViewModule()->GetCrossSectionViewSubject() #define RAN_U (2.0*vtkMath::Random()-1.0) #define RAN_N (1.4142*tan(2.0*RAN_U/3.1415926)) #define LEN(x) (sqrt(x[0]*x[0]+x[1]*x[1]+x[2]*x[2])) IOBJECT_DEFINE_TYPE(iAnimator,Animator,a,iObjectType::_Helper); IOBJECT_DEFINE_KEY(iAnimator,Phi,dp,Float,1); IOBJECT_DEFINE_KEY(iAnimator,Roll,dr,Float,1); IOBJECT_DEFINE_KEY(iAnimator,Theta,dt,Float,1); IOBJECT_DEFINE_KEY(iAnimator,Zoom,dz,Float,1); IOBJECT_DEFINE_KEY(iAnimator,FlybySpeed,fs,Float,1); IOBJECT_DEFINE_KEY(iAnimator,LoadScriptFile,ls,String,1); IOBJECT_DEFINE_KEY(iAnimator,LogoFile,lf,String,1); IOBJECT_DEFINE_KEY(iAnimator,LogoLocation,ll,Int,1); IOBJECT_DEFINE_KEY(iAnimator,LogoOpacity,lo,Float,1); IOBJECT_DEFINE_KEY(iAnimator,NumberOfBlendedFrames,nb,Int,1); IOBJECT_DEFINE_KEY(iAnimator,NumberOfFrames,nf,Int,1); IOBJECT_DEFINE_KEY(iAnimator,NumberOfTransitionFrames,nt,Int,1); IOBJECT_DEFINE_KEY(iAnimator,Style,s,Int,1); IOBJECT_DEFINE_KEY(iAnimator,ScriptFile,sf,String,1); IOBJECT_DEFINE_KEY(iAnimator,NumberOfTitlePageBlendedFrames,tbf,Int,1); IOBJECT_DEFINE_KEY(iAnimator,TitlePageFile,tf,String,1); IOBJECT_DEFINE_KEY(iAnimator,NumberOfTitlePageFrames,tnf,Int,1); IOBJECT_DEFINE_KEY(iAnimator,CrossSectionSpeed,xs,Float,1); IOBJECT_DEFINE_KEY(iAnimator,DebugFlag,-df,Int,1); IOBJECT_DEFINE_KEY(iAnimator,Debugging,-dd,Bool,1); // need a bool key for GUI shell // // Special keys that contain pointers to internal data. They should never be packed/unpacked, // only used for internal communication. Is there a better design? // IOBJECT_DEFINE_KEY(iAnimator,LogoImage,-li,Any,0); IOBJECT_DEFINE_KEY(iAnimator,TitlePageImage,-ti,Any,0); // // iAnimator class // iAnimator* iAnimator::New(iViewModule *vm) { IERROR_ASSERT(vm); return new iAnimator(vm); // non-inheritable, so no need to use Object Factory } iAnimator::iAnimator(iViewModule *vm) : iObject("Animator"), mViewModule(vm) { mStarted = mStartedRender = mUsingScript = false; mDebugFlag = 0; // scriptFile = ""; (this is automatic with iString) mNewRec = false; mCurRec = mPrevRec = -1; mCurFrame = mTotFrame = 0; mState.mode = 1; mState.nframes = 1; mState.dphi = 1.0; mState.dtheta = 0.0; mState.dscale = 1.0; mState.droll = 0.0; mState.flybySpeed = 0.0; mState.slideSpeed = 0.0; mState.nBlendedFrames = 0; mState.nTransitionFrames = 0; mTitlePageNumFrames = 0; mTitlePageNumBlendedFrames = 0; mLogoOpacity = 0.5; mLogoLocation = 0; mRandStep = 0.03; mSeed = 12345; mAnimatorScript = iAnimatorScript::New(this); IERROR_ASSERT(mAnimatorScript); mAnimatorObserver = iAnimatorEventObserver::New(this->GetViewModule()); IERROR_ASSERT(mAnimatorObserver); mLeader = 0; } iAnimator::~iAnimator() { this->RemoveAllFollowers(); if(mLeader != 0) mLeader->RemoveFollower(this); mAnimatorObserver->Delete(); mAnimatorScript->Delete(); while(mBlenderBase.Size() > 0) delete mBlenderBase.RemoveLast(); } // // This is the main driver // void iAnimator::Animate() { this->Start(); while(this->Continue()); this->Stop(); } // // Start the animator // void iAnimator::Start() { this->GetErrorStatus()->Clear(); if(mStarted) { this->GetErrorStatus()->Set("Attempting to start an already started animation."); return; } // // Disactivate Progress Dialog // iAbortRenderEventObserver::BlockAbortRenderEventObservers(true); // // Are we using a script? // this->SaveState(); if(mUsingScript) { mState.mode = 0; mState.nframes = 1; mState.dphi = 0.0; mState.dtheta = 0.0; mState.dscale = 1.0; mState.droll = 0.0; mState.flybySpeed = 0.01; mState.slideSpeed = 0.0; mState.nBlendedFrames = 0; mState.nTransitionFrames = 0; this->ClearCache(); } else { mAnimatorScript->SetText("render -1"); } this->GetViewModule()->StartAnimation(); mAnimatorScript->StartExecute(); mStarted = true; this->ClearCache(); int i; for(i=0; iStart(); } // // Keep animating until stopped // bool iAnimator::Continue() { if(!mStarted) { this->GetErrorStatus()->Set("Attempting to continue a never started animation."); return false; } this->GetErrorStatus()->Monitor(mAnimatorScript->GetErrorStatus()); this->ClearCache(); return mAnimatorScript->ExecuteOneLine(); } // // Stop animation // void iAnimator::Stop() { int i; for(i=0; iStop(); if(!mStarted) { this->GetErrorStatus()->Set("Attempting to finish a never started animation."); return; } this->GetViewModule()->FinishAnimation(); mAnimatorScript->StopExecute(); // // Reset to initial state // mStartedRender = false; this->GetViewModule()->JustifyLabelLeft(false); // // Restore the original state after execution of a script - must do it after reset() // so that projection is Set properly in case it was changed in a script before the // first render // this->RestoreState(true); if(!mUsingScript) mAnimatorScript->SetText(""); // // Activate Progress Dialog // iAbortRenderEventObserver::BlockAbortRenderEventObservers(false); mStarted = false; this->ClearCache(); } void iAnimator::AddFollower(iAnimator *f) { if(f!=0 && f!=this) { mFollowers.AddUnique(f); f->SetLeader(this); } } void iAnimator::RemoveFollower(iAnimator *f) { if(f != 0) { mFollowers.Remove(f); f->SetLeader(0); } } void iAnimator::SetLeader(iAnimator *l) { if(l != this) { mLeader = l; } } void iAnimator::RemoveAllFollowers() { int i; for(i=0; iSetLeader(0); mFollowers.Clear(); } // // Internal functions // void iAnimator::SetDebugFlag(int s) { mDebugFlag = s; this->GetViewModule()->SetDebugMode(s > 1); this->ClearCache(); } void iAnimator::ResetCurrentFile() { mNewRec = true; mPrevRec = mCurRec; mCurRec = DATAREADER->GetRecordNumber(); mCurFrame = mTotFrame = 0; this->ClearCache(); } void iAnimator::SaveState() { if(XSECTION != 0) mState.xsecPos = XSECTION->GetLocation(); else mState.xsecPos = 0.0; mState.ifBoundingBox = this->GetViewModule()->IsBoundingBoxVisible(); mState.ifColorBars = this->GetViewModule()->IsColorBarsVisible(); mState.ifTimeLabel = this->GetViewModule()->IsLabelVisible(); if(DATAREADER != 0) mState.currec = this->GetViewModule()->GetReader()->GetRecordNumber(); mState.cameraProjection = CAM->GetParallelProjection(); CAM->GetPosition(mState.cameraPosition); CAM->GetFocalPoint(mState.cameraFocalPoint); CAM->GetViewUp(mState.cameraViewUp); mState.cameraParallelScale = CAM->GetParallelScale(); CAM->GetClippingRange(mState.cameraClippingRange); mState2 = mState; this->ClearCache(); } void iAnimator::RestoreState(bool with_camera) { mState = mState2; if(DATAREADER!=0 && mDebugFlag<2) { DATAREADER->LoadRecord(mState.currec,0,true); } if(XSECTION != 0) XSECTION->SetLocation(mState.xsecPos); this->GetViewModule()->ShowBoundingBox(mState.ifBoundingBox ); this->GetViewModule()->ShowColorBars(mState.ifColorBars); this->GetViewModule()->ShowLabel(mState.ifTimeLabel); if(with_camera) { CAM->SetParallelProjection(mState.cameraProjection); CAM->SetPosition(mState.cameraPosition); CAM->SetFocalPoint(mState.cameraFocalPoint); CAM->SetViewUp(mState.cameraViewUp); CAM->SetParallelScale(mState.cameraParallelScale); } this->ClearCache(); } void iAnimator::CopyState(iAnimator *anim) { // // Copy state but not camera // anim->SaveState(); mState2 = anim->mState; this->RestoreState(false); this->ClearCache(); } void iAnimator::SetStyle(int ma) { if(ma>=0 && ma<=3) { mState.mode = ma; this->ClearCache(); } } void iAnimator::SetNumberOfFrames(int na) { if(na > 0) { mState.nframes = na; this->ClearCache(); } } void iAnimator::SetPhi(float va) { mState.dphi = va; this->ClearCache(); } void iAnimator::SetTheta(float va) { mState.dtheta = va; this->ClearCache(); } void iAnimator::SetZoom(float va) { mState.dscale = va; this->ClearCache(); } void iAnimator::SetRoll(float va) { mState.droll = va; this->ClearCache(); } void iAnimator::SetCrossSectionSpeed(float va) { mState.slideSpeed = va; this->ClearCache(); } void iAnimator::SetFlybySpeed(float va) { mState.flybySpeed = va; this->ClearCache(); } void iAnimator::SetNumberOfBlendedFrames(int na) { if(na >= 0) { mState.nBlendedFrames = na; this->ClearCache(); } } void iAnimator::SetNumberOfTransitionFrames(int na) { if(na >= 0) { mState.nTransitionFrames = na; this->ClearCache(); } } void iAnimator::SetNumberOfTitlePageFrames(int n) { if(n >= 0) { mTitlePageNumFrames = n; this->ClearCache(); } } void iAnimator::SetNumberOfTitlePageBlendedFrames(int n) { if(n >= 0) { mTitlePageNumBlendedFrames = n; this->ClearCache(); } } void iAnimator::SetLogoLocation(int n) { if(n>0 && n<5) { mLogoLocation = n; this->ClearCache(); } } void iAnimator::SetLogoOpacity(float v) { mLogoOpacity = v; this->ClearCache(); } bool iAnimator::SetLogoFile(const iString &s) { this->ClearCache(); bool ok = mLogoImage.LoadFromFile(s); if(ok) mLogoFile = s; else { mLogoFile.Clear(); mLogoImage.Clear(); } return ok; } bool iAnimator::SetTitlePageFile(const iString &s) { this->ClearCache(); bool ok = mTitlePageImage.LoadFromFile(s); if(ok) mTitlePageFile = s; else { mTitlePageFile.Clear(); mTitlePageImage.Clear(); } return ok; } bool iAnimator::SetScriptFile(const iString &name) { iString fname(name), text; mUsingScript = false; if(!name.IsEmpty()) { iDirectory::ExpandFileName(fname,this->GetViewModule()->GetControlModule()->GetShell()->GetEnvironment(Environment::Script)); iFile f(fname); if(!f.Open(iFile::_Read,iFile::_Text)) { this->GetErrorStatus()->Set("Animation script file is not found."); return false; } iString st, tmp; while(f.ReadLine(tmp)) text += tmp + "\n"; if(text.IsEmpty()) { this->GetErrorStatus()->Set("Animation script file is empty or unreadable."); f.Close(); return false; } f.Close(); mUsingScript = true; } mAnimatorScript->SetText(text); mScriptFile = fname; this->ClearCache(); return true; } bool iAnimator::Frame(bool dumpImage) { static float Pi = 3.1415927; double xc[3], x0[3]; float v0[3], r0[3], r1[3], vA[3], vB[3]; int i; mNewRec = false; this->ClearCache(); this->GetErrorStatus()->Clear(); if(!mStartedRender) { if(!DATAREADER->IsFileAnimatable()) { this->GetErrorStatus()->Set("File is not animatable."); return false; } this->GetViewModule()->JustifyLabelLeft(true); vtkMath::RandomSeed(mSeed); if(mState.mode == 2) { wData.dphl0 = mState.dphi; wData.dthl0 = mState.dtheta; wData.r = 0.0; wData.ramp = RAN_N; } if(mState.mode == 3) { for(i=0; i<3; i++) { wData.xc1[i] = 0.5*RAN_U; wData.xc2[i] = 0.5*RAN_U; } CAM->SetParallelProjection(0); CAM->GetPosition(wData.x); if(mState.cameraProjection == 1) { for(i=0; i<3; i++) wData.x[i] = 0.5*wData.x[i]; CAM->SetPosition(wData.x); } else { CAM->GetFocalPoint(wData.xc1); } CAM->SetFocalPoint(wData.xc1); float d = LEN(wData.x); wData.v[0] = d*0.5*RAN_U; wData.v[1] = d*0.5*RAN_U; wData.v[2] = 0.0; wData.t = 0.0; wData.dt0 = 0.1*Pi; wData.dt = wData.dt0; } mCurFrame = mTotFrame = 0; mPrevRec = -1; mCurRec = DATAREADER->GetRecordNumber(); mStartedRender = true; } if(mCurFrame == mState.nframes) { this->GetErrorStatus()->Monitor(DATAREADER->GetErrorStatus()); iProgressEventObserver *obs = DATAREADER->GetProgressEventObserver(DATAREADER->GetFileSetDataType()); if(obs != 0) obs->AttachScript(mAnimatorScript); DATAREADER->LoadRecord(-1,1,mDebugFlag>1); if(obs != 0) obs->AttachScript(0); if(this->GetErrorStatus()->IsError()) { if(this->GetErrorStatus()->Level()==10) { this->GetErrorStatus()->Clear(); if(mUsingScript) { this->GetErrorStatus()->Set("Not enough data files to complete the script.",-1); } } return false; } this->GetViewModule()->UpdateLabel(); mNewRec = true; mPrevRec = mCurRec; mCurRec = DATAREADER->GetRecordNumber(); mCurFrame = 0; } if(this->GetErrorStatus()->IsError()) { return false; } mCurFrame++; mTotFrame++; if(fabs(mState.slideSpeed)>1.0e-30 && XSECTION!=0) { double p = XSECTION->GetLocation(); p = p + mState.slideSpeed; XSECTION->SetLocation(p); if(XSECTION->GetOverTheEdgeFlag()) mState.slideSpeed = -mState.slideSpeed; } // // Add transformations for rotate & tumble // if(mState.mode==1 || mState.mode==2) { CAM->Azimuth(-mState.dphi); CAM->Elevation(-mState.dtheta); CAM->Zoom(mState.dscale); CAM->Roll(mState.droll); CAM->OrthogonalizeViewUp(); if(mState.mode == 2) { wData.r = wData.r + mRandStep; float cr = cos(wData.r*wData.ramp); float sr = sin(wData.r*wData.ramp); mState.dphi = wData.dphl0*cr + wData.dthl0*sr; mState.dtheta = wData.dthl0*cr - wData.dphl0*sr; if(wData.r > 1.0) { wData.r = 0.0; wData.ramp = RAN_N; wData.dphl0 = mState.dphi; wData.dthl0 = mState.dtheta; } } } // // Add transformations for flyby // if(mState.mode == 3) { for(i=0; i<3; i++) { xc[i] = wData.xc1[i] + (wData.xc2[i]-wData.xc1[i])*wData.t; x0[i] = wData.x[i]; v0[i] = wData.v[i]; } CAM->SetFocalPoint(xc); wData.dt *= 2; float d0, d1, cot, sot; do { wData.dt *= 0.5; for(i=0; i<3; i++) { r0[i] = x0[i] - xc[i]; vA[i] = r0[i]; vB[i] = v0[i]; } cot = cos(wData.dt); sot = sin(wData.dt); for(i=0; i<3; i++) r1[i] = vA[i]*cot + vB[i]*sot - r0[i]; d0 = d1 = 0.0; for(i=0; i<3; i++) { d0 = d0 + r0[i]*r0[i]; d1 = d1 + r1[i]*r1[i]; } d1 = sqrt(d1/d0); } while(d1>mState.flybySpeed && wData.dt>0.001*wData.dt0); if(d1 < 0.2*mState.flybySpeed) wData.dt = 1.5*wData.dt; for(i=0; i<3; i++) { wData.v[i] = vB[i]*cot-vA[i]*sot; wData.x[i] = r0[i] + r1[i] + xc[i]; } CAM->SetPosition(wData.x); CAM->OrthogonalizeViewUp(); wData.t = wData.t + wData.dt; if(wData.t > 1.0) { wData.t = 0.0; for(i=0; i<3; i++) { wData.xc1[i] = wData.xc2[i]; wData.xc2[i] = 0.5*RAN_U; } } } // // Image data holder // iStereoImageArray images; // // Create the primary image set // this->GetErrorStatus()->Monitor(this->GetViewModule()->GetErrorStatus(),true); this->GetViewModule()->CreateImages(images); if(this->GetErrorStatus()->IsError()) return false; // // Title page // if(mTotFrame==1 && dumpImage && !mTitlePageImage.IsEmpty() && mDebugFlag==0) { iImage tmp = mTitlePageImage; // // We must update composer here because there is no automatic way to call // composer->Update() when vtkRenderWindow changes its size (it does not invoke an event). // this->GetViewModule()->GetControlModule()->GetImageComposer()->Update(); tmp.Scale(this->GetViewModule()->GetFullImageWidth(),this->GetViewModule()->GetFullImageHeight()); iStereoImageArray tmpset; tmpset.Copy(images); int n; for(n=0; nDumpImages(tmpset); if(this->GetErrorStatus()->IsError()) return false; } for(n=0; nDumpImages(tmpset); if(this->GetErrorStatus()->IsError()) return false; } } // // Transition effects // bool doTransitionFrames = dumpImage && mTotFrame>0 && mPrevRec>0 && mCurFrame<=mState.nTransitionFrames && mState.nTransitionFrames>0 && mDebugFlag==0; if(doTransitionFrames) { iStereoImageArray tmpset; // // Objects for transition effects (blending with previous record) // this->GetErrorStatus()->Monitor(DATAREADER->GetErrorStatus(),true); DATAREADER->LoadRecord(mPrevRec,0,false); if(this->GetErrorStatus()->IsError()) return false; this->GetViewModule()->UpdateLabel(); this->GetErrorStatus()->Monitor(this->GetViewModule()->GetErrorStatus(),true); this->GetViewModule()->CreateImages(tmpset); if(this->GetErrorStatus()->IsError()) return false; float ops = (float)mCurFrame/mState.nTransitionFrames; this->GetErrorStatus()->Monitor(DATAREADER->GetErrorStatus(),true); DATAREADER->LoadRecord(mCurRec,0,false); if(this->GetErrorStatus()->IsError()) return false; } // // Blending of images // bool doBlendedFrames = dumpImage && mTotFrame >0 && mState.nBlendedFrames>0 && mDebugFlag==0; if(doBlendedFrames) { int k; // // Update the image list // while(mBlenderBase.Size() < mState.nBlendedFrames) { iStereoImageArray *ptmparr = new iStereoImageArray; IERROR_ASSERT(ptmparr); ptmparr->Copy(images); mBlenderBase.Add(ptmparr); } while(mBlenderBase.Size() > mState.nBlendedFrames) { delete mBlenderBase.RemoveLast(); } delete mBlenderBase[0]; for(k=0; kCopy(*mBlenderBase[k+1]); mBlenderBase.Last()->Copy(images); // // Make sure that all the arrays are of the same size // for(k=0; kSize() > images.Size()) mBlenderBase[k]->RemoveLast(); while(mBlenderBase[k]->Size() < images.Size()) mBlenderBase[k]->Add(images[mBlenderBase[k]->Size()]); } // // Blend the arrays // int n = 1; float ops; images.Copy(*mBlenderBase[0]); for(k=1; kGetErrorStatus()->Monitor(mFollowers[i]->GetErrorStatus(),true,"Follower Animator from window #"+iString::FromNumber(1+mFollowers[i]->GetViewModule()->GetWindowNumber())); if(!mFollowers[i]->Frame(false)) break; } if(mDebugFlag==0 && dumpImage) { this->DumpImages(images); } return this->GetErrorStatus()->NoError(); } // // Dump an image array, optionally adding a logo // void iAnimator::DumpImages(iStereoImageArray &images) { if(images.Size()>0 && mDebugFlag==0 && !mLogoImage.IsEmpty()) { // // If the logo is more than 20% of the image, scale it down. // Use tmp as a temp storage // iImage tmp = mLogoImage; if(tmp.Width()>images[0].Width()/5 || tmp.Height()>images[0].Height()/5) { tmp.Scale(images[0].Width()/5,images[0].Height()/5); } if(tmp.Width()>=2 && tmp.Height()>=2) { // // tmp is now the proper logo image // int i, ioff, joff; // // Where do we place the logo? // ioff = tmp.Width()/5; joff = tmp.Height()/5; switch(mLogoLocation) { case 1: { // upper right corner ioff = images[0].Width() - tmp.Width() - ioff; joff = images[0].Height() - tmp.Height() - joff; break; } case 2: { // lower left right corner break; } case 3: { // lower right corner ioff = images[0].Width() - tmp.Width() - ioff; break; } default: { // upper left corner - the default choice joff = images[0].Height() - tmp.Height() - joff; break; } } for(i=0; iGetErrorStatus()->Monitor(this->GetViewModule()->GetErrorStatus(),true); this->GetViewModule()->DumpImages(images,ImageType::AnimationFrame); } // // Two functions used in saving/restoring the state and in creating new instances with // void iAnimator::PackStateBody(iString &s) const { this->PackValue(s,KeyDebugFlag(),mDebugFlag); this->PackValue(s,KeyDebugging(),mDebugFlag!=0); this->PackValue(s,KeyScriptFile(),mScriptFile); this->PackValue(s,KeyStyle(),mState.mode); this->PackValue(s,KeyNumberOfFrames(),mState.nframes); this->PackValue(s,KeyNumberOfBlendedFrames(),mState.nBlendedFrames); this->PackValue(s,KeyNumberOfTransitionFrames(),mState.nTransitionFrames); this->PackValue(s,KeyPhi(),mState.dphi); this->PackValue(s,KeyTheta(),mState.dtheta); this->PackValue(s,KeyRoll(),mState.droll); this->PackValue(s,KeyZoom(),mState.dscale); this->PackValue(s,KeyCrossSectionSpeed(),mState.slideSpeed); this->PackValue(s,KeyFlybySpeed(),mState.flybySpeed); this->PackValue(s,KeyTitlePageFile(),mTitlePageFile); this->PackValue(s,KeyNumberOfTitlePageFrames(),mTitlePageNumFrames); this->PackValue(s,KeyNumberOfTitlePageBlendedFrames(),mTitlePageNumBlendedFrames); this->PackValue(s,KeyLogoFile(),mLogoFile); this->PackValue(s,KeyLogoOpacity(),mLogoOpacity); this->PackValue(s,KeyLogoLocation(),mLogoLocation); } void iAnimator::UnPackStateBody(const iString &s) { int i; float f; iString ss; if(this->UnPackValue(s,KeyDebugFlag(),i)) this->SetDebugFlag(i); if(this->UnPackValue(s,KeyNumberOfFrames(),i)) this->SetNumberOfFrames(i); if(this->UnPackValue(s,KeyNumberOfBlendedFrames(),i)) this->SetNumberOfBlendedFrames(i); if(this->UnPackValue(s,KeyNumberOfTransitionFrames(),i)) this->SetNumberOfTransitionFrames(i); if(this->UnPackValue(s,KeyPhi(),f)) this->SetPhi(f); if(this->UnPackValue(s,KeyTheta(),f)) this->SetTheta(f); if(this->UnPackValue(s,KeyRoll(),f)) this->SetRoll(f); if(this->UnPackValue(s,KeyZoom(),f)) this->SetZoom(f); if(this->UnPackValue(s,KeyCrossSectionSpeed(),f)) this->SetCrossSectionSpeed(f); if(this->UnPackValue(s,KeyFlybySpeed(),f)) this->SetFlybySpeed(f); if(this->UnPackValue(s,KeyScriptFile(),ss)) this->SetScriptFile(ss); if(this->UnPackValue(s,KeyTitlePageFile(),ss)) this->SetTitlePageFile(ss); if(this->UnPackValue(s,KeyNumberOfTitlePageFrames(),i)) this->SetNumberOfTitlePageFrames(i); if(this->UnPackValue(s,KeyNumberOfTitlePageBlendedFrames(),i)) this->SetNumberOfTitlePageBlendedFrames(i); if(this->UnPackValue(s,KeyLogoFile(),ss)) this->SetLogoFile(ss); if(this->UnPackValue(s,KeyLogoOpacity(),f)) this->SetLogoOpacity(f); if(this->UnPackValue(s,KeyLogoLocation(),i)) this->SetLogoLocation(i); if(this->UnPackValue(s,KeyStyle(),i)) this->SetStyle(i); // // Action keys // iObject::ReportMissingKeys(false); //action keys are not part of the states if(this->UnPackValue(s,KeyLoadScriptFile(),ss)) this->SetScriptFile(ss); iObject::ReportMissingKeys(true); } ifrit-3.4.2/core/ianimator.h0000755000175700010010000001627312167404405014305 0ustar HomeNone/*========================================================================= Program: Ionization FRont Interactive Tool (IFRIT) Language: C++ Copyright (c) 2002-2012 Nick Gnedin All rights reserved. This file may be distributed and/or modified under the terms of the GNU General Public License version 2 as published by the Free Software Foundation and appearing in the file LICENSE.GPL included in the packaging of this file. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHORS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. =========================================================================*/ #ifndef IANIMATOR_H #define IANIMATOR_H #include "iobject.h" #include "iarray.h" #include "imath.h" #include "iimage.h" class iAnimatorEventObserver; class iAnimatorScript; class iStereoImageArray; class vtkImageData; class vtkPolyData; struct iAnimatorState { int mode; int nframes; int nBlendedFrames; int nTransitionFrames; float dphi; float dtheta; float dscale; float droll; float slideSpeed; float flybySpeed; double xsecPos; bool ifBoundingBox; bool ifColorBars; bool ifTimeLabel; int currec; int cameraProjection; double cameraPosition[3]; double cameraFocalPoint[3]; double cameraViewUp[3]; double cameraParallelScale; double cameraClippingRange[2]; }; class iAnimator : public iObject { friend class iAnimatorScript; IPOINTER_AS_PART(ViewModule); public: vtkTypeMacro(iAnimator,iObject); static iAnimator* New(iViewModule *vm = 0); static const iObjectType& Type(); IOBJECT_DECLARE_GETSET(Style,mState.mode,int); //virtual void SetStyle(int ma); //inline int GetStyle() const { return mState.mode; } IOBJECT_DECLARE_GETSET(NumberOfFrames,mState.nframes,int); //virtual void SetNumberOfFrames(int na); //inline int GetNumberOfFrames() const { return mState.nframes; } IOBJECT_DECLARE_GETSET(Phi,mState.dphi,float); //virtual void SetPhi(float va); //inline float GetPhi() const { return mState.dphi; } IOBJECT_DECLARE_GETSET(Theta,mState.dtheta,float); //virtual void SetTheta(float va); //inline float GetTheta() const { return mState.dtheta; } IOBJECT_DECLARE_GETSET(Zoom,mState.dscale,float); //virtual void SetZoom(float va); //inline float GetZoom() const { return mState.dscale; } IOBJECT_DECLARE_GETSET(Roll,mState.droll,float); //virtual void SetRoll(float va); //inline float GetRoll() const { return mState.droll; } IOBJECT_DECLARE_GETSET(FlybySpeed,mState.flybySpeed,float); //virtual void SetFlybySpeed(float va); //inline float GetFlybySpeed() const { return mState.flybySpeed; } IOBJECT_DECLARE_GETSET(NumberOfBlendedFrames,mState.nBlendedFrames,int); //virtual void SetNumberOfBlendedFrames(int na); //inline int GetNumberOfBlendedFrames() const { return mState.nBlendedFrames; } IOBJECT_DECLARE_GETSET(NumberOfTransitionFrames,mState.nTransitionFrames,int); //virtual void SetNumberOfTransitionFrames(int na); //inline int GetNumberOfTransitionFrames() const { return mState.nTransitionFrames; } IOBJECT_DECLARE_GETSET1(DebugFlag,int); //virtual void SetDebugFlag(int s); //inline int GetDebugFlag() const { retun mDebugFlag; } static const iObjectKey& KeyDebugging(); bool SetScriptFile(const iString &fname); IOBJECT_DECLARE_GET1(ScriptFile,const iString&); //virtual void SetScriptFileName(const iString &s); //inline const String& GetScriptFile() const { return mScriptFile; } static const iObjectKey& KeyLoadScriptFile(); bool SetTitlePageFile(const iString &fname); IOBJECT_DECLARE_GET1(TitlePageFile,const iString&); //inline const iString& GetTitlePageFile() const { return mTitlePageFile; } bool SetLogoFile(const iString &fname); IOBJECT_DECLARE_GET1(LogoFile,const iString&); //inline const iString& GetLogoFile() const { return mLogoFile; } IOBJECT_DECLARE_GETSET(NumberOfTitlePageFrames,mTitlePageNumFrames,int); //virtual void SetNumberOfTitlePageFrames(int n); //inline int GetNumberOfTitlePageFrames() const { return mTitlePageNumFrames; } IOBJECT_DECLARE_GETSET(NumberOfTitlePageBlendedFrames,mTitlePageNumBlendedFrames,int); //virtual void SetNumberOfTitlePageBlendedFrames(int n); //inline int GetNumberOfTitlePageBlendedFrames() const { return mTitlePageNumBlendedFrames; } IOBJECT_DECLARE_GETSET1(LogoLocation,int); //virtual void SetLogoLocation(int n); //inline int GetLogoLocation() const { return mLogoLocation; } IOBJECT_DECLARE_GETSET1(LogoOpacity,float); //virtual void SetLogoOpacity(float v); //inline float GetLogoOpacity() const { return mLogoOpacity; } inline const iImage& GetTitlePageImage() const { return mTitlePageImage; } static const iObjectKey& KeyTitlePageImage(); inline const iImage& GetLogoImage() const { return mLogoImage; } static const iObjectKey& KeyLogoImage(); virtual void SetCrossSectionSpeed(float va); inline float GetCrossSectionSpeed() const { return (float)fabs(mState.slideSpeed); } static const iObjectKey& KeyCrossSectionSpeed(); inline bool UsingScript() const { return mUsingScript; } // // Animator controls // void Animate(); virtual void Start(); virtual void Stop(); virtual bool Continue(); void AddFollower(iAnimator *f); void RemoveFollower(iAnimator *f); void RemoveAllFollowers(); inline iAnimatorEventObserver* GetObserver() const { return mAnimatorObserver; } inline iAnimatorScript* GetScript() const { return mAnimatorScript; } inline void GetInfo(bool &nr, int &cr, int &cf) const { nr = mNewRec; cr = mCurRec; cf = mCurFrame; } virtual void CopyState(iAnimator *other); protected: virtual ~iAnimator(); virtual void PackStateBody(iString &s) const; virtual void UnPackStateBody(const iString &s); private: iAnimator(iViewModule *vm); void SetLeader(iAnimator *l); bool Frame(bool dumpImage = true); void DumpImages(iStereoImageArray &images); void ResetCurrentFile(); void SaveState(); void RestoreState(bool with_camera); bool mStarted, mStartedRender, mUsingScript; unsigned long mSeed; int mDebugFlag; iString mScriptFile; iAnimatorState mState; iAnimatorState mState2; float mRandStep; bool mNewRec; int mPrevRec, mCurRec, mTotFrame, mCurFrame; iArray mBlenderBase; iString mTitlePageFile, mLogoFile; iImage mTitlePageImage, mLogoImage; int mTitlePageNumBlendedFrames, mTitlePageNumFrames, mLogoLocation; float mLogoOpacity; iAnimatorScript *mAnimatorScript; iAnimatorEventObserver *mAnimatorObserver; iSearchableArray mFollowers; iAnimator *mLeader; // // Internal (work) variables // struct AnimatorData { double pos[3]; float r, dphl0, dthl0, ramp; double xc1[3], xc2[3], x[3]; float v[3], t, dt0, dt; } wData; }; #endif // IANIMATOR_H ifrit-3.4.2/core/ianimatorscript.cpp0000755000175700010010000005333612167404424016067 0ustar HomeNone/*========================================================================= Program: Ionization FRont Interactive Tool (IFRIT) Language: C++ Copyright (c) 2002-2012 Nick Gnedin All rights reserved. This file may be distributed and/or modified under the terms of the GNU General Public License version 2 as published by the Free Software Foundation and appearing in the file LICENSE.GPL included in the packaging of this file. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHORS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. =========================================================================*/ #include "ianimatorscript.h" #include "ianimator.h" #include "icamera.h" #include "icontrolmodule.h" #include "icontrolscript.h" #include "icrosssectionviewsubject.h" #include "idatareader.h" #include "idirectory.h" #include "ierror.h" #include "ierrorstatus.h" #include "iextensionfactory.h" #include "ifile.h" #include "irendertool.h" #include "iscriptkit.h" #include "ishell.h" #include "ishellfactory.h" #include "isurfaceviewsubject.h" #include "iviewmodule.h" #include "iviewobject.h" #include "iviewobjectfamily.h" #include #include #include // // Templates (needed for some compilers) // #include "iarraytemplate.h" #include "icalculatortemplate.h" #include "iscriptkittemplate.h" #include "iviewfamilytemplate.h" // // macros // #include "ianimatorscriptmacro.h" using namespace iParameter; #define curScript iRequiredCast(INFO,self) namespace iAnimatorScript_Private { DEFINE_WORKER_REL(Animator,NumberOfFrames,int); DEFINE_WORKER_REL(Animator,NumberOfBlendedFrames,int); DEFINE_WORKER_REL(Animator,NumberOfTransitionFrames,int); DEFINE_WORKER_REL(Animator,FlybySpeed,float); DEFINE_WORKER_REL(Animator,Phi,float); DEFINE_WORKER_REL(Animator,Theta,float); DEFINE_WORKER_REL(Animator,Roll,float); DEFINE_WORKER_REL(Animator,Zoom,float); DEFINE_WORKER_REL(Animator,CrossSectionSpeed,float); DEFINE_WORKER_REL(Animator,LogoOpacity,float); DEFINE_WORKER_ABS(Animator,SetStyle,int); DEFINE_WORKER_ABS(Animator,SetNumberOfTitlePageFrames,int); DEFINE_WORKER_ABS(Animator,SetNumberOfTitlePageBlendedFrames,int); DEFINE_WORKER_ABS(Animator,SetLogoLocation,int); DEFINE_WORKER_ABS(Camera,SetParallelScale,double); DEFINE_WORKER_ABS(Camera,SetParallelProjection,bool); DEFINE_WORKER_ABS(Visual,ShowLabel,bool); DEFINE_WORKER_ABS(Visual,ShowColorBars,bool); DEFINE_WORKER_ABS(Visual,ShowBoundingBox,bool); DEFINE_WORKER_ABSPTR(Visual,UpdateLabel,float); DEFINE_WORKER_ABS_FILE(Animator,SetTitlePageFile,"Unable to load title page image."); DEFINE_WORKER_ABS_FILE(Animator,SetLogoFile,"Unable to load logo image."); // // Object showing/hiding functions - for batch operations // DEFINE_WORKER_SHOW(Surface); DEFINE_WORKER_SHOW(CrossSection); DEFINE_WORKER_SHOW(Volume); DEFINE_WORKER_SHOW(Particles); DEFINE_WORKER_SHOW(VectorField); DEFINE_WORKER_SHOW(TensorField); #ifdef ISCRIPT_BACKWARD_COMPATIBLE // DEFINE_WORKER_LIMIT(iUniformScalars,LowerLimit); // DEFINE_WORKER_LIMIT(iUniformScalars,UpperLimit); // DEFINE_WORKER_LIMIT(iBasicParticles,LowerLimit); // DEFINE_WORKER_LIMIT(iBasicParticles,UpperLimit); // DEFINE_WORKER_LIMIT(iUniformVectors,UpperLimit); // DEFINE_WORKER_LIMIT(iUniformTensors,UpperLimit); DEFINE_WORKER_SUBJECT_BEGIN(Surface,IsoSurfaceLevel,float,true); sub->SetIsoSurfaceLevel(val); DEFINE_WORKER_SUBJECT_END; DEFINE_WORKER_SUBJECT_BEGIN(CrossSection,Location,double,true); sub->SetLocation(val); DEFINE_WORKER_SUBJECT_END; #endif // // focal point & camera location // bool CameraSetFocalPoint(iScript *self, short at, int num, const double *value, int index) { VECTOR_HELPER_ASSERT(3); double p[3]; curCamera->GetFocalPoint(p); VECTOR_HELPER_ASSIGN(3,double); curCamera->SetFocalPoint(p); curCamera->OrthogonalizeViewUp(); return true; } bool CameraSetPosition(iScript *self, short at, int num, const double *value, int index) { VECTOR_HELPER_ASSERT(3); double p[3]; curCamera->GetPosition(p); VECTOR_HELPER_ASSIGN(3,double); curCamera->SetPosition(p); curCamera->OrthogonalizeViewUp(); return true; } bool CameraSetViewUp(iScript *self, short at, int num, const double *value, int index) { VECTOR_HELPER_ASSERT(3); double p[3]; curCamera->GetViewUp(p); VECTOR_HELPER_ASSIGN(3,double); double *dop = curCamera->GetDirectionOfProjection(); double c[3]; vtkMath::Cross(dop,p,c); if(vtkMath::Norm(p)>1.0e-8 && vtkMath::Norm(c)>1.0e-8) { curCamera->SetViewUp(p); curCamera->OrthogonalizeViewUp(); return true; } else { self->GetErrorStatus()->Set("The ViewUp vector cannot coincide with the direction of projection."); return false; } } }; using namespace iAnimatorScript_Private; iAnimatorScript* iAnimatorScript::New(iAnimator *an) { IERROR_ASSERT(an); return new iAnimatorScript(an); } iAnimatorScript::iAnimatorScript(iAnimator *an) : iBasicScript(an->GetViewModule()->GetControlModule()->GetControlScript()) // always embedded { mEmbeddedControlScript = iShellFactory::CreateControlScript(an->GetViewModule()->GetControlModule(),this); mAnimator = an; mInRender = false; // // Alias words (mostly for backward compatibility) // this->CreateAliasWord("camera-scale","camera-parallel-scale"); this->CreateAliasWord("frames-per-file","number-of-frames"); this->CreateAliasWord("blended-frames","number-of-blended-frames"); this->CreateAliasWord("transition-frames","number-of-transition-frames"); #ifdef ISCRIPT_BACKWARD_COMPATIBLE this->CreateAliasWord("x-section-speed","cross-section-speed"); this->CreateAliasWord("xsection-speed","cross-section-speed"); this->CreateAliasWord("fly-by-speed","flyby-speed"); this->CreateAliasWord("mesh-file","uniform-scalars-file"); this->CreateAliasWord("particle-file","basic-particles-file"); this->CreateAliasWord("vector-file","uniform-vectors-file"); this->CreateAliasWord("tensor-file","uniform-tensors-file"); this->CreateAliasWord("xsection","cross-section"); this->CreateAliasWord("vector","vector-field"); this->CreateAliasWord("tensor","tensor-field"); this->CreateAliasWord("mesh-variable-lower-limit","uniform-scalars-lower-limit"); this->CreateAliasWord("mesh-variable-upper-limit","uniform-scalars-upper-limit"); this->CreateAliasWord("particle-attribute-lower-limit","basic-particles-lower-limit"); this->CreateAliasWord("particle-attribute-upper-limit","basic-particles-upper-limit"); this->CreateAliasWord("vector-upper-limit","uniform-vectors-upper-limit"); this->CreateAliasWord("tensor-upper-limit","uniform-tensors-upper-limit"); this->CreateAliasWord("scalar-field-lower-limit","uniform-scalars-lower-limit"); this->CreateAliasWord("scalar-field-upper-limit","uniform-scalars-upper-limit"); this->CreateAliasWord("particle-set-lower-limit","basic-particles-lower-limit"); this->CreateAliasWord("particle-set-upper-limit","basic-particles-upper-limit"); this->CreateAliasWord("vector-field-upper-limit","uniform-vectors-upper-limit"); this->CreateAliasWord("tensor-field-upper-limit","uniform-tensors-upper-limit"); this->CreateAliasWord("xsection-var","cross-section-var"); this->CreateAliasWord("xsection-dir","cross-section-dir"); this->CreateAliasWord("xsection-position","cross-section-position"); this->CreateAliasWord("rotate-scale","rotate"); this->CreateAliasWord("scale","zoom"); this->CreateAliasWord("fly-by","flyby"); this->CreateAliasWord("camera-path","camerapath"); this->CreateAliasWord("upper-left-corner","ulcorner"); this->CreateAliasWord("upper-right-corner","urcorner"); this->CreateAliasWord("lower-left-corner","llcorner"); this->CreateAliasWord("lower-right-corner","lrcorner"); this->CreateAliasWord("logo-position","logo-location"); #endif // // Parameter words // this->AddConstant(new iScriptKit::Constant(this,"static",0)); this->AddConstant(new iScriptKit::Constant(this,"rotate",1)); this->AddConstant(new iScriptKit::Constant(this,"tumble",2)); this->AddConstant(new iScriptKit::Constant(this,"flyby",3)); this->AddConstant(new iScriptKit::Constant(this,"path",4)); this->AddConstant(new iScriptKit::Constant(this,"next",-1)); this->AddConstant(new iScriptKit::Constant(this,"parallel",true)); this->AddConstant(new iScriptKit::Constant(this,"perspective",false)); this->AddConstant(new iScriptKit::Constant(this,"hidden",false)); this->AddConstant(new iScriptKit::Constant(this,"visible",true)); this->AddConstant(new iScriptKit::Constant(this,"current",iMath::_LargeInt+1)); this->AddConstant(new iScriptKit::Constant(this,"ulcorner",0)); this->AddConstant(new iScriptKit::Constant(this,"urcorner",1)); this->AddConstant(new iScriptKit::Constant(this,"llcorner",2)); this->AddConstant(new iScriptKit::Constant(this,"lrcorner",3)); this->AddConstant(new iScriptKit::Constant(this,"off",false)); this->AddConstant(new iScriptKit::Constant(this,"on",true)); // // Command words // // // Assignment operations hidden as statements // this->AddPrototype< iScriptKit::FunctionCallAssignmentStatement >("render",Render); this->AddPrototype< iScriptKit::FunctionCallAssignmentStatement >("render-all",RenderAll); this->AddPrototype< iScriptKit::FunctionCallAssignmentStatement >("render-set",RenderSet); this->AddPrototype< iScriptKit::FunctionCallAssignmentStatement >("load",Load); this->AddPrototype< iScriptKit::FunctionCallStatement >("execute control-script",ExecuteControlScript); this->AddPrototype< iScriptKit::FunctionCallStatement >("embed control-script",EmbedControlScript); // // Genuine assignment operations to pre-defined variables // this->AddPrototype< iScriptKit::FunctionCallAssignmentStatement >("style",AnimatorSetStyle); this->AddPrototype< iScriptKit::FunctionCallAssignmentStatement >("number-of-frames",AnimatorSetNumberOfFrames); this->AddPrototype< iScriptKit::FunctionCallAssignmentStatement >("number-of-blended-frames",AnimatorSetNumberOfBlendedFrames); this->AddPrototype< iScriptKit::FunctionCallAssignmentStatement >("number-of-transition-frames",AnimatorSetNumberOfTransitionFrames); this->AddPrototype< iScriptKit::FunctionCallAssignmentStatement >("flyby-speed",AnimatorSetFlybySpeed); this->AddPrototype< iScriptKit::FunctionCallAssignmentStatement >("rotation-phi",AnimatorSetPhi); this->AddPrototype< iScriptKit::FunctionCallAssignmentStatement >("rotation-theta",AnimatorSetTheta); this->AddPrototype< iScriptKit::FunctionCallAssignmentStatement >("rotation-roll",AnimatorSetRoll); this->AddPrototype< iScriptKit::FunctionCallAssignmentStatement >("zoom",AnimatorSetZoom); this->AddPrototype< iScriptKit::FunctionCallAssignmentStatement >("cross-section-speed",AnimatorSetCrossSectionSpeed); this->AddPrototype< iScriptKit::FunctionCallAssignmentStatement >("camera-parallel-scale",CameraSetParallelScale); this->AddPrototype< iScriptKit::FunctionCallAssignmentStatement >("camera-view-up",CameraSetViewUp); this->AddPrototype< iScriptKit::FunctionCallAssignmentStatement >("camera-focal-point",CameraSetFocalPoint); this->AddPrototype< iScriptKit::FunctionCallAssignmentStatement >("camera-position",CameraSetPosition); this->AddPrototype< iScriptKit::FunctionCallAssignmentStatement >("projection",CameraSetParallelProjection); this->AddPrototype< iScriptKit::FunctionCallAssignmentStatement >("record-label",VisualShowLabel); this->AddPrototype< iScriptKit::FunctionCallAssignmentStatement >("color-bars",VisualShowColorBars); this->AddPrototype< iScriptKit::FunctionCallAssignmentStatement >("bounding-box",VisualShowBoundingBox); this->AddPrototype< iScriptKit::FunctionCallAssignmentStatement >("record-label-value",VisualUpdateLabel); this->AddPrototype< iScriptKit::FunctionCallStatement >("title-page-file",AnimatorSetTitlePageFile); this->AddPrototype< iScriptKit::FunctionCallStatement >("logo-file",AnimatorSetLogoFile); this->AddPrototype< iScriptKit::FunctionCallAssignmentStatement >("title-page-number-of-frames",AnimatorSetNumberOfTitlePageFrames); this->AddPrototype< iScriptKit::FunctionCallAssignmentStatement >("title-page-number-of-blended-frames",AnimatorSetNumberOfTitlePageBlendedFrames); this->AddPrototype< iScriptKit::FunctionCallAssignmentStatement >("logo-opacity",AnimatorSetLogoOpacity); this->AddPrototype< iScriptKit::FunctionCallAssignmentStatement >("logo-location",AnimatorSetLogoLocation); this->AddPrototype< iScriptKit::FunctionCallAssignmentStatement >("surface",SurfaceShow); this->AddPrototype< iScriptKit::FunctionCallAssignmentStatement >("cross-section",CrossSectionShow); this->AddPrototype< iScriptKit::FunctionCallAssignmentStatement >("volume",VolumeShow); this->AddPrototype< iScriptKit::FunctionCallAssignmentStatement >("particles",ParticlesShow); this->AddPrototype< iScriptKit::FunctionCallAssignmentStatement >("vector-field",VectorFieldShow); this->AddPrototype< iScriptKit::FunctionCallAssignmentStatement >("tensor-field",TensorFieldShow); this->AddPrototype< iScriptKit::FunctionCallAssignmentStatement >("surface-level",SurfaceIsoSurfaceLevel); this->AddPrototype< iScriptKit::FunctionCallAssignmentStatement >("cross-section-position",CrossSectionLocation); // // This is deprecated: use embed control-script instead // this->AddPrototype< iScriptKit::DeprecatedStatement >("load uniform-scalars-file","Use instead: 'embed control-script exec DataReader:LoadData/Data-UniformScalars/'."); this->AddPrototype< iScriptKit::DeprecatedStatement >("load basic-particles-file","Use instead: 'embed control-script exec DataReader:LoadData/Data-BasicParticles/'."); this->AddPrototype< iScriptKit::DeprecatedStatement >("load uniform-vectors-file","Use instead: 'embed control-script exec DataReader:LoadData/Data-UniformVectors/'."); this->AddPrototype< iScriptKit::DeprecatedStatement >("load uniform-tensors-file","Use instead: 'embed control-script exec DataReader:LoadData/Data-UniformTensors/'."); this->AddPrototype< iScriptKit::DeprecatedStatement >("uniform-scalars-lower-limit","Use instead: 'embed control-script exec Data-UniformScalars:LowerLimit[]/'."); this->AddPrototype< iScriptKit::DeprecatedStatement >("uniform-scalars-upper-limit","Use instead: 'embed control-script exec Data-UniformScalars:UpperLimit[]/'."); this->AddPrototype< iScriptKit::DeprecatedStatement >("basic-particles-lower-limit","Use instead: 'embed control-script exec Data-UniformScalars:LowerLimit[]/'."); this->AddPrototype< iScriptKit::DeprecatedStatement >("basic-particles-upper-limit","Use instead: 'embed control-script exec Data-UniformScalars:UpperLimit[]/'."); this->AddPrototype< iScriptKit::DeprecatedStatement >("uniform-vectors-upper-limit","Use instead: 'embed control-script exec Data-UniformScalars:UpperLimit[]/'."); this->AddPrototype< iScriptKit::DeprecatedStatement >("uniform-tensors-upper-limit","Use instead: 'embed control-script exec Data-UniformScalars:UpperLimit[]/'."); this->AddPrototype< iScriptKit::DeprecatedStatement >("surface-var","Use instead: 'embed control-script exec Surface:IsoSurfaceVar[]/'."); this->AddPrototype< iScriptKit::DeprecatedStatement >("surface-opacity","Use instead: 'embed control-script exec Surface:Opacity[]/'."); this->AddPrototype< iScriptKit::DeprecatedStatement >("cross-section-var","Use instead: 'embed control-script exec CrossSection:Var[]/'."); this->AddPrototype< iScriptKit::DeprecatedStatement >("cross-section-dir","Use instead: 'embed control-script exec CrossSection:Dir[]/'."); this->AddPrototype< iScriptKit::DeprecatedStatement >("volume-var","Use instead: 'embed control-script exec Volume:Var[]/'."); this->AddPrototype< iScriptKit::DeprecatedStatement >("particles-opacity","Use instead: 'embed control-script exec Particles:Opacity[]/'."); this->AddPrototype< iScriptKit::DeprecatedStatement >("marker-position","Use instead: 'embed control-script exec Marker:Position[]///'."); this->AddPrototype< iScriptKit::DeprecatedStatement >("marker-size","Use instead: 'embed control-script exec Marker:Size[]/'."); this->AddPrototype< iScriptKit::DeprecatedStatement >("marker-opacity","Use instead: 'embed control-script exec Marker:Opacity[]/'."); } iAnimatorScript::~iAnimatorScript() { mEmbeddedControlScript->Delete(); } bool iAnimatorScript::IsCommandWordLetter(char c) const { // // Also allow a dash in between // return (c=='-' || this->iBasicScript::IsCommandWordLetter(c)); } // // Render scene // bool iAnimatorScript::Render(iScript *self, short, int n) { int i; curScript->SetInRender(true); if(n == -1) n = iMath::_IntMax; self->GetErrorStatus()->Monitor(curAnimator->GetErrorStatus(),true); for(i=0; iCheckAbort(i,n,1) && self->GetErrorStatus()->NoError(); i++) { if(!curAnimator->Frame()) self->GetErrorStatus()->Set("Animation finished.",-1); } curScript->SetInRender(false); return self->GetErrorStatus()->NoError(); } bool iAnimatorScript::RenderAll(iScript *self, short, int n) { int i, k; curScript->SetInRender(true); for(i=0; iCheckAbort(i,n,1) && self->GetErrorStatus()->NoError(); i++) { for(k=0; !self->CheckAbort(k,curControl->GetNumberOfViewModules(),2) && self->GetErrorStatus()->NoError() && kGetNumberOfViewModules(); k++) if(k != curControl->GetCurrentViewModuleIndex()) { self->GetErrorStatus()->Monitor(curControl->GetViewModule(k)->GetAnimator()->GetErrorStatus(),true); // // Force other animators to continue, even if they are done // curControl->GetViewModule(k)->GetAnimator()->Frame(false); } if(self->GetErrorStatus()->NoError()) { self->GetErrorStatus()->Monitor(curAnimator->GetErrorStatus(),true); if(!curAnimator->Frame()) self->GetErrorStatus()->Set("Animation finished.",-1); } } curScript->SetInRender(false); return self->GetErrorStatus()->NoError(); } bool iAnimatorScript::RenderSet(iScript *self, short, int num, const int *v, int index) { VECTOR_HELPER_ASSERT(curControl->GetNumberOfViewModules()); if(index != -1) { self->GetErrorStatus()->Set("This statement does not accept a single-component assignment."); return false; } curScript->SetInRender(true); int i; for(i=0; self->GetErrorStatus()->NoError() && !self->CheckAbort(i,num,1) && i0 && v[i]<=curControl->GetNumberOfViewModules() && v[i]!=1+curControl->GetCurrentViewModuleIndex()) { self->GetErrorStatus()->Monitor(curControl->GetViewModule(v[i]-1)->GetAnimator()->GetErrorStatus(),true); curControl->GetViewModule(v[i]-1)->GetAnimator()->Frame(false); } for(i=0; self->GetErrorStatus()->NoError() && !self->CheckAbort(i,num,1) && iGetCurrentViewModuleIndex()) { self->GetErrorStatus()->Monitor(curAnimator->GetErrorStatus(),true); if(!curAnimator->Frame()) self->GetErrorStatus()->Set("Animation finished.",-1); break; } curScript->SetInRender(false); return self->GetErrorStatus()->NoError(); } // // Embed control script // bool iAnimatorScript::ExecuteControlScript(iScript *self, const iString& filename) { if(filename.IsEmpty()) { self->GetErrorStatus()->Set("A name of a file with the Control Script must be specified."); return false; } iString fname(filename); iDirectory::ExpandFileName(fname,curControl->GetShell()->GetEnvironment(Environment::Base)); iFile f(fname); if(!f.Open(iFile::_Read,iFile::_Text)) { self->GetErrorStatus()->Set("Control script file is not found."); return false; } iString st, tmp; while(f.ReadLine(tmp)) st += tmp + "\n"; if(st.IsEmpty()) { self->GetErrorStatus()->Set("Control script file is empty or unreadable."); return false; } f.Close(); self->GetErrorStatus()->Monitor(curScript->mEmbeddedControlScript->GetErrorStatus(),true,"Control script: "); curScript->mEmbeddedControlScript->SetText(st); curScript->mEmbeddedControlScript->Execute(true); // do not reset the script!!! return self->GetErrorStatus()->NoError(); } bool iAnimatorScript::EmbedControlScript(iScript *self, const iString &value) { if(curScript->mEmbeddedControlScript == 0) { self->GetErrorStatus()->Set("This script does not support embedding."); return false; } // // Replace %% with \n // iString text(value); text.Replace("%%","\n"); self->GetErrorStatus()->Monitor(curScript->mEmbeddedControlScript->GetErrorStatus(),true,"Control script: "); curScript->mEmbeddedControlScript->SetText(text); curScript->mEmbeddedControlScript->Execute(true); // do not reset the script!!! return self->GetErrorStatus()->NoError(); } // // Load Sets // bool iAnimatorScript::Load(iScript *self, short, int value) { self->GetErrorStatus()->Monitor(curReader->GetErrorStatus(),true,"Control script: "); curReader->LoadRecord(value,0,curAnimator->GetDebugFlag()>1); if(self->GetErrorStatus()->NoError()) curAnimator->ResetCurrentFile(); return self->GetErrorStatus()->NoError(); } ifrit-3.4.2/core/ianimatorscript.h0000755000175700010010000000514012167404405015521 0ustar HomeNone/*========================================================================= Program: Ionization FRont Interactive Tool (IFRIT) Language: C++ Copyright (c) 2002-2012 Nick Gnedin All rights reserved. This file may be distributed and/or modified under the terms of the GNU General Public License version 2 as published by the Free Software Foundation and appearing in the file LICENSE.GPL included in the packaging of this file. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHORS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. =========================================================================*/ // // IFrIT animator script class - maps animator commands to function calls // #ifndef IANIMATORSCRIPT_H #define IANIMATORSCRIPT_H #include "ibasicscript.h" class iAnimator; class iControlScript; class iDataType; class iAnimatorScript : public iBasicScript { friend class iAnimator; friend class iExtensionFactory; public: vtkTypeMacro(iAnimatorScript,iBasicScript); static iAnimatorScript* New(iAnimator *an = 0); inline iAnimator* GetAnimator() const { return mAnimator; } void SetInRender(bool s) { mInRender = s; } inline bool IsInRender() const { return mInRender; } protected: iAnimatorScript(iAnimator *m); virtual ~iAnimatorScript(); virtual bool IsCommandWordLetter(char c) const; private: // // script functions that need access to private/protected members of iAnimator, iAnimatorScript, or iScript. // static bool Reset(iScript *self); static bool Render(iScript *self, short at, int n); static bool RenderAll(iScript *self, short at, int n); static bool RenderSet(iScript *self, short at, int num, const int *v, int index); static bool ExecuteControlScript(iScript *self, const iString& filename); static bool EmbedControlScript(iScript *self, const iString &text); static bool Load(iScript *self, short at, int value); bool mInRender; iAnimator *mAnimator; iControlScript *mEmbeddedControlScript; }; #endif // IANIMATORSCRIPT_H ifrit-3.4.2/core/ianimatorscriptmacro.h0000755000175700010010000001214612167404405016547 0ustar HomeNone/*========================================================================= Program: Ionization FRont Interactive Tool (IFRIT) Language: C++ Copyright (c) 2002-2012 Nick Gnedin All rights reserved. This file may be distributed and/or modified under the terms of the GNU General Public License version 2 as published by the Free Software Foundation and appearing in the file LICENSE.GPL included in the packaging of this file. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHORS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. =========================================================================*/ #define curAnimator curScript->GetAnimator() #define curVisual curScript->GetAnimator()->GetViewModule() #define curControl curScript->GetAnimator()->GetViewModule()->GetControlModule() #define curReader curScript->GetAnimator()->GetViewModule()->GetReader() #define curRenderer curScript->GetAnimator()->GetViewModule()->GetRenderer() #define curCamera curScript->GetAnimator()->GetViewModule()->GetRenderer()->GetActiveCamera() #define curLimits(t) curScript->GetAnimator()->GetViewModule()->GetReader()->GetLimits(t) #define curObject(name) curScript->GetAnimator()->GetViewModule()->Get##name##ViewSubject() #define indObject(name,n) curScript->GetAnimator()->GetViewModule()->Get##name##ViewSubject(n) #define curObjectFamily(name) curScript->GetAnimator()->GetViewModule()->GetViewObjectFamily(ViewSubject::Id::name) #define VECTOR_HELPER_ASSERT(_dim_) \ if(index<-1 || (index>=_dim_ && index!=iMath::_LargeInt)) \ { \ self->GetErrorStatus()->Set("Index is out of bounds."); \ return false; \ } \ if(index==-1 && num!=_dim_) \ { \ self->GetErrorStatus()->Set("Input array has incorrect dimension."); \ return false; \ } \ if(index>-1 && num!=1) \ { \ self->GetErrorStatus()->Set("A component of an array must be a scalar."); \ return false; \ } #define VECTOR_HELPER_ASSIGN(_dim_,_type_) \ if(index == -1) \ { \ int i; \ for(i=0; i<_dim_; i++) p[i] = iScriptKit::Variable<_type_>::Combine(p[i],value[i],at); \ } \ else \ { \ p[index] = iScriptKit::Variable<_type_>::Combine(p[index],value[0],at); \ } #define DEFINE_WORKER_REL(_class_,_method_,_type_) \ bool _class_##Set##_method_(iScript *self, short at, _type_ value) \ { \ _type_ next = iScriptKit::Variable<_type_>::Combine(cur##_class_->Get##_method_(),value,at); \ cur##_class_->Set##_method_(next); \ return true; \ } #define DEFINE_WORKER_ABS(_class_,_method_,_type_) \ bool _class_##_method_(iScript *self, short, _type_ value) \ { \ cur##_class_->_method_(value); \ return true; \ } #define DEFINE_WORKER_ABSPTR(_class_,_method_,_type_) \ bool _class_##_method_(iScript *self, short, _type_ value) \ { \ cur##_class_->_method_(&value); \ return true; \ } #define DEFINE_WORKER_ABS_FILE(_class_,_method_,_error_) \ bool _class_##_method_(iScript *self, const iString& value) \ { \ if(cur##_class_->_method_(value)) return true; else \ { \ self->GetErrorStatus()->Set(_error_); \ return false; \ } \ } #define DEFINE_WORKER_LIMIT(_name_,_limit_) \ bool _class_##_method_(iScript *self, short at, int num, float *value, int index) \ { \ iDataLimits *lim = curLimits(_name_##DataSubject::DataType()); \ if(lim!=0 && index>=0 && indexGetNumVars()) \ { \ float next = iScriptKit::Variable::Combine(lim->Get##_method_(index),value,at); \ lim->Set##_method_(index,next); \ return true; \ } \ else \ { \ self->GetErrorStatus()->Set("Invalid index."); \ return false; \ } \ } #define DEFINE_WORKER_SHOW(_class_) \ bool _class_##Show(iScript *self, short, bool value) \ { \ curObjectFamily(_class_)->Show(value); \ return true; \ } #define DEFINE_WORKER_SUBJECT_BEGIN(_class_,_method_,_type_,_rel_) \ bool _class_##_method_(iScript *self, short at, int num, const _type_ *value, int index) \ { \ VECTOR_HELPER_ASSERT((curObjectFamily(_class_)->GetMaxMemberIndex()+1)); \ i##_class_##ViewSubject *sub; \ if(index == iMath::_LargeInt) index = curObjectFamily(_class_)->GetCurrentMemberIndex(); \ _type_ val; int i, ib = (index == -1) ? 0 : index, ie = (index == -1) ? curObjectFamily(_class_)->GetMaxMemberIndex() : index; \ for(i=ib; i<=ie; i++) \ { \ sub = indObject(_class_,i); if(sub == 0) { self->GetErrorStatus()->Set("Incorrect View Object id."); return false; } \ if(_rel_) val = iScriptKit::Variable<_type_>::Combine(sub->Get##_method_(),value[(ib(vo,0,true,false) // avoid setting the number of inputs { } void iAppendPolyDataFilter::ProduceOutput() { this->ExecuteParent(); } ifrit-3.4.2/core/iappendpolydatafilter.h0000644000175700010010000000314312167404405016673 0ustar HomeNone/*========================================================================= Program: Ionization FRont Interactive Tool (IFRIT) Language: C++ Copyright (c) 2002-2012 Nick Gnedin All rights reserved. This file may be distributed and/or modified under the terms of the GNU General Public License version 2 as published by the Free Software Foundation and appearing in the file LICENSE.GPL included in the packaging of this file. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHORS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. =========================================================================*/ #ifndef IAPPENDPOLYDATAFILTER_H #define IAPPENDPOLYDATAFILTER_H #include "igenericfilter.h" #include class iAppendPolyDataFilter : public iGenericPolyDataToPolyDataFilter { IGENERICFILTER_DECLARE(iAppendPolyDataFilter,vtkAppendPolyData); protected: virtual void ProduceOutput(); }; #endif // IAPPENDPOLYDATAFILTER_H ifrit-3.4.2/core/iarray.h0000755000175700010010000000672412167404405013611 0ustar HomeNone/*========================================================================= Program: Ionization FRont Interactive Tool (IFRIT) Language: C++ Copyright (c) 2002-2012 Nick Gnedin All rights reserved. This file may be distributed and/or modified under the terms of the GNU General Public License version 2 as published by the Free Software Foundation and appearing in the file LICENSE.GPL included in the packaging of this file. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHORS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. =========================================================================*/ #ifndef IARRAY_H #define IARRAY_H // // Automatically-resizable array of type T; the type must have operator =. // template class iArray { public: iArray(int inc = 10); virtual ~iArray(); T& operator[](int i); const T& operator[](int i) const; inline int Size() const { return this->mNum; } inline int MaxIndex() const { return this->mNum-1; } inline T& Last(){ return this->mArr[this->mNum-1]; } inline const T& Last() const { return this->mArr[this->mNum-1]; } virtual void Add(const T &val); void Remove(int n); T RemoveLast(); // useful for deleteting all: while(arr.Size() > 0) delete arr.RemoveLast(); void Clear(); void Resize(int n); inline const T* Data() const { return this->mArr; } protected: void Extend(int len); T* mArr; int mNum, mLen; const int mInc; private: iArray(const iArray&); // not implemented void operator=(const iArray&); // not implemented }; // // This version also needs operator == // template class iSearchableArray : public iArray { public: iSearchableArray(int inc = 10); virtual int Find(const T &val) const; void AddUnique(const T &val); bool Remove(const T &val); private: iSearchableArray(const iSearchableArray&); // not implemented void operator=(const iSearchableArray&); // not implemented }; // // This version also needs operator < // template class iOrderedArray : public iSearchableArray { public: iOrderedArray(int inc = 10); virtual int Find(const T &val) const; virtual void Add(const T &val); virtual bool Less(const T& v1, const T& v2) const; private: iOrderedArray(const iOrderedArray&); // not implemented void operator=(const iOrderedArray&); // not implemented }; template inline bool iOrderedArray::Less(const T& v1, const T& v2) const { return v1 < v2; } // // According to C/C++ standard, comparing pointers using < is not portable. // Hence, the pointer array is not ordered. // template class iPointerArray : public iSearchableArray { public: iPointerArray(int inc = 10) : iSearchableArray(inc){} private: iPointerArray(const iPointerArray&); // not implemented void operator=(const iPointerArray&); // not implemented }; #endif // IARRAY_H ifrit-3.4.2/core/iarraytemplate.h0000755000175700010010000001202212167404405015331 0ustar HomeNone/*========================================================================= Program: Ionization FRont Interactive Tool (IFRIT) Language: C++ Copyright (c) 2002-2012 Nick Gnedin All rights reserved. This file may be distributed and/or modified under the terms of the GNU General Public License version 2 as published by the Free Software Foundation and appearing in the file LICENSE.GPL included in the packaging of this file. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHORS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. =========================================================================*/ #include "iarray.h" #include "ierror.h" // // iArray class // template iArray::iArray(int inc) : mInc((inc<1) ? 1 : inc) { this->mNum = 0; this->mLen = this->mInc; this->mArr = new T[this->mLen]; IERROR_ASSERT(this->mArr); } template iArray::~iArray() { delete [] this->mArr; } template T& iArray::operator[](int i) { if(i>=0 && imNum) return this->mArr[i]; else { IERROR_FATAL("Accessing iArray outside of boundaries."); return this->mArr[0]; } } template const T& iArray::operator[](int i) const { if(i>=0 && imNum) return this->mArr[i]; else { IERROR_LOW("Accessing iArray outside of boundaries."); return this->mArr[0]; } } template void iArray::Extend(int len) { int i, n, inc = this->mLen/4; if(inc+this->mLen < len) inc = len - this->mLen; this->mLen += (incmInc) ? this->mInc : inc; T *tmp, *arr; tmp = new T[this->mLen]; IERROR_ASSERT(tmp); n = this->mNum; arr = this->mArr; // dereference for speed for(i=0; imArr; this->mArr = tmp; } template void iArray::Add(const T &val) { if(this->mNum == this->mLen) this->Extend(0); this->mArr[this->mNum++] = val; } template void iArray::Remove(int n) { if(n<0 || n>=this->mNum) { IERROR_FATAL("Accessing iArray outside of boundaries."); } int i, m = --this->mNum; T *arr = this->mArr; // dereference for speed for(i=n; i T iArray::RemoveLast() { if(this->mNum == 0) { IERROR_FATAL("Accessing iArray outside of boundaries."); return this->mArr[0]; } this->mNum--; return this->mArr[this->mNum]; } template void iArray::Clear() { this->mNum = 0; } template void iArray::Resize(int n) { if(n > this->mLen) this->Extend(n); if(n > this->mNum) this->mNum = n; if(n < this->mNum) { if(n < 0) this->mNum = 0; else this->mNum = n; } } // // iSearchableArray class // template iSearchableArray::iSearchableArray(int inc) : iArray(inc) { } template int iSearchableArray::Find(const T &val) const { int i, n = this->mNum; T *arr = this->mArr; // dereference for speed for(i=0; i void iSearchableArray::AddUnique(const T &val) { if(this->Find(val) == -1) this->Add(val); } template bool iSearchableArray::Remove(const T &val) { int i = this->Find(val); if(i > -1) { this->iArray::Remove(i); return true; } else return false; } // // iOrderedArray class // template iOrderedArray::iOrderedArray(int inc) : iSearchableArray(inc) { } template int iOrderedArray::Find(const T &val) const { if(this->mNum == 0) return -1; // empty array T *arr = this->mArr; // dereference for speed // // Binary search of the ordered array // int ia, ib, ic; ia = 0; ib = this->mNum - 1; while(ib > ia+1) { ic = (ia+ib)/2; if(this->Less(arr[ic],val)) ia = ic; else if(this->Less(val,arr[ic])) ib = ic; else return ic; } if(arr[ia] == val) return ia; else if(arr[ib] == val) return ib; else return -1; } template void iOrderedArray::Add(const T &val) { int i, ia, ib; if(this->mNum == this->mLen) this->Extend(0); T *arr = this->mArr; // dereference for speed if(this->mNum==0 || arr[this->mNum-1]mNum++] = val; return; } if(this->Less(val,arr[0])) { ib = 0; } else { ia = 0; ib = this->mNum - 1; while(ib > ia+1) { i = (ia+ib)/2; if(this->Less(arr[i],val)) ia = i; else if(this->Less(val,arr[i])) ib = i; else ia = ib = i; } } for(i=this->mNum; i>ib; i--) arr[i] = arr[i-1]; arr[ib] = val; this->mNum++; } ifrit-3.4.2/core/iartifactcorrector.cpp0000755000175700010010000000561712167404424016547 0ustar HomeNone/*========================================================================= Program: Ionization FRont Interactive Tool (IFRIT) Language: C++ Copyright (c) 2002-2012 Nick Gnedin All rights reserved. This file may be distributed and/or modified under the terms of the GNU General Public License version 2 as published by the Free Software Foundation and appearing in the file LICENSE.GPL included in the packaging of this file. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHORS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. =========================================================================*/ #include "iartifactcorrector.h" #include "ierror.h" #include #include #include // // Templates // #include "igenericfiltertemplate.h" bool iArtifactCorrector::mIsEnabled = true; iArtifactCorrector::iArtifactCorrector(iViewSubject *vo) : iGenericPolyDataToPolyDataFilter(vo,1,true,false) { mTimer = vtkTimerLog::New(); IERROR_ASSERT(mTimer); mLastAllocatedTime = 0.0; this->SetDepthSortModeToFirstPoint(); } iArtifactCorrector::~iArtifactCorrector() { mTimer->Delete(); } void iArtifactCorrector::Enable(bool s) { mIsEnabled = s; } bool iArtifactCorrector::HasArtifacts(vtkRenderer *ren, vtkProperty *prop) { // // By default do nothing // return false; } void iArtifactCorrector::ProduceOutput() { mTimer->StartTimer(); this->ExecuteParent(); mTimer->StopTimer(); #ifdef I_DEBUG iConsole::PrintDebugMessage("Executing iArtifactCorrector..."); #endif } void iArtifactCorrector::CorrectArtifacts(vtkRenderer *ren, vtkProperty *prop, vtkPolyDataMapper *mapper, double time) { if(!mIsEnabled) return; #ifdef I_DEBUG iConsole::PrintDebugMessage("iArtifactCorrector: alloc="+iString::FromNumber(time)+" exec="+iString::FromNumber(mTimer->GetElapsedTime())); #endif if(mTimer->GetElapsedTime()>0.5*time && timeSetCamera(ren->GetActiveCamera()); if(this->HasArtifacts(ren,prop)) { this->vtkDepthSortPolyData::SetInput(mapper->GetInput()); this->Update(); mapper->GetInput()->ShallowCopy(this->GetOutput()); } } ifrit-3.4.2/core/iartifactcorrector.h0000755000175700010010000000422512167404405016205 0ustar HomeNone/*========================================================================= Program: Ionization FRont Interactive Tool (IFRIT) Language: C++ Copyright (c) 2002-2012 Nick Gnedin All rights reserved. This file may be distributed and/or modified under the terms of the GNU General Public License version 2 as published by the Free Software Foundation and appearing in the file LICENSE.GPL included in the packaging of this file. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHORS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. =========================================================================*/ // // Helper class for correcting visual artifacts (effectively, VTK bugs) // #ifndef IARTIFACTCORRECTOR_H #define IARTIFACTCORRECTOR_H #include "igenericfilter.h" #include class vtkPolyDataMapper; class vtkProperty; class vtkRenderer; class vtkTimerLog; class iArtifactCorrector : public iGenericPolyDataToPolyDataFilter { IGENERICFILTER_DECLARE(iArtifactCorrector,vtkDepthSortPolyData); public: static void Enable(bool s); static bool IsEnabled(){ return mIsEnabled; } void CorrectArtifacts(vtkRenderer *ren, vtkProperty *prop, vtkPolyDataMapper *mapper, double time); protected: virtual ~iArtifactCorrector(); virtual void ProduceOutput(); virtual bool HasArtifacts(vtkRenderer *ren, vtkProperty *prop); private: static bool mIsEnabled; vtkTimerLog *mTimer; double mLastAllocatedTime; void SetInput(vtkDataObject *); // not impelmeneted }; #endif ifrit-3.4.2/core/iaxis.cpp0000755000175700010010000001027712167404424013771 0ustar HomeNone/*========================================================================= Program: Ionization FRont Interactive Tool (IFRIT) Language: C++ Copyright (c) 2002-2012 Nick Gnedin All rights reserved. This file may be distributed and/or modified under the terms of the GNU General Public License version 2 as published by the Free Software Foundation and appearing in the file LICENSE.GPL included in the packaging of this file. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHORS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. =========================================================================*/ #include "iaxis.h" #include "ioverlayhelper.h" #include "irendertool.h" #include #include #include #include #include // // Templates // #include "iarraytemplate.h" #include "igenericproptemplate.h" iAxis* iAxis::New(iRenderTool *rt) { IERROR_ASSERT(rt); return new iAxis(rt); } iAxis::iAxis(iRenderTool *rt) : iGenericProp(true), mOverlayHelper(rt) { mLineWidth = 2; mTickLength = TickLength; this->PickableOff(); } iAxis::~iAxis() { } void iAxis::UpdateGeometry(vtkViewport *vp) { int mag = mOverlayHelper->GetRenderingMagnification(); if(mag == 1) { this->AxisActor->GetProperty()->SetLineWidth(mLineWidth); this->SetTickLength(mTickLength); mPos1 = this->GetPosition(); mPos2 = this->GetPosition2(); this->GetProperty()->SetColor(this->GetOverlayHelper()->GetColor(vp).ToVTK()); this->GetOverlayHelper()->UpdateTextProperty(vp,this->LabelTextProperty); this->GetOverlayHelper()->UpdateTextProperty(vp,this->TitleTextProperty); } else { int winij[2]; mOverlayHelper->ComputePositionShiftsUnderMagnification(winij); int *sz = vp->GetSize(); if(this->GetPoint1Coordinate()->GetCoordinateSystem() == VTK_NORMALIZED_VIEWPORT) { this->SetPosition(mag*mPos1.X-winij[0],mag*mPos1.Y-winij[1]); } else { this->SetPosition(mag*mPos1.X-sz[0]*winij[0],mag*mPos1.Y-sz[1]*winij[1]); } if(this->GetPoint2Coordinate()->GetCoordinateSystem() == VTK_NORMALIZED_VIEWPORT) { this->SetPosition2(mag*mPos2.X-winij[0],mag*mPos2.Y-winij[1]); } else { this->SetPosition2(mag*mPos2.X-sz[0]*winij[0],mag*mPos2.Y-sz[1]*winij[1]); } this->AxisActor->GetProperty()->SetLineWidth(mLineWidth*mag); this->SetTickLength(mag*mTickLength); } } void iAxis::UpdateOverlay(vtkViewport *vp) { int i, mag = mOverlayHelper->GetRenderingMagnification(); // // This must be after RenderOpaqueGeometry // this->TitleTextProperty->SetFontSize(mOverlayHelper->GetFontSize(vp,mag)); this->TitleMapper->GetTextProperty()->ShallowCopy(this->TitleTextProperty); this->LabelTextProperty->SetFontSize(mOverlayHelper->GetFontSize(vp,mag)); for(i=0; iAdjustedNumberOfLabels; i++) { this->LabelMappers[i]->GetTextProperty()->ShallowCopy(this->LabelTextProperty); } int *s = vp->GetSize(); if(mag == 1) { mPosT = this->TitleActor->GetPosition(); mPosL.Resize(this->AdjustedNumberOfLabels); for(i=0; iAdjustedNumberOfLabels; i++) { mPosL[i] = this->LabelActors[i]->GetPosition(); } } else { int winij[2]; mOverlayHelper->ComputePositionShiftsUnderMagnification(winij); this->TitleActor->SetPosition(mag*mPosT.X-s[0]*winij[0],mag*mPosT.Y-s[1]*winij[1]); for(i=0; iAdjustedNumberOfLabels; i++) { this->LabelActors[i]->SetPosition(mag*mPosL[i].X-s[0]*winij[0],mag*mPosL[i].Y-s[1]*winij[1]); } } } iAxis::Pos& iAxis::Pos::operator=(const double *ptr) { this->X = ptr[0]; this->Y = ptr[1]; return *this; } ifrit-3.4.2/core/iaxis.h0000644000175700010010000000366712167404405013437 0ustar HomeNone/*========================================================================= Program: Ionization FRont Interactive Tool (IFRIT) Language: C++ Copyright (c) 2002-2012 Nick Gnedin All rights reserved. This file may be distributed and/or modified under the terms of the GNU General Public License version 2 as published by the Free Software Foundation and appearing in the file LICENSE.GPL included in the packaging of this file. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHORS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. =========================================================================*/ #ifndef IAXIS_H #define IAXIS_H #include "igenericprop.h" #include #include "ipointermacro.h" class iOverlayHelper; class iRenderTool; class iAxis: public iGenericProp { IPOINTER_AS_USER(OverlayHelper); public: vtkTypeMacro(iAxis,vtkAxisActor2D); static iAxis* New(iRenderTool *rt = 0); protected: iAxis(iRenderTool *rt); virtual ~iAxis(); virtual void UpdateGeometry(vtkViewport *vp); virtual void UpdateOverlay(vtkViewport *vp); private: struct Pos { float X; float Y; Pos& operator=(const double *ptr); // impl-shared copy }; float mLineWidth; int mTickLength; Pos mPos1, mPos2, mPosT; iArray mPosL; }; #endif // IAXIS_H ifrit-3.4.2/core/ibasicdatasubjects.cpp0000755000175700010010000001112612167404424016475 0ustar HomeNone/*========================================================================= Program: Ionization FRont Interactive Tool (IFRIT) Language: C++ Copyright (c) 2002-2012 Nick Gnedin All rights reserved. This file may be distributed and/or modified under the terms of the GNU General Public License version 2 as published by the Free Software Foundation and appearing in the file LICENSE.GPL included in the packaging of this file. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHORS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. =========================================================================*/ #include "ibasicdatasubjects.h" #include "idata.h" #include "iuniformgridfileloader.h" // // ******************************************************************** // // iUniformScalarsDataSubject class // // ******************************************************************** // IFIELDDATASUBJECT_DEFINE_TYPE(iUniformScalarsDataSubject,1,"Uniform Scalars","us",0,"basic,field,scalars","IFRIT_SCALAR_FIELD_DATA_DIR"); // // Inherited keys // IFIELDDATASUBJECT_DEFINE_INHERITED_KEYS(iUniformScalarsDataSubject); IOBJECT_DEFINE_KEY(iUniformScalarsDataSubject,VariableCalculatorFunction,cf,String,1); IOBJECT_DEFINE_KEY(iUniformScalarsDataSubject,VariableCalculatorOutput,co,OffsetInt,1); iUniformScalarsDataSubject::iUniformScalarsDataSubject(iUniformScalarsFileLoader *fl) : iFieldDataSubject(fl,iUniformScalarsDataSubject::Type().FullName()) { mConcreteLoader = fl; this->ConfigureLimits(3,"Variable"); } void iUniformScalarsDataSubject::FieldDataSubjectPackStateBody(iString &s) const { this->PackValue(s,KeyVariableCalculatorOutput(),mConcreteLoader->GetCalculatorOutput()); this->PackValue(s,KeyVariableCalculatorFunction(),mConcreteLoader->GetCalculatorExpression()); } void iUniformScalarsDataSubject::FieldDataSubjectUnPackStateBody(const iString &s) { int i; iString s1; if(this->UnPackValue(s,KeyVariableCalculatorOutput(),i)) { mConcreteLoader->SetCalculatorOutput(i); this->ClearCache(); } if(this->UnPackValue(s,KeyVariableCalculatorFunction(),s1)) { mConcreteLoader->SetCalculatorExpression(s1); this->ClearCache(); } } // // ******************************************************************** // // iUniformVectorsDataSubject class // // ******************************************************************** // IFIELDDATASUBJECT_DEFINE_TYPE(iUniformVectorsDataSubject,2,"Uniform Vectors","uv",1,"basic,field","IFRIT_VECTOR_FIELD_DATA_DIR"); // // Inherited keys // IFIELDDATASUBJECT_DEFINE_INHERITED_KEYS(iUniformVectorsDataSubject); iUniformVectorsDataSubject::iUniformVectorsDataSubject(iFieldFileLoader *fl) : iFieldDataSubject(fl,iUniformVectorsDataSubject::Type().FullName()) { this->ConfigureLimits(1,"Vector field"); } // // ******************************************************************** // // iUniformTensorsDataSubject class // // ******************************************************************** // IFIELDDATASUBJECT_DEFINE_TYPE(iUniformTensorsDataSubject,3,"Uniform Tensors","ut",2,"basic,field","IFRIT_TENSOR_FIELD_DATA_DIR"); // // Inherited keys // IFIELDDATASUBJECT_DEFINE_INHERITED_KEYS(iUniformTensorsDataSubject); iUniformTensorsDataSubject::iUniformTensorsDataSubject(iFieldFileLoader *fl) : iFieldDataSubject(fl,iUniformTensorsDataSubject::Type().FullName()) { this->ConfigureLimits(1,"Tensor field"); } // // ******************************************************************** // // iBasicParticlesDataSubject class // // ******************************************************************** // IPARTICLEDATASUBJECT_DEFINE_TYPE(iBasicParticlesDataSubject,4,"Basic Particles","bp","basic,particles","IFRIT_PARTICLE_SET_DATA_DIR"); // // Inherited keys // IPARTICLEDATASUBJECT_DEFINE_INHERITED_KEYS(iBasicParticlesDataSubject); iBasicParticlesDataSubject::iBasicParticlesDataSubject(iParticleFileLoader *fl) : iParticleDataSubject(fl,iBasicParticlesDataSubject::Type().FullName()) { this->ConfigureLimits(3,"Attribute"); } ifrit-3.4.2/core/ibasicdatasubjects.h0000755000175700010010000000647312167404405016152 0ustar HomeNone/*========================================================================= Program: Ionization FRont Interactive Tool (IFRIT) Language: C++ Copyright (c) 2002-2012 Nick Gnedin All rights reserved. This file may be distributed and/or modified under the terms of the GNU General Public License version 2 as published by the Free Software Foundation and appearing in the file LICENSE.GPL included in the packaging of this file. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHORS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. =========================================================================*/ // // DataSubject(s) for basic IFrITe DataType(s) // #ifndef IBASICDATASUBJECTS_H #define IBASICDATASUBJECTS_H #include "ifielddatasubject.h" #include "iparticledatasubject.h" class iUniformScalarsFileLoader; class iUniformScalarsDataSubject : public iFieldDataSubject { friend class iDataReader; public: vtkTypeMacro(iUniformScalarsDataSubject,iFieldDataSubject); // // Inherited members // IFIELDDATASUBJECT_DECLARE_INHERITED_KEYS; IFIELDDATASUBJECT_DECLARE_INHERITED_MEMBERS; static const iObjectKey& KeyVariableCalculatorFunction(); static const iObjectKey& KeyVariableCalculatorOutput(); protected: virtual void FieldDataSubjectPackStateBody(iString &) const; virtual void FieldDataSubjectUnPackStateBody(const iString &); private: iUniformScalarsDataSubject(iUniformScalarsFileLoader *fl); // should not be created except by a Reader iUniformScalarsFileLoader *mConcreteLoader; }; class iUniformVectorsDataSubject : public iFieldDataSubject { friend class iDataReader; public: vtkTypeMacro(iUniformVectorsDataSubject,iFieldDataSubject); // // Inherited members // IFIELDDATASUBJECT_DECLARE_INHERITED_KEYS; IFIELDDATASUBJECT_DECLARE_INHERITED_MEMBERS; private: iUniformVectorsDataSubject(iFieldFileLoader *fl); // should not be created except by a Reader }; class iUniformTensorsDataSubject : public iFieldDataSubject { friend class iDataReader; public: vtkTypeMacro(iUniformTensorsDataSubject,iFieldDataSubject); // // Inherited members // IFIELDDATASUBJECT_DECLARE_INHERITED_KEYS; IFIELDDATASUBJECT_DECLARE_INHERITED_MEMBERS; private: iUniformTensorsDataSubject(iFieldFileLoader *fl); // should not be created except by a Reader }; class iBasicParticlesDataSubject : public iParticleDataSubject { friend class iDataReader; public: vtkTypeMacro(iBasicParticlesDataSubject,iParticleDataSubject); // // Inherited members // IPARTICLEDATASUBJECT_DECLARE_INHERITED_KEYS; IPARTICLEDATASUBJECT_DECLARE_INHERITED_MEMBERS; private: iBasicParticlesDataSubject(iParticleFileLoader *fl); // should not be created except by a Reader }; #endif ifrit-3.4.2/core/ibasicparticlesfileloader.cpp0000755000175700010010000002134212167404425020040 0ustar HomeNone/*========================================================================= Program: Ionization FRont Interactive Tool (IFRIT) Language: C++ Copyright (c) 2002-2012 Nick Gnedin All rights reserved. This file may be distributed and/or modified under the terms of the GNU General Public License version 2 as published by the Free Software Foundation and appearing in the file LICENSE.GPL included in the packaging of this file. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHORS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. =========================================================================*/ #include "ibasicparticlesfileloader.h" #include "icommoneventobservers.h" #include "ifile.h" #include "ierrorstatus.h" #include "iviewmodule.h" #include #include // // Templates (needed for some compilers) // #include "iarraytemplate.h" iBasicParticlesFileLoader::iBasicParticlesFileLoader(iDataReader *r) : iParticleFileLoader(r) { } void iBasicParticlesFileLoader::ReadFileBody(const iString &suffix, const iString &fname) { // // is the suffix valid? // if(suffix.Lower()!="txt" && suffix.Lower()!="bin") { this->GetErrorStatus()->Set("Incorrect file suffix."); return; } bool err, isBin = (suffix.Lower() == "bin"); // // Open the file // iFile F(fname); if(!F.Open(iFile::_Read,isBin?iFile::_Binary:iFile::_Text)) { this->GetErrorStatus()->Set("File does not exist."); return; } mObserver->Started(iProgressEventObserver::_Reading); mObserver->SetProgress(0.0); // // Read the header // int i, natt; bool paf; vtkIdType ntot0; float ll[3], ur[3]; iString buffer; if(isBin) { err = !this->ReadBinFileHeader(F,ntot0,ll,ur,paf,natt); } else { err = !this->ReadTxtFileHeader(F,ntot0,ll,ur,paf,natt,buffer); } if(ntot0 <= 0) err = true; if(err) { F.Close(); mObserver->Finished(); this->GetErrorStatus()->Set("Corrupted header."); return; } // // Compute scale and offset // float offsetF[3], scaleF[3]; double offsetD[3], scaleD[3]; if(paf) { for(i=0; i<3; i++) { offsetF[i] = ll[i]; scaleF[i] = 2.0/(ur[i]-ll[i]); } } else { for(i=0; i<3; i++) { offsetD[i] = ll[i]; scaleD[i] = 2.0/(ur[i]-ll[i]); } } // // Configure streams // this->ConfigureStreams(&ntot0,&natt,paf); mObserver->SetProgress(0.01); // // Read actual data // if(isBin) { err = !this->ReadBinFileContents(F,paf,scaleF,offsetF,scaleD,offsetD); } else { err = !this->ReadTxtFileContents(F,paf,scaleF,offsetF,scaleD,offsetD,buffer); } if(err || mObserver->IsAborted()) { if(!err) this->GetErrorStatus()->Set("Aborted."); else this->GetErrorStatus()->Set("Corrupted data."); mObserver->Finished(); this->ReleaseStreams(); F.Close(); return; } mObserver->SetProgress(1.0); mObserver->Finished(); F.Close(); } bool iBasicParticlesFileLoader::ReadBinFileHeader(iFile &F, vtkIdType &ntot0, float *ll, float *ur, bool &paf, int &natt) { // // Read the header // if(!this->DetectFortranFileStructure(F,sizeof(int))) return false; int ntot1; if(!this->ReadFortranRecord(F,Buffer(ntot1),0.0f,0.0f)) return false; ntot0 = ntot1; float bounds[6]; if(!this->ReadFortranRecord(F,Buffer(bounds,6),0.0f,0.0f)) return false; int i; for(i=0; i<3; i++) { ll[i] = bounds[i]; ur[i] = bounds[3+i]; } // // Auto-detect whether points are float or double // vtkIdType nrec = sizeof(float)*ntot0; int mar = F.SetMarker(); if(!this->SkipFortranRecord(F,nrec)) // X { // // not float - try double // paf = false; nrec = sizeof(double)*ntot0; F.ReturnToMarker(mar); if(!this->SkipFortranRecord(F,nrec)) return false; // X if(!this->SkipFortranRecord(F,nrec)) return false; // Y if(!this->SkipFortranRecord(F,nrec)) return false; // Z } else { if(!this->SkipFortranRecord(F,nrec)) return false; // Y if(!this->SkipFortranRecord(F,nrec)) return false; // Z paf = true; } // // Measure the file size to find out the number of attributes // nrec = sizeof(float)*ntot0; for(i=0; i<999 && this->SkipFortranRecord(F,nrec); i++); F.ReturnToMarker(mar,true); natt = i; return true; } bool iBasicParticlesFileLoader::ReadTxtFileHeader(iFile &F, vtkIdType &ntot0, float *ll, float *ur, bool &paf, int &natt, iString &buffer) { iString s; // // TxT file coordinates are float - do we need to check whether they are long enough to be double? // paf = true; // // First line // if(!F.ReadLine(s)) return false; unsigned long ntotRead; int ret = sscanf(s.ToCharPointer(),"%ld",&ntotRead); if(ret != 1) return false; if(ntotRead <= 0) return false; ntot0 = ntotRead; // // Second line // if(!F.ReadLine(s)) return false; char *axisName[3]; int i; for(i=0; i<3; i++) { axisName[i] = 0; axisName[i] = new char[8192]; if(axisName[i] == 0) break; } if(i < 3 ) { for(i=0; i<3; i++) if(axisName[i] != 0) delete [] axisName[i]; return false; } ret = sscanf(s.ToCharPointer(),"%g %g %g %g %g %g %s %s %s",&ll[0],&ll[1],&ll[2],&ur[0],&ur[1],&ur[2],axisName[0],axisName[1],axisName[2]); if(ret == 9) this->GetViewModule()->SetAxesBox(axisName[0],axisName[1],axisName[2],ll[0],ur[0],ll[1],ur[1],ll[2],ur[2]); for(i=0; i<3; i++) if(axisName[i] != 0) delete [] axisName[i]; if(ret!=6 && ret!=9) return false; // // Find out the number of attributes // if(!F.ReadLine(s)) return false; double xyz[3]; float f[10]; ret = sscanf(s.ToCharPointer(),"%lg %lg %lg %g %g %g %g %g %g %g %g %g %g",&xyz[0],&xyz[1],&xyz[2],&f[0],&f[1],&f[2],&f[3],&f[4],&f[5],&f[6],&f[7],&f[8],&f[9]); if(ret<3 || ret>12) return false; natt = ret - 3; buffer = s; return true; } bool iBasicParticlesFileLoader::ReadBinFileContents(iFile &F, bool paf, float *scaleF, float *offsetF, double *scaleD, double *offsetD) { ParticleStream *s = this->GetStream(0); // // parameters for the Progress Bar // float updateStart, updateDuration = 0.99/(s->NumAttributesInFile+3); // // Read coordinates // int n; bool err = false; for(n=0; !err && n<3; n++) { updateStart = 0.01 + updateDuration*n; if(paf) { err = !this->ReadPositions(F,1,n,updateStart,updateDuration,scaleF+n,offsetF+n); } else { err = !this->ReadPositions(F,1,n,updateStart,updateDuration,scaleD+n,offsetD+n); } } if(err || mObserver->IsAborted()) { if(err) this->GetErrorStatus()->Set("Corrupted data."); else this->GetErrorStatus()->SetAbort(); return false; } // // Read attributes // for(n=0; !err && nNumAttributesInFile; n++) { updateStart = 0.01 + updateDuration*(n+3); err = !this->ReadAttributes(F,1,n,updateStart,updateDuration); } if(err || mObserver->IsAborted()) { if(err) this->GetErrorStatus()->Set("Corrupted data."); else this->GetErrorStatus()->SetAbort(); return false; } return true; } bool iBasicParticlesFileLoader::ReadTxtFileContents(iFile &F, bool paf, float *scaleF, float *offsetF, double *scaleD, double *offsetD, iString buffer) { ParticleStream *s = this->GetStream(0); // // Use the buffer // double xyz[3], xyzD[3]; float xyzF[3], f[10]; int i, ret; vtkIdType l; mIterator.Start(); for(l=0; lNumTotal; l++) { if(l > 0) { if(!F.ReadLine(buffer)) { this->GetErrorStatus()->Set("Truncated file."); return false; } } ret = sscanf(buffer.ToCharPointer(),"%lg %lg %lg %g %g %g %g %g %g %g %g %g %g",&xyz[0],&xyz[1],&xyz[2],&f[0],&f[1],&f[2],&f[3],&f[4],&f[5],&f[6],&f[7],&f[8],&f[9]); if(ret < s->NumAttributesInFile+3) { this->GetErrorStatus()->Set("Corrupted data."); return false; } if((100*l)/s->NumTotal < (100*(l+1))/s->NumTotal) { mObserver->SetProgress(0.01+(float)l/s->NumTotal); if(mObserver->IsAborted()) { this->GetErrorStatus()->SetAbort(); return false; } } if(mIterator.IsSelected()) { if(paf) { for(i=0; i<3; i++) xyzF[i] = -1.0 + scaleF[i]*(xyz[i]-offsetF[i]); s->Points->SetPoint(mIterator.GlobalIndex(),xyzF); } else { for(i=0; i<3; i++) xyzD[i] = -1.0 + scaleD[i]*(xyz[i]-offsetD[i]); s->Points->SetPoint(mIterator.GlobalIndex(),xyzD); } if(s->Scalars != 0) s->Scalars->SetTuple(mIterator.GlobalIndex(),f); } } mIterator.Stop(); return true; } ifrit-3.4.2/core/ibasicparticlesfileloader.h0000755000175700010010000000425512167404406017510 0ustar HomeNone/*========================================================================= Program: Ionization FRont Interactive Tool (IFRIT) Language: C++ Copyright (c) 2002-2012 Nick Gnedin All rights reserved. This file may be distributed and/or modified under the terms of the GNU General Public License version 2 as published by the Free Software Foundation and appearing in the file LICENSE.GPL included in the packaging of this file. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHORS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. =========================================================================*/ // // DataFileLoader for reading basic particle files // #ifndef IBASICPARTICLESFILELOADER_H #define IBASICPARTICLESFILELOADER_H #include "iparticlefileloader.h" class iBasicParticlesFileLoader : public iParticleFileLoader { friend class iDataReader; public: vtkTypeMacro(iBasicParticlesFileLoader,iParticleFileLoader); protected: iBasicParticlesFileLoader(iDataReader *r); virtual void ReadFileBody(const iString &suffix, const iString &fname); virtual bool ReadBinFileHeader(iFile &F, vtkIdType &ntot0, float *ll, float *ur, bool &paf, int &natt); virtual bool ReadTxtFileHeader(iFile &F, vtkIdType &ntot0, float *ll, float *ur, bool &paf, int &natt, iString &buffer); virtual bool ReadBinFileContents(iFile &F, bool paf, float *scaleF, float *offsetF, double *scaleD, double *offsetD); virtual bool ReadTxtFileContents(iFile &F, bool paf, float *scaleF, float *offsetF, double *scaleD, double *offsetD, iString buffer); }; #endif ifrit-3.4.2/core/ibasicscript.cpp0000755000175700010010000001356712167404425015341 0ustar HomeNone/*========================================================================= Program: Ionization FRont Interactive Tool (IFRIT) Language: C++ Copyright (c) 2002-2012 Nick Gnedin All rights reserved. This file may be distributed and/or modified under the terms of the GNU General Public License version 2 as published by the Free Software Foundation and appearing in the file LICENSE.GPL included in the packaging of this file. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHORS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. =========================================================================*/ #include "ibasicscript.h" #include "iscriptkit.h" // // Templates // #include "icalculatortemplate.h" #include "iscriptkittemplate.h" namespace iBasicScript_Private { template class Declaration : public iScriptKit::VariableDeclarationStatement { public: Declaration(iScript *script, const iString &command) : iScriptKit::VariableDeclarationStatement(script,command) { } protected: virtual iScriptKit::Prototype* CreatePrototype(const iString &name, int dim) const { return this->iScriptKit::VariableDeclarationStatement::NewPrototype(name,dim); // full specification is needed for some compilers } }; class Loop1 : public iScriptKit::LoopFlowControlStatement { public: Loop1(iScript *script, const iString &command) : iScriptKit::LoopFlowControlStatement(script,command,false) { } protected: virtual bool ParseOperandForCount() { // // Do nothing - the whole argument is the count expression // return true; } }; class Loop2 : public iScriptKit::LoopFlowControlStatement { public: Loop2(iScript *script, const iString &command) : iScriptKit::LoopFlowControlStatement(script,command,true) { mIndexVariable = 0; } protected: virtual bool ParseOperandForCount() { // // Look for the variable name in the context: // (for) var to N (old syntax) // (for) var=b,e,s // (for) var = b,e,s // iString s(mOperand); s.ReduceWhiteSpace(); iString vn = s.Section(" ",0,0); if(vn.Contains('=')) vn = s.Section("=",0,0); // // Is this a defined integer variable? // iScriptKit::Value *var = this->FindVariable(vn); if(var == 0) { this->ReportError("The loop index variable is not declared."); return false; } if(var->GetTypeId()!=0 && var->Dim()!=1) { this->ReportError("The loop index variable must be an integer scalar."); return false; } mIndexVariable = var; #ifdef ISCRIPT_BACKWARD_COMPATIBLE // // Variable is fine. Is it an old-style syntax? // if(s.Section(" ",1,1) == "to") { s = s.Section(" ",2,2); mOperand = s; return true; } #endif // // This is a new-style syntax // s = mOperand.Section("=",1); mFirstExpression = s.Section(",",0,0); mOperand = s.Section(",",1,1); mStepExpression = s.Section(",",2); return true; } virtual void OnExecute() { iScriptKit::Variable *var; if(mIndexVariable==0 || (var = static_cast*>(mIndexVariable))==0) { this->ReportError("A bug in iBasicScript class is detected."); } else { var->Assign(mIndex,0); } } iScriptKit::Value *mIndexVariable; }; class Conditional : public iScriptKit::ConditionalFlowControlStatement { public: Conditional(iScript *script, const iString &command) : iScriptKit::ConditionalFlowControlStatement(script,command) { } protected: virtual bool ParseOperandForCondition() { // // Look for the argument in the context: // (if) then // iString s(mOperand); s.ReduceWhiteSpace(); if(s.Part(-4) != "then") { this->ReportError("Syntax error: if statement must end with 'then'."); return false; } mOperand.Replace("then",""); return true; } }; }; using namespace iBasicScript_Private; iBasicScript::iBasicScript(iScript *parent) : iScript(parent) { // // IFrIT script are case-sensitive since the keys are // mCaseSensitive = true; // // This is for embeding other scripts // mHeadOfLineContinuationString = "> "; mAppendSeparator = "%%"; // // Dummy words // this->CreateDummyWord("set"); // // Aliases // this->CreateAliasWord("real","float"); this->CreateAliasWord("endif","end"); // // Parameter words // this->AddConstant(new iScriptKit::Constant(this,"false",false)); this->AddConstant(new iScriptKit::Constant(this,"true",true)); // // Declarations // this->AddPrototype< Declaration >("int"); this->AddPrototype< Declaration >("bool"); this->AddPrototype< Declaration >("float"); this->AddPrototype< Declaration >("double"); #ifdef ISCRIPT_BACKWARD_COMPATIBLE this->AddPrototype< Declaration >("var int"); this->AddPrototype< Declaration >("var bool"); this->AddPrototype< Declaration >("var float"); this->AddPrototype< Declaration >("var double"); #endif // // Flow control operations // this->AddPrototype< Loop1 >("loop"); this->AddPrototype< Loop2 >("for"); this->AddPrototype< iScriptKit::ClosingFlowControlStatement >("end"); this->AddPrototype< iScriptKit::SwappingFlowControlStatement >("else"); this->AddPrototype< Conditional >("if"); } ifrit-3.4.2/core/ibasicscript.h0000755000175700010010000000307512167404406014776 0ustar HomeNone/*========================================================================= Program: Ionization FRont Interactive Tool (IFRIT) Language: C++ Copyright (c) 2002-2012 Nick Gnedin All rights reserved. This file may be distributed and/or modified under the terms of the GNU General Public License version 2 as published by the Free Software Foundation and appearing in the file LICENSE.GPL included in the packaging of this file. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHORS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. =========================================================================*/ // // IFrIT base script class - provide a small set of common functionality to all IFrIT scripts // #ifndef IBASICSCRIPT_H #define IBASICSCRIPT_H #include "iscript.h" class iBasicScript: public iScript { public: vtkTypeMacro(iBasicScript,iScript); protected: iBasicScript(iScript *parent); }; #endif // IBASICSCRIPT_H ifrit-3.4.2/core/ibitmaptextsubject.cpp0000755000175700010010000000566012167404425016567 0ustar HomeNone/*========================================================================= Program: Ionization FRont Interactive Tool (IFRIT) Language: C++ Copyright (c) 2002-2012 Nick Gnedin All rights reserved. This file may be distributed and/or modified under the terms of the GNU General Public License version 2 as published by the Free Software Foundation and appearing in the file LICENSE.GPL included in the packaging of this file. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHORS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. =========================================================================*/ #include "ibitmaptextsubject.h" #include "ierror.h" #include "ioverlayhelper.h" #include "itextactor.h" #include #include #include #include // // Templates // #include "iarraytemplate.h" #include "igenericproptemplate.h" iBitmapTextSubject* iBitmapTextSubject::New(iTextActor *parent, iRenderTool *rt) { IERROR_ASSERT(rt); return new iBitmapTextSubject(parent,rt); } iBitmapTextSubject::iBitmapTextSubject(iTextActor *parent, iRenderTool *rt) : iTextSubject(parent,rt) { mMapper = vtkTextMapper::New(); IERROR_ASSERT(mMapper); mActor = vtkActor2D::New(); IERROR_ASSERT(mActor); this->AppendComponent(mActor); mActor->SetMapper(mMapper); mActor->GetPositionCoordinate()->SetCoordinateSystemToNormalizedViewport(); mMapper->SetTextProperty(mParent->GetTextProperty()); } iBitmapTextSubject::~iBitmapTextSubject() { mMapper->Delete(); mActor->Delete(); } void iBitmapTextSubject::ComputeSize(vtkViewport *viewport, float s[2]) { mMapper->SetInput(mParent->GetText().ToCharPointer()); double w = (float)mMapper->GetWidth(viewport); double h = (float)mMapper->GetHeight(viewport); viewport->ViewportToNormalizedViewport (w,h); s[0] = w; s[1] = h; } void iBitmapTextSubject::UpdateGeometryBody(vtkViewport* viewport, int mag) { if(mag == 1) { //mMapper->GetTextProperty()->SetOrientation(mParent->GetAngle()); mActor->SetPosition(mPos[0],mPos[1]); mActor->SetPosition2(mSize[0],mSize[1]); } else { int winij[2]; this->GetOverlayHelper()->ComputePositionShiftsUnderMagnification(winij); mActor->SetPosition(mag*mPos[0]-winij[0],mag*mPos[1]-winij[1]); mActor->SetPosition2(mag*mSize[0],mag*mSize[1]); } } ifrit-3.4.2/core/ibitmaptextsubject.h0000755000175700010010000000375712167404406016240 0ustar HomeNone/*========================================================================= Program: Ionization FRont Interactive Tool (IFRIT) Language: C++ Copyright (c) 2002-2012 Nick Gnedin All rights reserved. This file may be distributed and/or modified under the terms of the GNU General Public License version 2 as published by the Free Software Foundation and appearing in the file LICENSE.GPL included in the packaging of this file. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHORS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. =========================================================================*/ //********************************************************************** // // Class for displaying bitmap (2D) text in VTK // //********************************************************************** #ifndef IBITMAPSUBJECT_H #define IBITMAPSUBJECT_H #include "itextsubject.h" class vtkActor2D; class vtkTextMapper; class iBitmapTextSubject: public iTextSubject { public: static iBitmapTextSubject* New(iTextActor *parent, iRenderTool *rv); protected: virtual ~iBitmapTextSubject(); virtual void ComputeSize(vtkViewport *v, float s[2]); virtual void UpdateGeometryBody(vtkViewport *vp, int mag); private: iBitmapTextSubject(iTextActor *parent, iRenderTool *rv); vtkTextMapper *mMapper; vtkActor2D *mActor; }; #endif // IBITMAPSUBJECT_H ifrit-3.4.2/core/iboundeddisksource.cpp0000755000175700010010000000726712167404425016547 0ustar HomeNone/*========================================================================= Program: Ionization FRont Interactive Tool (IFRIT) Language: C++ Copyright (c) 2002-2012 Nick Gnedin All rights reserved. This file may be distributed and/or modified under the terms of the GNU General Public License version 2 as published by the Free Software Foundation and appearing in the file LICENSE.GPL included in the packaging of this file. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHORS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. =========================================================================*/ #include "iboundeddisksource.h" #include "ierror.h" #include "itransform.h" #include #include #include #include #include #include // // iBoundedDiskSource class // iBoundedDiskSource* iBoundedDiskSource::New(iViewSubject *vo) { IERROR_ASSERT(vo); return new iBoundedDiskSource(vo); } iBoundedDiskSource::iBoundedDiskSource(iViewSubject *vo) : iBoundedPolyDataSource(vo,true,true) { mPointNormals = vtkPolyDataNormals::New(); IERROR_ASSERT(mPointNormals); mSource = vtkDiskSource::New(); IERROR_ASSERT(mSource); mPointNormals->SplittingOff(); mPointNormals->ConsistencyOff(); mPointNormals->ComputePointNormalsOn(); mPointNormals->ComputeCellNormalsOff(); mPointNormals->FlipNormalsOff(); mSource->SetInnerRadius(0.0); mSource->SetOuterRadius(1.0); mAppendPolyData = vtkAppendPolyData::New(); IERROR_ASSERT(mAppendPolyData); mArrowSource = vtkArrowSource::New(); IERROR_ASSERT(mArrowSource); mTransformPolyDataFilter = vtkTransformPolyDataFilter::New(); IERROR_ASSERT(mTransformPolyDataFilter); iTransform *t = iTransform::New(); IERROR_ASSERT(t); t->Identity(); t->RotateY(-90.0); mTransformPolyDataFilter->SetTransform(t); t->Delete(); mTransformPolyDataFilter->SetInput(mArrowSource->GetOutput()); mAppendPolyData->AddInput(mSource->GetOutput()); mAppendPolyData->AddInput(mTransformPolyDataFilter->GetOutput()); mWithArrow = false; this->SetWithArrow(true); } iBoundedDiskSource::~iBoundedDiskSource() { mSource->Delete(); mPointNormals->Delete(); mAppendPolyData->Delete(); mArrowSource->Delete(); mTransformPolyDataFilter->Delete(); } void iBoundedDiskSource::SetWithArrow(bool s) { if(s == mWithArrow) return; mWithArrow = s; if(s) { mFilter->SetInput(mAppendPolyData->GetOutput()); } else { mFilter->SetInput(mSource->GetOutput()); } } void iBoundedDiskSource::AddObserverToSource(unsigned long e, vtkCommand *c, float p) { mSource->AddObserver(e,c,p); mPointNormals->AddObserver(e,c,p); } void iBoundedDiskSource::UpdateSourceResolution() { mSource->SetRadialResolution(1+mResolution/2); mSource->SetCircumferentialResolution(3*mResolution); } float iBoundedDiskSource::GetSourceMemorySize() const { float s = 0.0; s += mPointNormals->GetOutput()->GetActualMemorySize(); s += mSource->GetOutput()->GetActualMemorySize(); return s; } void iBoundedDiskSource::UpdateBoundaryConditions() { } ifrit-3.4.2/core/iboundeddisksource.h0000755000175700010010000000443412167404406016204 0ustar HomeNone/*========================================================================= Program: Ionization FRont Interactive Tool (IFRIT) Language: C++ Copyright (c) 2002-2012 Nick Gnedin All rights reserved. This file may be distributed and/or modified under the terms of the GNU General Public License version 2 as published by the Free Software Foundation and appearing in the file LICENSE.GPL included in the packaging of this file. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHORS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. =========================================================================*/ #ifndef IBOUNDEDDISKSOURCE_H #define IBOUNDEDDISKSOURCE_H #include "iboundedpolydatasource.h" class vtkAppendPolyData; class vtkArrowSource; class vtkDiskSource; class vtkPolyDataNormals; class vtkTransformPolyDataFilter; class iBoundedDiskSource : public iBoundedPolyDataSource { public: vtkTypeMacro(iBoundedDiskSource,iBoundedPolyDataSource); static iBoundedDiskSource* New(iViewSubject *vo = 0); void SetWithArrow(bool s); inline bool GetWithArrow() const { return mWithArrow; } protected: iBoundedDiskSource(iViewSubject *vo); virtual ~iBoundedDiskSource(); virtual void UpdateBoundaryConditions(); virtual void UpdateSourceResolution(); virtual void AddObserverToSource(unsigned long e, vtkCommand *c, float priority); virtual float GetSourceMemorySize() const; private: // // VTK stuff // vtkDiskSource *mSource; vtkPolyDataNormals *mPointNormals; vtkAppendPolyData *mAppendPolyData; vtkArrowSource *mArrowSource; vtkTransformPolyDataFilter *mTransformPolyDataFilter; bool mWithArrow; }; #endif // IBOUNDEDDISKSOURCE_H ifrit-3.4.2/core/iboundedplanesource.cpp0000755000175700010010000000456412167404425016711 0ustar HomeNone/*========================================================================= Program: Ionization FRont Interactive Tool (IFRIT) Language: C++ Copyright (c) 2002-2012 Nick Gnedin All rights reserved. This file may be distributed and/or modified under the terms of the GNU General Public License version 2 as published by the Free Software Foundation and appearing in the file LICENSE.GPL included in the packaging of this file. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHORS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. =========================================================================*/ #include "iboundedplanesource.h" #include "ierror.h" #include #include #include // // iBoundedPlaneSource class // iBoundedPlaneSource* iBoundedPlaneSource::New(iViewSubject *vo) { IERROR_ASSERT(vo); return new iBoundedPlaneSource(vo); } iBoundedPlaneSource::iBoundedPlaneSource(iViewSubject *vo) : iBoundedPolyDataSource(vo,true,false) { mSource = vtkPlaneSource::New(); IERROR_ASSERT(mSource); mSource->SetOrigin(0.0,0.0,0.0); mSource->SetPoint1(7.0,0.0,0.0); mSource->SetPoint2(0.0,7.0,0.0); mSource->SetCenter(0.0,0.0,0.0); mFilter->SetInput(mSource->GetOutput()); } iBoundedPlaneSource::~iBoundedPlaneSource() { mSource->Delete(); } void iBoundedPlaneSource::AddObserverToSource(unsigned long e, vtkCommand *c, float p) { mSource->AddObserver(e,c,p); } void iBoundedPlaneSource::UpdateSourceResolution() { mSource->SetResolution(mResolution,mResolution); } float iBoundedPlaneSource::GetSourceMemorySize() const { float s = 0.0; s += mSource->GetOutput()->GetActualMemorySize(); return s; } void iBoundedPlaneSource::UpdateBoundaryConditions() { } ifrit-3.4.2/core/iboundedplanesource.h0000755000175700010010000000366312167404406016354 0ustar HomeNone/*========================================================================= Program: Ionization FRont Interactive Tool (IFRIT) Language: C++ Copyright (c) 2002-2012 Nick Gnedin All rights reserved. This file may be distributed and/or modified under the terms of the GNU General Public License version 2 as published by the Free Software Foundation and appearing in the file LICENSE.GPL included in the packaging of this file. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHORS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. =========================================================================*/ #ifndef IBOUNDEDPLANESOURCE_H #define IBOUNDEDPLANESOURCE_H #include "iboundedpolydatasource.h" class vtkPlaneSource; class iBoundedPlaneSource : public iBoundedPolyDataSource { public: vtkTypeMacro(iBoundedPlaneSource,iBoundedPolyDataSource); static iBoundedPlaneSource* New(iViewSubject *vo = 0); protected: iBoundedPlaneSource(iViewSubject *vo); virtual ~iBoundedPlaneSource(); virtual void UpdateBoundaryConditions(); virtual void UpdateSourceResolution(); virtual void AddObserverToSource(unsigned long e, vtkCommand *c, float priority); virtual float GetSourceMemorySize() const; private: // // VTK stuff // vtkPlaneSource *mSource; }; #endif // IBOUNDEDPLANESOURCE_H ifrit-3.4.2/core/iboundedpolydatasource.cpp0000755000175700010010000001071512167404425017422 0ustar HomeNone/*========================================================================= Program: Ionization FRont Interactive Tool (IFRIT) Language: C++ Copyright (c) 2002-2012 Nick Gnedin All rights reserved. This file may be distributed and/or modified under the terms of the GNU General Public License version 2 as published by the Free Software Foundation and appearing in the file LICENSE.GPL included in the packaging of this file. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHORS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. =========================================================================*/ #include "iboundedpolydatasource.h" #include "idatalimits.h" #include "ierror.h" #include "itransform.h" #include "iviewmodule.h" #include #include #include #include #include #include // // Templates // #include "igenericfiltertemplate.h" // // iBoundedPolyDataSource class // iBoundedPolyDataSource::iBoundedPolyDataSource(iViewSubject *vo, bool normalCanChange, bool radiusCanChange) : iGenericSource(vo,true), mNormalCanChange(normalCanChange), mRadiusCanChange(radiusCanChange) { mTransform = iTransform::New(); IERROR_ASSERT(mTransform); mClipper = vtkClipPolyData::New(); IERROR_ASSERT(mClipper); mClipPlanes = vtkPlanes::New(); IERROR_ASSERT(mClipPlanes); mFilter = vtkTransformPolyDataFilter::New(); IERROR_ASSERT(mFilter); mClipper->SetClipFunction(mClipPlanes); mClipper->InsideOutOn(); mFilter->SetTransform(mTransform); mTransform->PreMultiply(); mRadius = 1.0; mCenter[0] = mCenter[1] = mCenter[2] = 0.0; mNormal[0] = mNormal[1] = 0.0f; mNormal[2] = 1.0f; mResolution = 6; mBounds[0] = mBounds[2] = mBounds[4] = -1.0; mBounds[1] = mBounds[3] = mBounds[5] = 1.0; mClipPlanes->SetBounds(mBounds); mNormalChanged = true; mClipper->SetInput(mFilter->GetOutput()); } iBoundedPolyDataSource::~iBoundedPolyDataSource() { mClipper->Delete(); mClipPlanes->Delete(); mTransform->Delete(); mFilter->Delete(); } unsigned long iBoundedPolyDataSource::AddObserver(unsigned long e, vtkCommand *c, float p) { this->AddObserverToSource(e,c,p); mFilter->AddObserver(e,c,p); return mClipper->AddObserver(e,c,p); } void iBoundedPolyDataSource::SetResolution(int r) { if(r > 0) { mResolution = r; this->UpdateSourceResolution(); this->Modified(); } } void iBoundedPolyDataSource::SetCenter(const double x[3]) { int i; for(i=0; i<3; i++) mCenter[i] = x[i]; this->Modified(); } void iBoundedPolyDataSource::SetNormal(const float n[3]) { int i; for(i=0; i<3; i++) mNormal[i] = n[i]; vtkMath::Normalize(mNormal); mNormalChanged = true; this->Modified(); } void iBoundedPolyDataSource::SetRadius(double r) { if(r > 0.0) { mRadius = r; this->Modified(); } } void iBoundedPolyDataSource::SetBounds(double b0, double b1, double b2, double b3, double b4, double b5) { mBounds[0] = b0; mBounds[1] = b1; mBounds[2] = b2; mBounds[3] = b3; mBounds[4] = b4; mBounds[5] = b5; mClipPlanes->SetBounds(mBounds); this->Modified(); } void iBoundedPolyDataSource::ProduceOutput() { vtkPolyData *output = this->GetOutput(); mTransform->Identity(); if(vtkMath::Norm(mCenter) > 1.0e-30) { mTransform->Translate(mCenter); mFilter->Modified(); } if(mRadiusCanChange && fabs(mRadius-1.0)>1.0e-10) { mTransform->Scale(mRadius,mRadius,mRadius); mFilter->Modified(); } if(mNormalCanChange && mNormalChanged) { mTransform->SetDirection(mNormal); } this->UpdateBoundaryConditions(); mClipper->Update(); output->ShallowCopy(mClipper->GetOutput()); } float iBoundedPolyDataSource::GetMemorySize() const { float s = 0.0; s += mClipper->GetOutput()->GetActualMemorySize(); s += mFilter->GetOutput()->GetActualMemorySize(); s += this->GetSourceMemorySize(); return s; } ifrit-3.4.2/core/iboundedpolydatasource.h0000755000175700010010000000571412167404406017071 0ustar HomeNone/*========================================================================= Program: Ionization FRont Interactive Tool (IFRIT) Language: C++ Copyright (c) 2002-2012 Nick Gnedin All rights reserved. This file may be distributed and/or modified under the terms of the GNU General Public License version 2 as published by the Free Software Foundation and appearing in the file LICENSE.GPL included in the packaging of this file. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHORS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. =========================================================================*/ #ifndef IBOUNDEDPOLYDATASOURCE_H #define IBOUNDEDPOLYDATASOURCE_H #include "igenericfilter.h" #include class iLimits; class iTransform; class vtkClipPolyData; class vtkPlanes; class vtkTransformPolyDataFilter; class iBoundedPolyDataSource : public iGenericSource { public: vtkTypeMacro(iBoundedPolyDataSource,vtkPolyDataSource); unsigned long AddObserver(unsigned long e, vtkCommand *c, float priority = 0.0); void SetCenter(const double x[3]); inline const double* GetCenter() const { return mCenter; } void SetResolution(int r); inline int GetResolution() const { return mResolution; } void SetBounds(double b0, double b1, double b2, double b3, double b4, double b5); inline const double* GetBounds() const { return mBounds; } void SetRadius(double r); inline double GetRadius() const { return mRadius; } void SetNormal(const float n[3]); inline const float* GetNormal() const { return mNormal; } float GetMemorySize() const; protected: iBoundedPolyDataSource(iViewSubject *vo, bool normalCanChange, bool radiusCanChange); virtual ~iBoundedPolyDataSource(); virtual void ProduceOutput(); virtual void UpdateBoundaryConditions() = 0; virtual void UpdateSourceResolution() = 0; virtual void AddObserverToSource(unsigned long e, vtkCommand *c, float priority) = 0; virtual float GetSourceMemorySize() const = 0; double mBounds[6]; double mCenter[3], mRadius; int mResolution; float mNormal[3]; bool mNormalChanged; const bool mNormalCanChange, mRadiusCanChange; // // VTK stuff // iTransform *mTransform; vtkPlanes *mClipPlanes; vtkClipPolyData *mClipper; vtkTransformPolyDataFilter *mFilter; }; #endif // IBOUNDEDPOLYDATASOURCE_H ifrit-3.4.2/core/iboundedspheresource.cpp0000755000175700010010000001001012167404425017057 0ustar HomeNone/*========================================================================= Program: Ionization FRont Interactive Tool (IFRIT) Language: C++ Copyright (c) 2002-2012 Nick Gnedin All rights reserved. This file may be distributed and/or modified under the terms of the GNU General Public License version 2 as published by the Free Software Foundation and appearing in the file LICENSE.GPL included in the packaging of this file. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHORS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. =========================================================================*/ #include "iboundedspheresource.h" #include "idatalimits.h" #include "ierror.h" #include "iviewmodule.h" #include #include #include #include // // iBoundedSphereSource class // iBoundedSphereSource* iBoundedSphereSource::New(iViewSubject *vo) { IERROR_ASSERT(vo); return new iBoundedSphereSource(vo); } iBoundedSphereSource::iBoundedSphereSource(iViewSubject *vo) : iBoundedPolyDataSource(vo,false,true) { mAppend = vtkAppendPolyData::New(); IERROR_ASSERT(mAppend); for(int i=0; i<8; i++) { mSource[i] = vtkSphereSource::New(); IERROR_ASSERT(mSource[i]); } mAppend->UserManagedInputsOn(); mAppend->SetInputByNumber(0,mSource[0]->GetOutput()); mSource[0]->SetCenter(0.0,0.0,0.0); mSource[0]->SetPhiResolution(mResolution); mSource[0]->SetThetaResolution(2*mResolution); mSource[0]->SetRadius(1.0); mFilter->SetInput(mSource[0]->GetOutput()); } iBoundedSphereSource::~iBoundedSphereSource() { mAppend->Delete(); for(int i=0; i<8; i++) { mSource[i]->Delete(); } } void iBoundedSphereSource::AddObserverToSource(unsigned long e, vtkCommand *c, float p) { mAppend->AddObserver(e,c,p); for(int i=0; i<8; i++) { mSource[i]->AddObserver(e,c,p); } } void iBoundedSphereSource::UpdateSourceResolution() { mSource[0]->SetPhiResolution(mResolution); mSource[0]->SetThetaResolution(2*mResolution); } float iBoundedSphereSource::GetSourceMemorySize() const { float s = 0.0; for(int i=0; i<8; i++) { s += mSource[i]->GetOutput()->GetActualMemorySize(); } s += mAppend->GetOutput()->GetActualMemorySize(); return s; } void iBoundedSphereSource::UpdateBoundaryConditions() { int i, j, l, side[3]; double cen[3], xb; if(this->GetLimits()==0 || !this->GetLimits()->IsBoxPeriodic()) { mFilter->SetInput(mSource[0]->GetOutput()); return; } bool per[3]; this->GetLimits()->GetPeriodicities(per); // // Test for out-of-bounds pieces // for(i=0; i<3; i++) { side[i] = 0; if(per[i]) { xb = mCenter[i] - mRadius; if(xb < mBounds[2*i+0]) side[i] = -1; // we should only cross one boundary xb = mCenter[i] + mRadius; if(xb > mBounds[2*i+1]) side[i] = 1; } } if(side[0]==0 && side[1]==0 && side[2]==0) { // // Fully inside // mFilter->SetInput(mSource[0]->GetOutput()); return; } mFilter->SetInput(mAppend->GetOutput()); l = 1; for(i=0; i<3; i++) { if(side[i] != 0) { mAppend->SetNumberOfInputs(2*l); for(j=l; j<2*l; j++) { mSource[j]->SetRadius(1.0); mSource[j]->SetPhiResolution(mResolution); mSource[j]->SetThetaResolution(2*mResolution); mSource[j-l]->GetCenter(cen); cen[i] -= 2.0*side[i]/mRadius; mSource[j]->SetCenter(cen); mAppend->SetInputByNumber(j,mSource[j]->GetOutput()); } l *= 2; } } } ifrit-3.4.2/core/iboundedspheresource.h0000755000175700010010000000402312167404406016532 0ustar HomeNone/*========================================================================= Program: Ionization FRont Interactive Tool (IFRIT) Language: C++ Copyright (c) 2002-2012 Nick Gnedin All rights reserved. This file may be distributed and/or modified under the terms of the GNU General Public License version 2 as published by the Free Software Foundation and appearing in the file LICENSE.GPL included in the packaging of this file. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHORS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. =========================================================================*/ #ifndef IBOUNDEDSPHERESOURCE_H #define IBOUNDEDSPHERESOURCE_H #include "iboundedpolydatasource.h" class vtkAppendPolyData; class vtkSphereSource; class iBoundedSphereSource : public iBoundedPolyDataSource { public: vtkTypeMacro(iBoundedSphereSource,iBoundedPolyDataSource); static iBoundedSphereSource* New(iViewSubject *vo = 0); protected: iBoundedSphereSource(iViewSubject *vo); virtual ~iBoundedSphereSource(); virtual void UpdateBoundaryConditions(); virtual void UpdateSourceResolution(); virtual void AddObserverToSource(unsigned long e, vtkCommand *c, float priority); virtual float GetSourceMemorySize() const; private: // // VTK stuff // vtkAppendPolyData *mAppend; vtkSphereSource *mSource[8]; // 8 of them for periodic BC }; #endif // IBOUNDEDSPHERESOURCE_H ifrit-3.4.2/core/ibuffer.h0000644000175700010010000000337012167404406013734 0ustar HomeNone/*========================================================================= Program: Ionization FRont Interactive Tool (IFRIT) Language: C++ Copyright (c) 2002-2012 Nick Gnedin All rights reserved. This file may be distributed and/or modified under the terms of the GNU General Public License version 2 as published by the Free Software Foundation and appearing in the file LICENSE.GPL included in the packaging of this file. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHORS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. =========================================================================*/ #ifndef IBUFFER_H #define IBUFFER_H // // Adjustable buffer (piece of memory) of type T. There is no out-of-boundary checking // like in iArray // template class iBuffer { public: iBuffer(); ~iBuffer(); void Reset(bool fill0); void Extend(int s); void Fill(const T* ptr, int size); // fast fill T& operator[](int i); inline const T& operator[](int i) const { return this->mArr[i]; } inline operator T*() const { return this->mArr; } private: T* mArr; int mLen; }; #endif // IBUFFER_H ifrit-3.4.2/core/ibuffertemplate.h0000755000175700010010000000433512167404406015475 0ustar HomeNone/*========================================================================= Program: Ionization FRont Interactive Tool (IFRIT) Language: C++ Copyright (c) 2002-2012 Nick Gnedin All rights reserved. This file may be distributed and/or modified under the terms of the GNU General Public License version 2 as published by the Free Software Foundation and appearing in the file LICENSE.GPL included in the packaging of this file. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHORS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. =========================================================================*/ #include "ibuffer.h" #include "ierror.h" template iBuffer::iBuffer() { this->mLen = 100; this->mArr = new T[this->mLen]; IERROR_ASSERT(this->mArr); } template iBuffer::~iBuffer() { delete [] this->mArr; } template void iBuffer::Reset(bool fill0) { delete [] this->mArr; this->mLen = 100; this->mArr = new T[this->mLen]; IERROR_ASSERT(this->mArr); if(fill0) memset(this->mArr,0,this->mLen*sizeof(T)); } template T& iBuffer::operator[](int i) { if(i >= this->mLen) this->Extend(i+1); return this->mArr[(i<0)?0:i]; } template void iBuffer::Fill(const T* ptr, int size) { int i; if(size > this->mLen) this->Extend(size); for(i=0; imArr[i] = ptr[i]; // we cannot use memcpy here because = is not necessarily a simple memory copy } template void iBuffer::Extend(int s) { if(s > this->mLen) { delete [] this->mArr; this->mLen = s; mArr = new T[this->mLen]; IERROR_ASSERT(mArr); } } ifrit-3.4.2/core/icalculator.h0000755000175700010010000000450712167404406014622 0ustar HomeNone/*========================================================================= Program: Ionization FRont Interactive Tool (IFRIT) Language: C++ Copyright (c) 2002-2012 Nick Gnedin All rights reserved. This file may be distributed and/or modified under the terms of the GNU General Public License version 2 as published by the Free Software Foundation and appearing in the file LICENSE.GPL included in the packaging of this file. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHORS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. =========================================================================*/ #ifndef ICALCULATOR_H #define ICALCULATOR_H #include "icalculatorbase.h" namespace iCalculatorKit { template class DataVariable; template class var; template class ptr; }; template class iCalculator : public iCalculatorBase { public: typedef T number_t; typedef iCalculatorKit::DataVariable result_t; typedef iCalculatorKit::var real_var; typedef iCalculatorKit::var bool_var; typedef iCalculatorKit::ptr real_ptr; typedef iCalculatorKit::ptr bool_ptr; iCalculator(); inline const result_t* GetResult() { return static_cast(this->Result()); } const T* GetResultData() const; int GetResultSize() const; void AddVariable(const result_t *var); // this ensures type correctness protected: virtual iCalculatorKit::Variable* CreateLiteral(const iString &str) const; virtual iCalculatorKit::Function* CreateFunction(const iString &str, int loc) const; #ifdef I_DEBUG virtual void PrintStack(int iptr, int narg, int jmax, iCalculatorKit::Variable** stack); #endif }; #endif // ICALCULATOR_H ifrit-3.4.2/core/icalculatorbase.cpp0000755000175700010010000003426012167404425016010 0ustar HomeNone/*========================================================================= Program: Ionization FRont Interactive Tool (IFRIT) Language: C++ Copyright (c) 2002-2012 Nick Gnedin All rights reserved. This file may be distributed and/or modified under the terms of the GNU General Public License version 2 as published by the Free Software Foundation and appearing in the file LICENSE.GPL included in the packaging of this file. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHORS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. =========================================================================*/ #include "icalculatorbase.h" #include "icalculatorkit.h" #include "icalculatorparser.h" #include "ierror.h" // // Templates // #include "iarraytemplate.h" #include "ibuffertemplate.h" using namespace iCalculatorKit; iCalculatorBase::iCalculatorBase() { mParser = 0; mErrorPosition = -1; mTrapFPE = false; mResult = 0; mStatus = 0; mResultVariable = 0; } iCalculatorBase::~iCalculatorBase() { this->Reset(); if(mParser != 0) delete mParser; } void iCalculatorBase::Reset() { mStatus = 0; mResult = 0; mCode.Clear(); mUsedVars.Clear(); while(mDataStack.Size() > 0) delete mDataStack.RemoveLast(); while(mCallStack.Size() > 0) delete mCallStack.RemoveLast(); while(mLiterals.Size() > 0) delete mLiterals.RemoveLast(); } void iCalculatorBase::SetResultVariable(iCalculatorKit::Variable *var) { if(mResultVariable != var) { mResultVariable = var; if(mStatus > 1) mStatus = 1; // make sure we re-link if this is changed } } void iCalculatorBase::SetResultVariable(iCalculatorKit::Variable &var) { this->SetResultVariable(&var); } void iCalculatorBase::SetTrapFPE(bool s) { if(mTrapFPE != s) { mTrapFPE = s; mStatus = 0; // make sure we re-compile if this is changed } } void iCalculatorBase::AddVariable(const iCalculatorKit::Variable *var) { if(var!=0 && !var->Name().IsEmpty()) { mVariables.Add(var); } } void iCalculatorBase::RemoveVariable(const iString &name) { if(!name.IsEmpty()) { int i; for(i=mVariables.MaxIndex(); i>=0; i--) // variables are always looped over in the reverse order to insure proper name resolution { if(mVariables[i]->Name() == name) { mVariables.Remove(i); return; // remove one at a time } } } } void iCalculatorBase::SetError(const iString &message, int pos) { mErrorMessage = message; mErrorPosition = pos; this->SetErrorExtra(message,pos); this->Reset(); } // // Overwritable method for extending // iCalculatorParser* iCalculatorBase::CreateParser() const { return new iCalculatorParser(false); // Create the default parser } void iCalculatorBase::SetErrorExtra(const iString &, int) { // // Nothing to do here // } iString iCalculatorBase::ReportRunTimeErrorExtra(int, const iCalculatorKit::Function *) { return "unknown error"; } // // Punctuation symbols // const iString& iCalculatorBase::SymbolSeparator() const { if(mParser == 0) { mParser = this->CreateParser(); IERROR_ASSERT(mParser); } return mParser->SymbolSeparator(); } const iString& iCalculatorBase::SymbolOpeningBraket() const { if(mParser == 0) { mParser = this->CreateParser(); IERROR_ASSERT(mParser); } return mParser->SymbolOpeningBraket(); } const iString& iCalculatorBase::SymbolClosingBraket() const { if(mParser == 0) { mParser = this->CreateParser(); IERROR_ASSERT(mParser); } return mParser->SymbolClosingBraket(); } const iString& iCalculatorBase::SymbolOpeningParenthesis() const { if(mParser == 0) { mParser = this->CreateParser(); IERROR_ASSERT(mParser); } return mParser->SymbolOpeningParenthesis(); } const iString& iCalculatorBase::SymbolClosingParenthesis() const { if(mParser == 0) { mParser = this->CreateParser(); IERROR_ASSERT(mParser); } return mParser->SymbolClosingParenthesis(); } bool iCalculatorBase::IsValidVariableName(const iString &name) const { if(name.IsEmpty()) return false; if(mParser == 0) { mParser = this->CreateParser(); IERROR_ASSERT(mParser); } int i; bool ok = true; if(!mParser->IsVariableFirstLetter(name[0])) ok = false; for(i=1; ok && iIsVariableLetter(name[i])) { ok = false; break; } return ok; } // // Main workers // bool iCalculatorBase::Evaluate(const iString &expr) { if(!this->Compile(expr)) return false; if(!this->Link()) return false; return this->Execute(); } bool iCalculatorBase::Compile(const iString &expr) { if(mParser == 0) { mParser = this->CreateParser(); IERROR_ASSERT(mParser); } if(!mParser->Parse(expr)) { mCode.Clear(); this->SetError(mParser->GetErrorMessage(),mParser->GetErrorPosition()); return false; } if(mParser->GetPseudoCode() != mCode) // Need to re-compile. { this->Reset(); mErrorMessage.Clear(); mErrorPosition = -1; // // First, create the stack. // mCode = mParser->GetPseudoCode(); int i = 0; while(i < mCode.Length()) { if(!this->CompileToken(i)) { return false; } } if(mDataStack.Size() < 1) { this->SetError("Usage error: cannot evaluate empry expression.",0); return false; } } mStatus = 1; return true; } bool iCalculatorBase::CompileToken(int &index) { iString w; int i2, i3, i1 = index; Handle *h; Variable *var; Function *fun; // // Add one handle // if(mCode.Find(mParser->TokenBeg(),i1) != i1) { this->SetError("Internal error: pseudo-code is corrupted.",i1); return false; } i1 += mParser->TokenBeg().Length(); // // A literal // if(mCode.Find(mParser->TokenNum(),i1) == i1) { i1 += mParser->TokenFun().Length(); i2 = mCode.Find(mParser->TokenEnd(),i1); if(i2 == -1) { this->SetError("Internal error: pseudo-code is corrupted.",i1); return false; } w = mCode.Part(i1,i2-i1); var = this->CreateLiteral(w); if(var == 0) { this->SetError("Internal error: unable to convert string {"+w+"} into a literal value, or there is not enough memory to proceed.",i1); return false; } h = new Handle(var); if(h == 0) { this->SetError("There is not enough memory to proceed.",-1); return false; } mLiterals.Add(var); mDataStack.Add(h); index = i2 + mParser->TokenEnd().Length(); return true; } // // A variable // if(mCode.Find(mParser->TokenVar(),i1) == i1) { i1 += mParser->TokenFun().Length(); i2 = mCode.Find(mParser->TokenEnd(),i1); if(i2 == -1) { this->SetError("Internal error: pseudo-code is corrupted.",i1); return false; } w = mCode.Part(i1,i2-i1); h = new Handle(w); if(h == 0) { this->SetError("There is not enough memory to proceed.",-1); return false; } mDataStack.Add(h); index = i2 + mParser->TokenEnd().Length(); if(mUsedVars.IsEmpty()) mUsedVars += w; else mUsedVars += "," + w; return true; } // // A function // if(mCode.Find(mParser->TokenFun(),i1) == i1) { i1 += mParser->TokenFun().Length(); i2 = mCode.Find(mParser->TokenBeg(),i1); i3 = mCode.Find(mParser->TokenEnd(),i1); if(i2==-1 && i3==-1) { this->SetError("Internal error: pseudo-code is corrupted.",i1); return false; } if(i2==-1 || i3CreateFunction(w,mDataStack.Size()); if(fun == 0) { this->SetError("Syntax error: {"+w+"} is not a name of a valid function.",-1); return false; } h = new Handle(fun->Result()); if(h == 0) { this->SetError("There is not enough memory to proceed.",-1); return false; } mCallStack.Add(fun); mDataStack.Add(h); // // Compile function arguments // iString w1; int narg = 0; while(mParser->FindCompleteTokenToRight(mCode,w1,i2-1) >= i2) { if(!this->CompileToken(i2)) return false; narg++; } // // Verify the number of arguments for this function // if(fun->NumArguments()>-1 && narg!=fun->NumArguments()) { this->SetError("Syntax error: incorrect number of arguments for function {"+w+"}. This function only accepts "+iString::FromNumber(fun->NumArguments())+" arguments.",i2); return false; } if(fun->NumArguments() == -1) fun->SetNumArguments(narg); if(i2 != mCode.Find(mParser->TokenEnd(),i2)) { this->SetError("Internal error: pseudo-code is corrupted.",i2); return false; } index = i2 + mParser->TokenEnd().Length(); return true; } this->SetError("Internal error: pseudo-code is corrupted.",index); return false; } // // This is for extending (used in scripts) // const Variable* iCalculatorBase::FindExternalVariable(const iString &) const { return 0; } const Variable* iCalculatorBase::FindVariable(const iString &name) const { int i; for(i=mVariables.MaxIndex(); i>=0; i--) // variables are always looped over in the reverse order to insure proper name resolution { if(mVariables[i]->Name() == name) return mVariables[i]; } // // If we don't own this variable, check external variables (used if we are used inside a script) // return this->FindExternalVariable(name); } bool iCalculatorBase::Link() { if(mStatus < 1) { this->SetError("Usage error: trying to link the expression before it is compiled.",-1); return false; } if(mStatus >= 2) return true; // already linked // // Make sure that all variable handles are satisfied. // int i, id; const Variable *var; for(id=0; idSelf() == 0) { var = this->FindVariable(mDataStack[id]->Name()); if(var == 0) { this->SetError("Link error: variable {"+mDataStack[id]->Name()+"} has not been defined.",-1); return false; } mDataStack[id]->Attach(var); } // // Now check that all dimensions and usages are consistent. // For that, we need to use a temporary value stack that changes as we "execute". // mBuffer.Extend(mDataStack.Size()); mSavedBuffer.Extend(mDataStack.Size()); for(id=0; idSelf(); memcpy(mBuffer,mSavedBuffer,mDataStack.Size()*sizeof(Variable*)); // // Now go down the stack, as if we were evaluating the expression. // int ic, iptr, narg; iString err; iBuffer dims; iBuffer uses; id = mDataStack.MaxIndex(); for(ic=mCallStack.MaxIndex(); ic>=0; ic--) { iptr = mCallStack[ic]->DataLocation(); narg = mCallStack[ic]->NumArguments(); if(iptr+narg > id) // Under normal circumstances, this should never happen. { this->SetError("Internal error: the data stack is corrupted.",ic); return false; } iptr++; for(i=0; iDim(); uses[i] = mBuffer[iptr+i]->Use(); } if(!mCallStack[ic]->CheckArguments(dims,uses,err)) { if(err.IsEmpty()) { this->SetError("Link error: dimensions and/or usage patterns of arguments for function {"+mDataStack[iptr-1]->Name()+"} are not compatible.",-1); } else { this->SetError("Link error for function {"+mDataStack[iptr-1]->Name()+"}: "+err+".",-1); } return false; } // // We are fine, compress the stack // for(i=iptr+narg; i<=id; i++) mBuffer[i-narg] = mBuffer[i]; id -= narg; } // // At the end, we should end up with a single value in the stack. // if(id > 0) { this->SetError("Internal error: the result of the execution is not a single value.",id); return false; } if(mResultVariable != 0) { if(mResultVariable->Dim() != mBuffer[0]->Dim()) { this->SetError("Usage error: the dimension of the result variable (" + iString::FromNumber(mResultVariable->Dim()) + ") is not compatible with the dimension of the expression (" + iString::FromNumber(mBuffer[0]->Dim())+").",-1); return false; } if(mResultVariable->Use() != mBuffer[0]->Use()) { this->SetError("Usage error: the usage pattern of the result variable (" + iString::FromNumber(mResultVariable->Use()) + ") is not compatible with the usage pattern of the expression (" + iString::FromNumber(mBuffer[0]->Use())+").",-1); return false; } } mResult = mBuffer[0]; mStatus = 2; return true; } bool iCalculatorBase::Execute() { if(mStatus < 2) { this->SetError("Usage error: trying to execute the expression before it is compiled and linked.",-1); return false; } // // Create the run-time stack. // memcpy(mBuffer,mSavedBuffer,mDataStack.Size()*sizeof(Variable*)); // // Now go down the stack and evaluate the expression. // int i, id, ic, iptr, narg; id = mDataStack.MaxIndex(); iCalculatorKit::Function* const *callStack = mCallStack.Data(); // cache for speed iCalculatorKit::Variable* *dataStack = mBuffer; // cache for speed #ifdef I_DEBUG // this->PrintStack(0,0,id,dataStack); #endif for(ic=mCallStack.MaxIndex(); ic>=0; ic--) { iptr = callStack[ic]->DataLocation() + 1; narg = callStack[ic]->NumArguments(); i = callStack[ic]->Evaluate(dataStack+iptr); if(i != 0) { this->ReportRunTimeError(i,callStack[ic]); return false; } // // We are fine, compress the stack // for(i=iptr+narg; i<=id; i++) dataStack[i-narg] = dataStack[i]; id -= narg; #ifdef I_DEBUG // this->PrintStack(iptr,narg,id,dataStack); #endif } if(mResultVariable != 0) { if(!mResultVariable->Copy(*mResult)) { this->SetError("Run-time error: unable to copy the result into the result variable;",-1); return false; } } mStatus = 3; return true; } void iCalculatorBase::ReportRunTimeError(int ierr, const Function* caller) { iString err; switch(ierr) { case 1: { err = "indexing vector outside the bounds"; break; } case 2: { err = "floating-point exception (division by zero, invalid function argument, etc)"; break; } default: { err = this->ReportRunTimeErrorExtra(ierr,caller); break; } } this->SetError("Run-time error in function {"+caller->Result()->Name()+"} : "+err,-1); } ifrit-3.4.2/core/icalculatorbase.h0000755000175700010010000001261612167404406015455 0ustar HomeNone/*========================================================================= Program: Ionization FRont Interactive Tool (IFRIT) Language: C++ Copyright (c) 2002-2012 Nick Gnedin All rights reserved. This file may be distributed and/or modified under the terms of the GNU General Public License version 2 as published by the Free Software Foundation and appearing in the file LICENSE.GPL included in the packaging of this file. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHORS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. =========================================================================*/ #ifndef ICALCULATORBASE_H #define ICALCULATORBASE_H #include "iarray.h" #include "ibuffer.h" #include "istring.h" class iCalculatorParser; namespace iCalculatorKit { class Handle; class Variable; class Function; }; class iCalculatorBase { public: iCalculatorBase(); virtual ~iCalculatorBase(); // // If set, the result is always copied into it. Calculator does not own it, so it is not destroyed when the calculator is destroyed. // If this is set, the calculator needs to be re-linked. The usage and dimension of the variable should correspond to the usage and // dimension of the result; if they not, an error will be generated (i.e. calculator will not re-format the variable). Use zero to unset it. // void SetResultVariable(iCalculatorKit::Variable *var); void SetResultVariable(iCalculatorKit::Variable &var); // // Do all at once // bool Evaluate(const iString &expr); // // Step-by-step work // bool Compile(const iString &expr); bool Link(); bool Execute(); // // Get the list of used variables // inline const iString& ListUsedVariables() const { return mUsedVars; } // // Floating-point exceptions // void SetTrapFPE(bool s); inline bool GetTrapFPE() const { return mTrapFPE; } // // Get the error message and position // inline const iString& GetErrorMessage() const { return mErrorMessage; } inline int GetErrorPosition() const { return mErrorPosition; } // // Remove a variable with a given name. It removes the last added variable with this name, thus uncovering the previous one. // This allows to implement name resolution: adding a (local) variable with the same name as an already existing one will hide // the existing variable until the local variable is removed. Variables are not actually deleted, just removed from the calculator list. // void RemoveVariable(const iString &name); // // Reset to the empty state // void Reset(); // // Parser punctuation symbols // const iString& SymbolSeparator() const; const iString& SymbolOpeningBraket() const; const iString& SymbolClosingBraket() const; const iString& SymbolOpeningParenthesis() const; const iString& SymbolClosingParenthesis() const; bool IsValidVariableName(const iString &name) const; protected: inline iCalculatorKit::Variable* Result() const { return mResult; } // // Add a variable to use in the expression. Calculator does not own variables, they must be created/destroyed outside this class. // We keep this protected so that a child must replace it - otherwise it would be possible to add variables of one data type to a // calculator of a different data type. // void AddVariable(const iCalculatorKit::Variable *var); // // Set the error message; also allow for extending this call. // void SetError(const iString &message, int pos); virtual void SetErrorExtra(const iString &message, int pos); virtual iString ReportRunTimeErrorExtra(int ierr, const iCalculatorKit::Function *caller); // // Inheritable methods for extending // virtual iCalculatorParser* CreateParser() const; virtual iCalculatorKit::Variable* CreateLiteral(const iString &str) const = 0; virtual iCalculatorKit::Function* CreateFunction(const iString &str, int loc) const = 0; virtual const iCalculatorKit::Variable* FindExternalVariable(const iString &name) const; #ifdef I_DEBUG virtual void PrintStack(int iptr, int narg, int jmax, iCalculatorKit::Variable** stack) = 0; #endif private: void ReportRunTimeError(int ierr, const iCalculatorKit::Function *caller); bool CompileToken(int &index); bool CheckFunction(int index, int &stackptr); const iCalculatorKit::Variable* FindVariable(const iString &name) const; int mErrorPosition; iString mErrorMessage; bool mTrapFPE; iString mCode, mUsedVars; mutable iCalculatorParser *mParser; int mStatus; iCalculatorKit::Variable *mResult, *mResultVariable; iArray mDataStack; iArray mCallStack; iBuffer mBuffer, mSavedBuffer; // pre-allocated buffers to avoid memory allocation during execution iArray mVariables; iArray mLiterals; }; #endif // ICALCULATORBASE_H ifrit-3.4.2/core/icalculatorkit.cpp0000755000175700010010000000457212167404425015670 0ustar HomeNone/*========================================================================= Program: Ionization FRont Interactive Tool (IFRIT) Language: C++ Copyright (c) 2002-2012 Nick Gnedin All rights reserved. This file may be distributed and/or modified under the terms of the GNU General Public License version 2 as published by the Free Software Foundation and appearing in the file LICENSE.GPL included in the packaging of this file. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHORS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. =========================================================================*/ #include "icalculatorkit.h" namespace iCalculatorKit { // // Handle // Handle::Handle(const iString &name) : mName(name), mVar(0) { } Handle::Handle(Variable *v) : mName(v->Name()), mVar(v) { } void Handle::Attach(const Variable *v) { if(mVar==0 && v!=0) { mVar = const_cast(v); // take away constness since handles also control internal, changeable variables mName = v->Name(); } } // // Variable // Variable::Variable(int dim, int use, const iString &name) : mDim(dim), mUse(use), mName(name) { } Variable::~Variable() { } bool Variable::Copy(const Variable &var) { if((mDim!=var.mDim || mUse!=var.mUse) && !this->Morph(var.mDim,var.mUse)) return false; this->CopyBody(var); return true; } bool Variable::Morph(int dim, int use) { if(!this->MorphBody(dim,use)) return false; mDim = dim; mUse = use; return true; } // // Function // Function::Function(Variable *result, int narg, int loc) : mResult(result), mNumArgs(narg), mDataLoc(loc) { } Function::~Function() { } void Function::SetNumArguments(int narg) { if(mNumArgs < 0) mNumArgs = narg; } }; ifrit-3.4.2/core/icalculatorkit.h0000755000175700010010000000601012167404407015322 0ustar HomeNone/*========================================================================= Program: Ionization FRont Interactive Tool (IFRIT) Language: C++ Copyright (c) 2002-2012 Nick Gnedin All rights reserved. This file may be distributed and/or modified under the terms of the GNU General Public License version 2 as published by the Free Software Foundation and appearing in the file LICENSE.GPL included in the packaging of this file. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHORS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. =========================================================================*/ #ifndef ICALCULATORKIT_H #define ICALCULATORKIT_H #include "istring.h" namespace iCalculatorKit { // // ********************************************************************** // // Generic interface // // ********************************************************************** // class Variable; class Handle { public: Handle(const iString &name); Handle(Variable *v); void Attach(const Variable *v); inline Variable* Self() const { return mVar; } inline const iString& Name() const { return mName; } private: iString mName; Variable *mVar; }; class Variable { public: virtual ~Variable(); inline int Dim() const { return mDim; } inline int Use() const { return mUse; } inline const iString& Name() const { return mName; } bool Copy(const Variable &var); bool Morph(int dim, int use); protected: Variable(int dim, int use, const iString &name); virtual void CopyBody(const Variable &var) = 0; virtual bool MorphBody(int dim, int use) = 0; private: int mDim, mUse; iString mName; }; class Function { public: virtual ~Function(); inline Variable* Result() const { return mResult; } inline int DataLocation() const { return mDataLoc; } inline int NumArguments() const { return mNumArgs; } // // There properties are set at link-time // void SetNumArguments(int narg); // // This function is called at link-time; it should also set the usage and dimension of the argument // virtual bool CheckArguments(int *dims, int *uses, iString &err) = 0; // // Main worker called at run-time // virtual int Evaluate(Variable **args) = 0; protected: Function(Variable *result, int narg, int loc); Variable *mResult; int mNumArgs; private: int mDataLoc; }; }; #endif // ICALCULATORKIT_H ifrit-3.4.2/core/icalculatorparser.cpp0000755000175700010010000005113412167404425016371 0ustar HomeNone/*========================================================================= Program: Ionization FRont Interactive Tool (IFRIT) Language: C++ Copyright (c) 2002-2012 Nick Gnedin All rights reserved. This file may be distributed and/or modified under the terms of the GNU General Public License version 2 as published by the Free Software Foundation and appearing in the file LICENSE.GPL included in the packaging of this file. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHORS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. =========================================================================*/ #include "icalculatorparser.h" // // Templates // #include "iarraytemplate.h" // // iCalculatorParser class // iCalculatorParser::iCalculatorParser(bool blank) { mMaxPriority = 0; mErrorPosition = -1; mExpression = "$undefined$"; // to check for null expressions if(!blank) { // // Mathematical operators // this->AddOperator("^","pow",7,true); this->AddOperator("*","mul",5,true); this->AddOperator("/","div",5,true); this->AddOperator("+","add",4,true); this->AddOperator("-","sub",4,true); this->AddOperator("-","neg",6,false); // // Logical operators // this->AddOperator("<","ltn",3,true); this->AddOperator(">","gtn",3,true); this->AddOperator("<=","leq",3,true); this->AddOperator(">=","geq",3,true); this->AddOperator("==","eql",2,true); this->AddOperator("!=","neq",2,true); this->AddOperator("&&","and",1,true); this->AddOperator("||","lor",1,true); this->AddOperator("!","not",6,false); // // Vector operators // this->AddOperator(".","dot",5,true); this->AddOperator("%","xrs",5,true); } } iCalculatorParser::~iCalculatorParser() { } bool iCalculatorParser::AddOperator(const iString& symbol, const iString& code, int priority, bool binary) { if(priority <= 0) return false; int i; for(i=0; iVerifyIntegrityHelper(this->TokenBeg())) return false; if(!this->VerifyIntegrityHelper(this->TokenEnd())) return false; if(!this->VerifyIntegrityHelper(this->TokenFun())) return false; if(!this->VerifyIntegrityHelper(this->TokenNum())) return false; if(!this->VerifyIntegrityHelper(this->TokenVar())) return false; int i; for(i=0; i mMaxPriority) mMaxPriority = mOperators[i].P; } return true; } bool iCalculatorParser::VerifyIntegrityHelper(const iString &token) { int i; for(i=0; iSymbolOpeningParenthesis()) return false; if(token == this->SymbolClosingParenthesis()) return false; if(token == this->SymbolSeparator()) return false; if(token == this->SymbolOpeningBraket()) return false; if(token == this->SymbolClosingBraket()) return false; return true; } // // Punctuation symbols // inline const iString& iCalculatorParser::SymbolOpeningParenthesis() const { static const iString self("("); return self; } inline const iString& iCalculatorParser::SymbolClosingParenthesis() const { static const iString self(")"); return self; } inline const iString& iCalculatorParser::SymbolSeparator() const { static const iString self(","); return self; } inline const iString& iCalculatorParser::SymbolOpeningBraket() const { static const iString self("["); return self; } inline const iString& iCalculatorParser::SymbolClosingBraket() const { static const iString self("]"); return self; } // // Pseudo-code tokens // inline const iString& iCalculatorParser::TokenBeg() const { static const iString self("{"); return self; } inline const iString& iCalculatorParser::TokenEnd() const { static const iString self("}"); return self; } inline const iString& iCalculatorParser::TokenFun() const { static const iString self("$"); return self; } inline const iString& iCalculatorParser::TokenNum() const { static const iString self("#"); return self; } inline const iString& iCalculatorParser::TokenVar() const { static const iString self("@"); return self; } // // Other functions // void iCalculatorParser::SetErrorExtra(const iString &, int) { // // Nothing to do here // } void iCalculatorParser::SetError(const iString &message, const iString &context, int pos) { mErrorMessage = "Syntax error: " + message; iString str(context); // // Reverse engineer the context // int i, j; iString w; while(mLog.Size() > 0) { // // Find the last match, since we parse from left to right always // w = mLog.Last().New; i = -1; while((j=str.Find(w,i+1)) != -1) i = j; if(i > -1) { if(i < pos) pos += (mLog.Last().Old.Length()-w.Length()); str.Replace(i,w.Length(),mLog.Last().Old); } mLog.RemoveLast().Clear(); } #ifdef I_DEBUG w = str.Part(pos); #endif mErrorPosition = mExpression.FindIgnoringWhiteSpace(str); if(mErrorPosition > -1) { // // Count out the correct location // int i, j=mErrorPosition; for(i=0; iSetErrorExtra(message,mErrorPosition); mCode.Clear(); mExpression.Clear(); } // // Text manipulation helpers. These helpers are fast and include no bound checking. // int iCalculatorParser::FindVariableToLeft(const iString &str, int index) const { if(index == 0) return 0; int in = index - 1; while(in>0 && this->IsVariableLetter(str[in])) in--; // keep going along word letters while(in>=0 && inIsVariableFirstLetter(str[in])) in++; // go back if we went too far return in; } int iCalculatorParser::FindVariableToRight(const iString &str, int index) const { int in = index + 1; int len = str.Length(); if(this->IsVariableFirstLetter(str[in])) // the first character after the white space must be a beginning of a word { while(inIsVariableLetter(str[in])) in++; } return --in; } int iCalculatorParser::FindLiteralToLeft(const iString &str, int index) const { int i = 0; while(iIsRecognizedLiteral(str,i,index-i)) i++; return i; } int iCalculatorParser::FindLiteralToRight(const iString &str, int index) const { index++; int len = str.Length() - index; while(len>0 && !this->IsRecognizedLiteral(str,index,len)) len--; return len + index - 1; } int iCalculatorParser::FindOperatorMatch(const iString &str, const iArray &ops, int index, int &kop) const { int k, j, js, jc = str.Length(); kop = -1; for(k=0; k-1 && (j-1 && ops[k].S.Length()>ops[kop].S.Length()))) // if we found a longer match at the same position, use it { // // Is this inside a decorated token? // if(this->IsInsideAToken(str,j)) { js = j + 1; } else { js = jc = j; kop = k; } } else js = jc; } } return jc; } int iCalculatorParser::FindCompleteTokenToLeft(const iString &str, iString &token, int index) const { // // Count opening and closing tokens until we get a match // int j = this->TokenEnd().Length(), stack = 1; if(str.Find(this->TokenEnd(),index-j) != index-j) return index; for(j=index-2*j; stack>0 && j>=0; j--) { if(str.Find(this->TokenBeg(),j) == j) stack--; if(str.Find(this->TokenEnd(),j) == j) stack++; } if(stack == 0) { j++; token = str.Part(j,index-j); return j; } else return index; } int iCalculatorParser::FindCompleteTokenToRight(const iString &str, iString &token, int index) const { int iBeg, iEnd; index++; str.FindTokenMatch(this->TokenBeg(),iBeg,this->TokenEnd(),iEnd,index,true); if(iBeg!=index || iEnd==-1) return index - 1; else { token = str.Part(iBeg,iEnd-iBeg+1); return iEnd; } } bool iCalculatorParser::IsRecognizedLiteral(const iString &str, int index, int length) const { bool ok; str.Part(index,length).ToDouble(ok); return ok; } bool iCalculatorParser::IsInsideAToken(const iString &str, int index) const { int i2 = str.Find(this->TokenEnd(),index); if(i2 == -1) return false; int i1 = str.Find(this->TokenBeg(),index); return (i1==-1 || i1>i2); } bool iCalculatorParser::IsFullyParsed(const iString &str) const { if(str.IsEmpty()) return true; if(str.Find(this->TokenBeg()) != 0) return false; iString w; return (this->FindCompleteTokenToRight(str,w,-1)+1 == str.Length()); } void iCalculatorParser::DecorateToken(iString &code, const iString &op, const iString &token) { code = this->TokenBeg() + token + op + code + this->TokenEnd(); } #ifdef I_CHECK1 bool iCalculatorParser::ValidatePseudoCode(const iString &code) const { if(!this->IsFullyParsed(code)) return false; // // Check the outer token // int l = this->TokenBeg().Length(); if(code.Find(this->TokenFun(),l) == l) { // // This a function // int is = this->TokenFun().Length() + l - 1; int ie = this->FindVariableToRight(code,is); if(is == ie) return false; int ind = ie; iString token; while(ind < code.Length()-this->TokenEnd().Length()-1) { if((ie=this->FindCompleteTokenToRight(code,token,ind)) == ind) return false; if(!this->ValidatePseudoCode(token)) return false; ind = ie; } return true; } if(code.Find(this->TokenVar(),l) == l) { // // This a variable // int is = this->TokenVar().Length() + l - 1; int ie = this->FindVariableToRight(code,is); if(is==ie || ie+1TokenEnd().Length()) return false; return true; } if(code.Find(this->TokenNum(),l) == l) { // // This a recognized literal // int ind = l + this->TokenNum().Length(); if(!this->IsRecognizedLiteral(code,ind,code.Length()-this->TokenEnd().Length()-ind)) return false; return true; } return false; } #endif // // Main worker // bool iCalculatorParser::Parse(const iString &str) { mErrorMessage.Clear(); mErrorPosition = -1; if(!mIsVerified) { if(!this->VerifyIntegrity()) { this->SetError("Internal error: iCalculatorParser is configured incorrectly.","",-1); return false; } mIsVerified = true; } if(str == mExpression) return true; // Everything has been done already. if(str.IsEmpty()) { this->SetError("A null expression is not allowed.",str,0); return false; } // // Construct the pseudo-code // mExpression = str; mCode.Clear(); iString code = str; code.RemoveWhiteSpace(); // // Find all parenthesis-enclosed pieces // iString w, name; int io, ic, in; while((ic=code.Find(this->SymbolClosingParenthesis())) > -1) { w = code.Part(0,ic+1); io = -1; while((in=w.Find(this->SymbolOpeningParenthesis(),io+1)) > -1) io = in; if(io == -1) { this->SetError("A closing parenthesis is not preceeded by an opening parenthesis.",code,in); return false; } in = this->FindVariableToLeft(code,io); // // If there is a word in front, it is a function call; in both cases we treat it identically // name = w.Part(in,io-in); w = code.Part(in,ic-in+1); if(!this->ParseSegment(w,name)) return false; code.Replace(in,ic-in+1,w); } // // Are there non-closed opening parentheses? // in = code.Find(this->SymbolOpeningParenthesis()); if(in >= 0) { this->SetError("Unmatched opening parenthesis.",code,in); return false; } // // No parenthesis left, parse what's left // in = code.Find(this->SymbolSeparator()); if(in >= 0) { this->SetError("Orphan separator.",code,in); return false; } if(!this->ParseComponent(code)) return false; #ifdef I_CHECK1 if(!this->ValidatePseudoCode(code)) { this->SetError("Internal error: the pseudo-code is parsed incorrectly.","",-1); return false; } #endif // // Clear the log, it can take a lot of memory // while(mLog.Size() > 0) mLog.RemoveLast().Clear(); mCode = code; return true; } bool iCalculatorParser::ParseSegment(iString &code, const iString &fun) { // // Select the piece between the parenthesis // Logger log(this,code); iString tmp; code = code.Part(fun.Length()+this->SymbolOpeningParenthesis().Length(),code.Length()-this->SymbolClosingParenthesis().Length()-fun.Length()-this->SymbolOpeningParenthesis().Length()); // // Split by commas, there are no other parentheses inside // iString dec(fun); if(code.Contains(this->SymbolSeparator()) == 0) { // // A single component // if(!this->ParseComponent(code)) return false; tmp = code; } else { // // Multiple components present. Parse the individual components. // int len = this->SymbolSeparator().Length(); int i2 = -len, i1; iString wold, w; while(i2 < code.Length()) { i1 = i2; i2 = code.Find(this->SymbolSeparator(),i1+len); if(i2 == -1) i2 = code.Length(); w = code.Part(i1+len,i2-i1-len); if(!this->ParseComponent(w)) return false; code.Replace(i1+len,i2-i1-len,w); i2 = i1 + len + w.Length(); tmp += w; // this is just like code, but without separators } // // Is this a vector construct? // if(dec.IsEmpty()) { // // A vector construct (a,b,c). Is there one already parsed? // dec = "vec"; if((i1=code.Find(this->TokenFun()+dec)) != -1) { this->SetError("Nested vector constructs (a,(c,d)) are not permitted.",code,i1); return false; } } } if(!dec.IsEmpty()) { this->DecorateToken(tmp,dec,this->TokenFun()); // decorate if it is a fun, do nothing if it is just some thing like (a+b) since a+b will be already decorated. } code = tmp; return true; } bool iCalculatorParser::ParseComponent(iString &code) { // // If this component is already decorated, skip it. // if(this->IsFullyParsed(code)) return true; Logger log(this,code); // // Replace vector components with function calls // iString wold, w, name; int jo, jc, jn; while((jc=code.Find(this->SymbolClosingBraket())) > -1) { w = code.Part(0,jc+1); jo = -1; while((jn=w.Find(this->SymbolOpeningBraket(),jo+1)) > -1) jo = jn; if(jo == -1) { this->SetError("A closing bracket is not preceeded by an opening bracket.",code,jc); return false; } jn = this->FindVariableToLeft(w,jo); if(jn == jo) { // // There is no word in front, it is a syntax error // this->SetError("Brackets should only be used for selecting individual vector elements.",code,jo); return false; } // // Remove brackets // name = code.Part(jn,jo-jn); w = code.Part(jo+this->SymbolOpeningBraket().Length(),jc-jo+1-this->SymbolOpeningBraket().Length()-this->SymbolClosingBraket().Length()); if(!this->ParseExpressions(w)) return false; wold = name + this->SymbolOpeningBraket() + w + this->SymbolClosingBraket(); this->DecorateToken(name,"",this->TokenVar()); w = name + w; this->DecorateToken(w,"arg",this->TokenFun()); code.Replace(jn,jc-jn+1,w); log.LogChange(wold,w); } // // Parse the rest // if(!this->ParseExpressions(code)) return false; return true; } bool iCalculatorParser::ParseExpressions(iString &code) { // // If this expression is already decorated, skip it. // if(this->IsFullyParsed(code)) return true; Logger log(this,code); // // Go over the expression and classify tokens as literals, variables, and unknown. // iString wold, w; int i, k, kop, iop1 = -1, iop2; while(iop1 < code.Length()-1) { // // Find the next operator // iop2 = this->FindOperatorMatch(code,mOperators,iop1+1,kop); // // If this an operator right after another one, it may be a unary one or may be a part of a literal. Check it. // if(iop2 == iop1 + 1) { i = this->FindLiteralToRight(code,iop1); if(i>iop1 && i+1==this->FindOperatorMatch(code,mOperators,i+1,k)) { // // Hey, that a literal! // kop = k; wold = w = code.Part(iop1+1,i-iop1); this->DecorateToken(w,"",this->TokenNum()); code.Replace(iop1+1,i-iop1,w); log.LogChange(wold,w); iop2 = iop1 + 1 + w.Length(); } } else { // // Identify the operand // i = this->FindCompleteTokenToRight(code,w,iop1); if(i > iop1) { // // We found a token, is it a single one? // if(i+1 == iop2) { // // Yes, just keep going // iop2 = iop1 + 1 + w.Length(); } else { // // No, that means a missing operator // this->SetError("Missing binary operator",code,i+1); return false; } } else { i = this->FindLiteralToRight(code,iop1); if(i+1 >= iop2) // the literal search may incorporate this operator char and move beyond it. { // // This is a literal // wold = w = code.Part(iop1+1,i-iop1); this->DecorateToken(w,"",this->TokenNum()); code.Replace(iop1+1,i-iop1,w); log.LogChange(wold,w); iop2 = iop1 + 1 + w.Length(); } else { i = this->FindVariableToRight(code,iop1); if(i+1 == iop2) { // // This is a variable // wold = w = code.Part(iop1+1,i-iop1); this->DecorateToken(w,"",this->TokenVar()); code.Replace(iop1+1,i-iop1,w); log.LogChange(wold,w); iop2 = iop1 + 1 + w.Length(); } else { // // There is no literal or variable here, take it as an unknown token // this->SetError("Unrecognizable token",code,iop1+1); return false; } } } } if(kop == -1) { iop1 = code.Length() - 1; } else { iop1 = iop2 + mOperators[kop].S.Length() - 1; } } // // Start searching for math operators in order of priority. // Since we have no parentheses in this component, function calls have already been decorated. // iArray ops; for(k=mMaxPriority; k>0; k--) { ops.Clear(); for(i=0; iParseSomeOperators(code,ops)) return false; if(this->IsFullyParsed(code)) { // // We are done: report success // return true; } } // // This expression is still nor parsed, this is an error // this->SetError("Internal error: an expression is not parsed completely.",code,0); return false; } bool iCalculatorParser::ParseSomeOperators(iString &code, const iArray &ops) { // // If this expression is already decorated, skip it. // if(this->IsFullyParsed(code)) return true; Logger log(this,code); iString w1, w2, wold, w; int k, jo = -1, jc, jn1, jn2; while((jo=this->FindOperatorMatch(code,ops,jo+1,k)) < code.Length()) { w1.Clear(); w2.Clear(); if(!ops[k].B) { // // If this a unary operator, the token on the left must be a binary operator of equal or lower priority // if(jo > 0) { int i; bool found = false; w = code.Part(0,jo); for(i=0; iFindCompleteTokenToLeft(code,w1,jo); if(jn1 == jo) { this->SetError("Missing token on the left.",code,jo); return false; } } jc = jo + ops[k].S.Length() - 1; jn2 = this->FindCompleteTokenToRight(code,w2,jc); if(jn2 == jc) { this->SetError("Missing token.",code,jc+1); return false; } // // Now decorate everything // w = w1 + w2; this->DecorateToken(w,ops[k].C,this->TokenFun()); wold = code.Part(jn1,jn2-jn1+1); code.Replace(jn1,jn2-jn1+1,w); log.LogChange(wold,w); jo = jn1; } return true; } iCalculatorParser::Logger::Logger(iCalculatorParser *owner, const iString &code) : mSavedCode(code), mCode(code), mOwner(owner) { IERROR_ASSERT(mOwner); mSavedLogLocation = mOwner->mLog.Size(); } iCalculatorParser::Logger::~Logger() { if(mOwner->GetErrorMessage().IsEmpty()) { while(mOwner->mLog.Size() > mSavedLogLocation) mOwner->mLog.RemoveLast().Clear(); this->LogChange(mSavedCode,mCode); } } void iCalculatorParser::Logger::LogChange(const iString &o, const iString &n) { if(o != n) { Change c; c.Old = o; c.New = n; mOwner->mLog.Add(c); } } ifrit-3.4.2/core/icalculatorparser.h0000755000175700010010000001213512167404407016034 0ustar HomeNone/*========================================================================= Program: Ionization FRont Interactive Tool (IFRIT) Language: C++ Copyright (c) 2002-2012 Nick Gnedin All rights reserved. This file may be distributed and/or modified under the terms of the GNU General Public License version 2 as published by the Free Software Foundation and appearing in the file LICENSE.GPL included in the packaging of this file. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHORS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. =========================================================================*/ #ifndef ICALCULATORPARSER_H #define ICALCULATORPARSER_H #include "iarray.h" #include "istring.h" class iCalculatorBase; class iCalculatorParser { friend class iCalculatorBase; private: bool Parse(const iString &str); inline const iString& GetPseudoCode() const { return mCode; } // // Get the error message and position // inline const iString& GetErrorMessage() const { return mErrorMessage; } inline int GetErrorPosition() const { return mErrorPosition; } protected: iCalculatorParser(bool blank); virtual ~iCalculatorParser(); bool AddOperator(const iString& symbol, const iString& code, int priority, bool binary); // // Punctuation symbols // virtual const iString& SymbolSeparator() const; virtual const iString& SymbolOpeningBraket() const; virtual const iString& SymbolClosingBraket() const; virtual const iString& SymbolOpeningParenthesis() const; virtual const iString& SymbolClosingParenthesis() const; // // Pseudo-code tokens // virtual const iString& TokenBeg() const; virtual const iString& TokenEnd() const; virtual const iString& TokenFun() const; virtual const iString& TokenNum() const; virtual const iString& TokenVar() const; // // Other functions // virtual bool IsVariableLetter(char c) const; virtual bool IsVariableFirstLetter(char c) const; virtual bool IsRecognizedLiteral(const iString &str, int index, int length) const; // can be overwritten by a child to recognize special numbers virtual void SetErrorExtra(const iString &message, int pos); // // Error-recording operations // class Logger { public: Logger(iCalculatorParser *owner, const iString &code); ~Logger(); void LogChange(const iString &o, const iString &n); private: iString mSavedCode; const iString& mCode; int mSavedLogLocation; iCalculatorParser *mOwner; }; void SetError(const iString &message, const iString &context, int pos); private: struct OperatorInfo { iString S; iString C; int P; bool B; OperatorInfo() : P(0), B(false) {} }; void DecorateToken(iString &code, const iString &op, const iString &token); // // Text manipulation helpers // int FindVariableToLeft(const iString &str, int index) const; int FindVariableToRight(const iString &str, int index) const; int FindLiteralToLeft(const iString &str, int index) const; int FindLiteralToRight(const iString &str, int index) const; int FindCompleteTokenToLeft(const iString &str, iString &token, int index) const; int FindCompleteTokenToRight(const iString &str, iString &token, int index) const; int FindOperatorMatch(const iString &str, const iArray &ops, int index, int &kop) const; bool IsInsideAToken(const iString &str, int index) const; bool IsFullyParsed(const iString &str) const; // // Parsing helpers // bool ParseSegment(iString &code, const iString &fun); bool ParseComponent(iString &code); bool ParseExpressions(iString &code); bool ParseSomeOperators(iString &code, const iArray &ops); // // Self-check // bool VerifyIntegrity(); bool VerifyIntegrityHelper(const iString &token); #ifdef I_CHECK1 bool ValidatePseudoCode(const iString &code) const; #endif // // Reverse enginnering log for error identification // struct Change { iString Old; iString New; void Clear(){ Old.Clear(); New.Clear(); } }; iArray mLog; int mErrorPosition; iString mErrorMessage; iString mExpression, mCode; iArray mOperators; bool mIsVerified; int mMaxPriority; }; inline bool iCalculatorParser::IsVariableLetter(char c) const { // // Variables may contain letters, numbers, and '_'. // return ((c>='0'&&c<='9') || (c>='A'&&c<='Z') || (c>='a'&&c<='z') || c=='_'); } inline bool iCalculatorParser::IsVariableFirstLetter(char c) const { // // Variables must start with a letter or '_'. // return ((c>='A'&&c<='Z') || (c>='a'&&c<='z') || c=='_'); } #endif // ICALCULATORPARSER_H ifrit-3.4.2/core/icalculatortemplate.h0000755000175700010010000007676012167404407016371 0ustar HomeNone/*========================================================================= Program: Ionization FRont Interactive Tool (IFRIT) Language: C++ Copyright (c) 2002-2012 Nick Gnedin All rights reserved. This file may be distributed and/or modified under the terms of the GNU General Public License version 2 as published by the Free Software Foundation and appearing in the file LICENSE.GPL included in the packaging of this file. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHORS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. =========================================================================*/ #include "icalculator.h" #include "icalculatorkit.h" #include "ierror.h" #include "imath.h" #include "istring.h" #define ICALCULATOR_FUN_1V_V(_name_,_in_t_,_out_t_) \ template class _name_##_ : public Function_NV_V \ { \ public: \ _name_##_(int loc) : Function_NV_V(1,loc,#_name_){} \ virtual int Evaluate(Variable **args) \ { \ int i, n = this->mResult->Dim(); \ T *arg1 = static_cast*>(args[0])->Data(); \ T *res = static_cast*>(this->mResult)->Data(); \ for(i=0; i class trap_##_name_##_ : public Function_NV_V \ { \ public: \ trap_##_name_##_(int loc) : Function_NV_V(1,loc,#_name_){} \ virtual int Evaluate(Variable **args) \ { \ int i, n = this->mResult->Dim(); \ T *arg1 = static_cast*>(args[0])->Data(); \ T *res = static_cast*>(this->mResult)->Data(); \ for(i=0; i class _name_##_ : public Function_NV_V \ { \ public: \ _name_##_(int loc) : Function_NV_V(1,loc,#_name_){} \ virtual int Evaluate(Variable **args) \ { \ int i, n = this->mResult->Dim(); \ T *arg1 = static_cast*>(args[0])->Data(); \ T *res = static_cast*>(this->mResult)->Data(); \ for(i=0; i class trap_##_name_##_ : public Function_NV_V \ { \ public: \ trap_##_name_##_(int loc) : Function_NV_V(1,loc,#_name_){} \ virtual int Evaluate(Variable **args) \ { \ int i, n = this->mResult->Dim(); \ T *arg1 = static_cast*>(args[0])->Data(); \ T *res = static_cast*>(this->mResult)->Data(); \ for(i=0; i class _name_##_ : public Function_NV_V \ { \ public: \ _name_##_(int loc) : Function_NV_V(2,loc,#_name_){} \ virtual int Evaluate(Variable **args) \ { \ int i, n = this->mResult->Dim(); \ T *arg1 = static_cast*>(args[0])->Data(); \ T *arg2 = static_cast*>(args[1])->Data(); \ T *res = static_cast*>(this->mResult)->Data(); \ for(i=0; i class trap_##_name_##_ : public Function_NV_V \ { \ public: \ trap_##_name_##_(int loc) : Function_NV_V(2,loc,#_name_){} \ virtual int Evaluate(Variable **args) \ { \ int i, n = this->mResult->Dim(); \ T *arg1 = static_cast*>(args[0])->Data(); \ T *arg2 = static_cast*>(args[1])->Data(); \ T *res = static_cast*>(this->mResult)->Data(); \ for(i=0; i class _name_##_ : public Function_NV_V \ { \ public: \ _name_##_(int loc) : Function_NV_V(2,loc,#_name_){} \ virtual int Evaluate(Variable **args) \ { \ int i, n = this->mResult->Dim(); \ T *arg1 = static_cast*>(args[0])->Data(); \ T *arg2 = static_cast*>(args[1])->Data(); \ T *res = static_cast*>(this->mResult)->Data(); \ for(i=0; i class trap_##_name_##_ : public Function_NV_V \ { \ public: \ trap_##_name_##_(int loc) : Function_NV_V(2,loc,#_name_){} \ virtual int Evaluate(Variable **args) \ { \ int i, n = this->mResult->Dim(); \ T *arg1 = static_cast*>(args[0])->Data(); \ T *arg2 = static_cast*>(args[1])->Data(); \ T *res = static_cast*>(this->mResult)->Data(); \ for(i=0; i class _name_##_ : public Function_SV_V \ { \ public: \ _name_##_(int loc) : Function_SV_V(loc,#_name_){} \ virtual int Evaluate(Variable **args) \ { \ int i, n = this->mResult->Dim(); \ T *arg1 = static_cast*>(args[0])->Data(); \ T *arg2 = static_cast*>(args[1])->Data(); \ T *res = static_cast*>(this->mResult)->Data(); \ for(i=0; imScalar1?0:i],arg2[this->mScalar2?0:i])); \ return 0; \ } \ } #define ICALCULATOR_TRAP_FUN_SV_V(_name_,_in_t_,_out_t_,_assert_) \ template class trap_##_name_##_ : public Function_SV_V \ { \ public: \ trap_##_name_##_(int loc) : Function_SV_V(loc,#_name_){} \ virtual int Evaluate(Variable **args) \ { \ int i, n = this->mResult->Dim(); \ T *arg1 = static_cast*>(args[0])->Data(); \ T *arg2 = static_cast*>(args[1])->Data(); \ T *res = static_cast*>(this->mResult)->Data(); \ for(i=0; imScalar1?0:i],arg2[this->mScalar2?0:i])); \ } \ return 0; \ } \ } #define ICALCULATOR_OPR_SV_V(_name_,_in_t_,_out_t_,_op_) \ template class _name_##_ : public Function_SV_V \ { \ public: \ _name_##_(int loc) : Function_SV_V(loc,#_name_){} \ virtual int Evaluate(Variable **args) \ { \ int i, n = this->mResult->Dim(); \ T *arg1 = static_cast*>(args[0])->Data(); \ T *arg2 = static_cast*>(args[1])->Data(); \ T *res = static_cast*>(this->mResult)->Data(); \ for(i=0; imScalar1?0:i] _op_ arg2[this->mScalar2?0:i]; \ return 0; \ } \ } #define ICALCULATOR_TRAP_OPR_SV_V(_name_,_in_t_,_out_t_,_op_,_assert_) \ template class trap_##_name_##_ : public Function_SV_V \ { \ public: \ trap_##_name_##_(int loc) : Function_SV_V(loc,#_name_){} \ virtual int Evaluate(Variable **args) \ { \ int i, n = this->mResult->Dim(); \ T *arg1 = static_cast*>(args[0])->Data(); \ T *arg2 = static_cast*>(args[1])->Data(); \ T *res = static_cast*>(this->mResult)->Data(); \ for(i=0; imScalar1?0:i] _op_ arg2[this->mScalar2?0:i]; \ } \ return 0; \ } \ } #define ICALCULATOR_FUN_MINMAX(_name_,_in_t_,_out_t_,_op_) \ template class _name_##_ : public Function_NV1V_VS \ { \ public: \ _name_##_(int loc) : Function_NV1V_VS(loc,#_name_){} \ virtual int Evaluate(Variable **args) \ { \ int i, n; \ T *arg = static_cast*>(args[0])->Data(); \ T *res = static_cast*>(this->mResult)->Data(); \ if(this->mNumArgs > 1) \ { \ int j, narg = this->mNumArgs; \ n = this->mResult->Dim(); \ memcpy(res,arg,n*sizeof(T)); \ for(j=1; j*>(args[j])->Data(); \ for(i=0; iDim(); \ res[0] = arg[0]; \ for(i=1; i(loc) #define ICALCULATOR_SELECT_TRAP_FUN(_name_) \ if(str == #_name_) return new iCalculatorKit::trap_##_name_##_(loc) namespace iCalculatorKit { // // These are already defined in some versions of Linux and in ISO C99, so we keep them // inside the namespace // inline double asinh(double v){ return log(v+sqrt(v*v+1.0)); } inline double acosh(double v){ return log(v+sqrt(v*v-1.0)); } inline double atanh(double v){ return 0.5*log((1.0+v)/(1.0-v)); } inline double sign(double v){ return (v < 0.0) ? -1.0 : 1.0; } // // useful helper functions // template T ConvertFromString(const iString &str, bool &ok); template<> inline float ConvertFromString(const iString &str, bool &ok) { return str.ToFloat(ok); } template<> inline double ConvertFromString(const iString &str, bool &ok) { return str.ToDouble(ok); } template T ConvertToBoolRepresentation(T v); template<> inline float ConvertToBoolRepresentation(float v) { return (fabs(v) < iMath::_FloatTolerance ? 0.0f : 1.0f); } template<> inline double ConvertToBoolRepresentation(double v) { return (fabs(v) < iMath::_DoubleTolerance ? 0.0 : 1.0); } // // ********************************************************************** // // More specialized abstract implementations for variables // // ********************************************************************** // template class DataVariable : public Variable { public: DataVariable(int dim, int use, const iString &name) : Variable(dim,use,name), mData(0) { } inline T* const Data() const { return this->mData; } protected: virtual void CopyBody(const Variable &var) { if(this->mData != 0) memcpy(this->mData,static_cast&>(var).mData,this->Dim()*sizeof(T)); } T* mData; }; template class GenericDataVariable : public DataVariable { public: GenericDataVariable(int dim, int use, const iString &name) : DataVariable(dim,use,name) { } protected: virtual bool MorphBody(int dim, int use) { if(morphable) { if(dim < 1) return false; if(dim != this->Dim()) this->ChangeDimension(dim); if(use == 1) { int i; for(i=0; imData[i] = ConvertToBoolRepresentation(this->mData[i]); } return true; } else return false; } virtual void ChangeDimension(int dim) = 0; }; // // ********************************************************************** // // Concrete implementations for variables // // ********************************************************************** // // // Vector that owns the data ("access by value"). // template class var_ : public GenericDataVariable { public: var_(int dim, int use, const iString &name) : GenericDataVariable(dim,use,name) { this->mData = new T[dim]; IERROR_ASSERT(this->mData); } virtual ~var_() { delete [] this->mData; } protected: virtual void ChangeDimension(int dim) { delete [] this->mData; this->mData = new T[dim]; IERROR_ASSERT(this->mData); } }; // // Vector that references the data ("access by reference") // template class ptr_ : public GenericDataVariable { public: ptr_(T* ptr, int dim, int use, const iString &name) : GenericDataVariable(dim,use,name) { this->mData = ptr; IERROR_ASSERT(this->mData); } protected: virtual void ChangeDimension(int dim) { // // Just reset the pointer length - which is done by the parent // } }; // // ********************************************************************** // // More specialized abstract implementations for functions // // ********************************************************************** // // // Function with vector result and n arguments // template class GenericFunction : public Function { public: GenericFunction(int narg, int loc, const iString &name) : Function(new var_(1,0,name),narg,loc) { IERROR_ASSERT(this->mResult); } virtual ~GenericFunction() { delete this->mResult; } }; // // vector-to-vector multi-argument function // template class Function_NV_V : public GenericFunction { public: Function_NV_V(int narg, int loc, const iString &name) : GenericFunction(narg,loc,name){} virtual bool CheckArguments(int *dims, int *uses, iString &err) { int i; for(i=0; imNumArgs; i++) { if(uses[i] != in_t) { err = "argument #" + iString::FromNumber(i+1) + " has an incompatible usage patterns"; return false; } if(dims[i] < 1) { err = "argument #" + iString::FromNumber(i+1) + " has an invalid dimension < 1"; return false; } if(dims[i] != dims[0]) { err = "argument #" + iString::FromNumber(i+1) + " has an incompatible dimension of " + iString::FromNumber(dims[i]) + " instead of " + iString::FromNumber(dims[0]); return false; } } if(!this->mResult->Morph(scalar?1:dims[0],out_t)) { err = "output (dim=" + iString::FromNumber(this->mResult->Dim()) + ",use=" + iString::FromNumber(this->mResult->Use()) + ") is not compatible with required dimension of " + iString::FromNumber(dims[0]) + " and usage pattern of " + iString::FromNumber(out_t); return false; } return true; } }; // // vector+scalar-to-vector 2-argument function // template class Function_SV_V : public GenericFunction { public: Function_SV_V(int loc, const iString &name) : GenericFunction(2,loc,name){} virtual bool CheckArguments(int *dims, int *uses, iString &err) { int i; for(i=0; i<2; i++) { if(uses[i] != in_t) { err = "argument #" + iString::FromNumber(i+1) + " has an incompatible usage pattern"; return false; } if(dims[i] < 1) { err = "argument #" + iString::FromNumber(i+1) + " has an invalid dimension < 1"; return false; } } int dim = (dims[0] > dims[1]) ? dims[0] : dims[1]; for(i=0; i<2; i++) { if(dims[i]!=1 && dims[i]!=dim) { err = "argument #" + iString::FromNumber(i+1) + " has an incompatible dimension of " + iString::FromNumber(dims[i]) + " instead of 1 or " + iString::FromNumber(dim); return false; } } if(!this->mResult->Morph(dim,out_t)) { err = "output (dim=" + iString::FromNumber(this->mResult->Dim()) + ",use=" + iString::FromNumber(this->mResult->Use()) + ") is not compatible with required dimension of " + iString::FromNumber(dim) + " and usage pattern of " + iString::FromNumber(out_t); return false; } this->mScalar1 = (dims[0]==1 && dim>1); this->mScalar2 = (dims[1]==1 && dim>1); return true; } protected: bool mScalar1, mScalar2; }; // // an operation on 2 spatial points // template class Function_2P : public GenericFunction { public: Function_2P(int loc, const iString &name) : GenericFunction(2,loc,name){} virtual bool CheckArguments(int *dims, int *uses, iString &err) { int i; for(i=0; imNumArgs; i++) { if(uses[i] != 0) { err = "argument #" + iString::FromNumber(i+1) + " has an incompatible usage pattern"; return false; } if(dims[i] != 3) { err = "argument #" + iString::FromNumber(i+1) + " has an invalid dimension; a dimension of a point must be 3"; return false; } } if(!this->mResult->Morph(scalar?1:3,0)) { err = "output (dim=" + iString::FromNumber(this->mResult->Dim()) + ",use=" + iString::FromNumber(this->mResult->Use()) + ") is not compatible with required dimension of " + (scalar?"1":"3") + " and usage pattern of 0"; return false; } return true; } }; // // min/max type functions - do vector-to-vector for narg>1, vector-to-scalar for n=1 // template class Function_NV1V_VS : public GenericFunction { public: Function_NV1V_VS(int loc, const iString &name) : GenericFunction(-1,loc,name){} virtual bool CheckArguments(int *dims, int *uses, iString &err) { int i; for(i=0; imNumArgs; i++) { if(uses[i] != in_t) { err = "argument #" + iString::FromNumber(i+1) + " has an incompatible usage pattern"; return false; } if(dims[i] < 1) { err = "argument #" + iString::FromNumber(i+1) + " has an invalid dimension < 1"; return false; } if(dims[i] != dims[0]) { err = "argument #" + iString::FromNumber(i+1) + " has an incompatible dimension of " + iString::FromNumber(dims[i]) + " instead of " + iString::FromNumber(dims[0]); return false; } } if(!this->mResult->Morph(this->mNumArgs==1?1:dims[0],out_t)) { err = "output (dim=" + iString::FromNumber(this->mResult->Dim()) + ",use=" + iString::FromNumber(this->mResult->Use()) + ") is not compatible with required dimension of " + iString::FromNumber(this->mNumArgs==1?1:dims[0]) + " and usage pattern of " + iString::FromNumber(out_t); return false; } return true; } }; // // ********************************************************************** // // Concrete implementations for functions // // ********************************************************************** // // // Mathematical operators // ICALCULATOR_OPR_SV_V(mul,0,0,*); ICALCULATOR_OPR_SV_V(add,0,0,+); ICALCULATOR_OPR_SV_V(sub,0,0,-); ICALCULATOR_OPR_1V_V(neg,0,0,-); ICALCULATOR_FUN_SV_V(pow,0,0); ICALCULATOR_OPR_SV_V(div,0,0,/); ICALCULATOR_TRAP_FUN_SV_V(pow,0,0,arg1[i]<0.0 || (arg1[i]==0 && arg2[i]<0.0)); ICALCULATOR_TRAP_OPR_SV_V(div,0,0,/,arg2[i] == 0.0); // // Logical operators // ICALCULATOR_OPR_SV_V(ltn,0,1,<); ICALCULATOR_OPR_SV_V(gtn,0,1,>); ICALCULATOR_OPR_SV_V(leq,0,1,<=); ICALCULATOR_OPR_SV_V(geq,0,1,>=); ICALCULATOR_OPR_SV_V(eql,0,1,==); ICALCULATOR_OPR_SV_V(neq,0,1,!=); ICALCULATOR_OPR_SV_V(and,1,1,&&); ICALCULATOR_OPR_SV_V(lor,1,1,||); ICALCULATOR_OPR_1V_V(not,1,1,!); // // One-argument functions // ICALCULATOR_FUN_1V_V(sin,0,0); ICALCULATOR_FUN_1V_V(cos,0,0); ICALCULATOR_FUN_1V_V(atan,0,0); ICALCULATOR_FUN_1V_V(sinh,0,0); ICALCULATOR_FUN_1V_V(cosh,0,0); ICALCULATOR_FUN_1V_V(tanh,0,0); ICALCULATOR_FUN_1V_V(asinh,0,0); ICALCULATOR_FUN_1V_V(pow10,0,0); ICALCULATOR_FUN_1V_V(exp,0,0); ICALCULATOR_FUN_1V_V(floor,0,0); ICALCULATOR_FUN_1V_V(ceil,0,0); ICALCULATOR_FUN_1V_V(fabs,0,0); ICALCULATOR_FUN_1V_V(sign,0,0); ICALCULATOR_FUN_1V_V(tan,0,0); ICALCULATOR_FUN_1V_V(asin,0,0); ICALCULATOR_FUN_1V_V(acos,0,0); ICALCULATOR_TRAP_FUN_1V_V(tan,0,0,cos(arg1[i]) == 0.0); ICALCULATOR_TRAP_FUN_1V_V(asin,0,0,arg1[i]<-1.0 || arg1[i]>1.0); ICALCULATOR_TRAP_FUN_1V_V(acos,0,0,arg1[i]<-1.0 || arg1[i]>1.0); ICALCULATOR_FUN_1V_V(acosh,0,0); ICALCULATOR_FUN_1V_V(atanh,0,0); ICALCULATOR_TRAP_FUN_1V_V(acosh,0,0,arg1[i] < 1.0); ICALCULATOR_TRAP_FUN_1V_V(atanh,0,0,arg1[i]<-1.0 || arg1[i]>1.0); ICALCULATOR_FUN_1V_V(log,0,0); ICALCULATOR_FUN_1V_V(log10,0,0); ICALCULATOR_FUN_1V_V(sqrt,0,0); ICALCULATOR_TRAP_FUN_1V_V(log,0,0,arg1[i] <= 0.0); ICALCULATOR_TRAP_FUN_1V_V(log10,0,0,arg1[i] <= 0.0); ICALCULATOR_TRAP_FUN_1V_V(sqrt,0,0,arg1[i] < 0.0); // // Vector operators // template class dot_ : public Function_2P { public: dot_(int loc) : Function_2P(loc,"dot"){} virtual int Evaluate(Variable **args) { int i; T *arg1 = static_cast*>(args[0])->Data(); T *arg2 = static_cast*>(args[1])->Data(); T *res = static_cast*>(this->mResult)->Data(); res[0] = T(0); for(i=0; i<3; i++) res[0] += arg1[i]*arg2[i]; return 0; } }; template class xrs_ : public Function_2P { public: xrs_(int loc) : Function_2P(loc,"xrs"){} virtual int Evaluate(Variable **args) { T *arg1 = static_cast*>(args[0])->Data(); T *arg2 = static_cast*>(args[1])->Data(); T *res = static_cast*>(this->mResult)->Data(); res[0] = arg1[1]*arg2[2] - arg1[2]*arg2[1]; res[1] = arg1[2]*arg2[0] - arg1[0]*arg2[2]; res[2] = arg1[0]*arg2[1] - arg1[1]*arg2[0]; return 0; } }; // // Special operators: vector construct, vector component // template class vec_ : public GenericFunction { public: vec_(int loc) : GenericFunction(-1,loc,"vec"){} virtual bool CheckArguments(int *dims, int *uses, iString &err) { int i; for(i=0; imNumArgs; i++) { if(uses[i] != uses[0]) { err = "argument #" + iString::FromNumber(i+1) + " has an incompatible usage pattern"; return false; } if(dims[i] != 1) { err = "argument #" + iString::FromNumber(i+1) + " has an invalid dimension; all arguments must have dimension of 1"; return false; } } if(!this->mResult->Morph(this->mNumArgs,uses[0])) { err = "output (dim=" + iString::FromNumber(this->mResult->Dim()) + ",use=" + iString::FromNumber(this->mResult->Use()) + ") is not compatible with required dimension of " + iString::FromNumber(this->mNumArgs) + " and usage pattern of " + iString::FromNumber(uses[0]); return false; } return true; } virtual int Evaluate(Variable **args) { int i, n = this->mResult->Dim(); T *res = static_cast*>(this->mResult)->Data(); for(i=0; i*>(args[i])->Data()[0]; } return 0; } }; template class arg_ : public GenericFunction { public: arg_(int loc) : GenericFunction(2,loc,"arg"){} virtual bool CheckArguments(int *dims, int *uses, iString &err) { if(uses[1] != 0) { err = "argument #2 must be numeric (i.e. have a usage pattern of 0)"; return false; } if(dims[1] != 1) { err = "argument #2 must be a scalar (i.e. have a dimension of 1)"; return false; } if(dims[0] < 2) { err = "argument #1 must be a true vector (i.e. have a dimension of 2 and more)"; return false; } if(!this->mResult->Morph(1,uses[0])) { err = "output (dim=" + iString::FromNumber(this->mResult->Dim()) + ",use=" + iString::FromNumber(this->mResult->Use()) + ") is not compatible with required dimension of 1 and usage pattern of " + iString::FromNumber(uses[0]); return false; } return true; } virtual int Evaluate(Variable **args) { int ind = int(static_cast*>(args[1])->Data()[0]); DataVariable *arg1 = static_cast*>(args[0]); if(ind>0 && ind<=arg1->Dim()) { static_cast*>(this->mResult)->Data()[0] = arg1->Data()[ind-1]; return 0; } else return 1; } }; // // min/max type functions - do vector-to-vector for narg>1, vector-to-scalar for n=1 // ICALCULATOR_FUN_MINMAX(min,0,0,>); ICALCULATOR_FUN_MINMAX(max,0,0,<); template class sum_ : public Function_NV1V_VS { public: sum_(int loc) : Function_NV1V_VS(loc,"sum"){} virtual int Evaluate(Variable **args) { int i, n; T *arg = static_cast*>(args[0])->Data(); T *res = static_cast*>(this->mResult)->Data(); if(this->mNumArgs > 1) { int j, narg = this->mNumArgs; n = this->mResult->Dim(); memcpy(res,arg,n*sizeof(T)); for(j=1; j*>(args[j])->Data(); for(i=0; iDim(); res[0] = arg[0]; for(i=1; i class dim_ : public GenericFunction { public: dim_(int loc) : GenericFunction(1,loc,"dim"){} virtual bool CheckArguments(int *dims, int *uses, iString &err) { if(!this->mResult->Morph(1,0)) { err = "output (dim=" + iString::FromNumber(this->mResult->Dim()) + ",use=" + iString::FromNumber(this->mResult->Use()) + ") is not compatible with required dimension of 1 and usage pattern of 0"; return false; } return true; } virtual int Evaluate(Variable **args) { static_cast*>(this->mResult)->Data()[0] = args[0]->Dim(); return 0; } }; // // User-friendly Variable types that auto-add to the calculator: // 1. Vector that owns the data ("access by value"). // template class var : public var_ { public: var(const iString &name, iCalculator *c = 0) : var_(1,use,name) { if(c != 0) c->AddVariable(this); } var(const iString &name, int dim, iCalculator *c = 0) : var_(dim,use,name) { if(c != 0) c->AddVariable(this); } inline T& operator[](int i){ return this->mData[i]; } inline const T& operator[](int i) const { return this->mData[i]; } inline operator T*(){ return this->mData; } inline operator const T*() const { return this->mData; } }; // // 2. Vector that references the data ("access by reference") // template class ptr : public ptr_ { public: ptr(T* p, const iString &name, iCalculator *c = 0) : ptr_(p,1,use,name) { if(c != 0) c->AddVariable(this); } ptr(T* p, const iString &name, int dim, iCalculator *c = 0) : ptr_(p,dim,use,name) { if(c != 0) c->AddVariable(this); } inline T& operator[](int i){ return this->mData[i]; } inline const T& operator[](int i) const { return this->mData[i]; } inline operator T*(){ return this->mData; } inline operator const T*() const { return this->mData; } inline T* operator++(){ this->mData += this->Dim(); return this->mData; } }; }; // // ********************************************************************** // // Default template calculator (that works with the default parser) // // ********************************************************************** // template iCalculator::iCalculator() : iCalculatorBase() { } template const T* iCalculator::GetResultData() const { if(this->Result() != 0) return static_cast*>(this->Result())->Data(); else return 0; } template int iCalculator::GetResultSize() const { if(this->Result() != 0) return this->Result()->Dim(); else return 0; } template void iCalculator::AddVariable(const result_t *var) { this->iCalculatorBase::AddVariable(var); } #ifdef I_DEBUG template void iCalculator::PrintStack(int iptr, int narg, int jmax, iCalculatorKit::Variable** stack) { iConsole::Display(iConsole::_Info,"\nCall:\n"); iConsole::Display(iConsole::_Info,(iString::FromNumber(iptr)+","+iString::FromNumber(narg)+"\n").ToCharPointer()); int i, j; iString w; for(j=0; j<=jmax; j++) { w = "stack["+iString::FromNumber(j)+"]: " + stack[j]->Name() + " "; for(i=0; iDim(); i++) w += iString::FromNumber(static_cast*>(stack[j])->Data()[i])+" "; w += "\n"; iConsole::Display(iConsole::_Info,w.ToCharPointer()); } } #endif // // Overwritable method for extending // template iCalculatorKit::Variable* iCalculator::CreateLiteral(const iString &str) const { bool ok; T v = iCalculatorKit::ConvertFromString(str,ok); if(!ok) return 0; iCalculatorKit::var_ *ret = new iCalculatorKit::var_(1,0,"$$c"); if(ret == 0) return 0; ret->Data()[0] = v; return ret; } template iCalculatorKit::Function* iCalculator::CreateFunction(const iString &str, int loc) const { // // Mathematical operators // ICALCULATOR_SELECT_FUN(mul); ICALCULATOR_SELECT_FUN(add); ICALCULATOR_SELECT_FUN(sub); ICALCULATOR_SELECT_FUN(neg); if(this->GetTrapFPE()) { ICALCULATOR_SELECT_TRAP_FUN(pow); ICALCULATOR_SELECT_TRAP_FUN(div); } else { ICALCULATOR_SELECT_FUN(pow); ICALCULATOR_SELECT_FUN(div); } // // Logical operators // ICALCULATOR_SELECT_FUN(ltn); ICALCULATOR_SELECT_FUN(gtn); ICALCULATOR_SELECT_FUN(leq); ICALCULATOR_SELECT_FUN(geq); ICALCULATOR_SELECT_FUN(eql); ICALCULATOR_SELECT_FUN(neq); ICALCULATOR_SELECT_FUN(and); ICALCULATOR_SELECT_FUN(lor); ICALCULATOR_SELECT_FUN(not); // // One-argument functions // ICALCULATOR_SELECT_FUN(sin); ICALCULATOR_SELECT_FUN(cos); ICALCULATOR_SELECT_FUN(atan); ICALCULATOR_SELECT_FUN(tanh); ICALCULATOR_SELECT_FUN(sinh); ICALCULATOR_SELECT_FUN(cosh); ICALCULATOR_SELECT_FUN(asinh); ICALCULATOR_SELECT_FUN(pow10); ICALCULATOR_SELECT_FUN(exp); ICALCULATOR_SELECT_FUN(floor); ICALCULATOR_SELECT_FUN(ceil); ICALCULATOR_SELECT_FUN(fabs); ICALCULATOR_SELECT_FUN(sign); if(this->GetTrapFPE()) { ICALCULATOR_SELECT_TRAP_FUN(tan); ICALCULATOR_SELECT_TRAP_FUN(asin); ICALCULATOR_SELECT_TRAP_FUN(acos); ICALCULATOR_SELECT_TRAP_FUN(acosh); ICALCULATOR_SELECT_TRAP_FUN(atanh); ICALCULATOR_SELECT_TRAP_FUN(log); ICALCULATOR_SELECT_TRAP_FUN(log10); ICALCULATOR_SELECT_TRAP_FUN(sqrt); } else { ICALCULATOR_SELECT_FUN(tan); ICALCULATOR_SELECT_FUN(asin); ICALCULATOR_SELECT_FUN(acos); ICALCULATOR_SELECT_FUN(acosh); ICALCULATOR_SELECT_FUN(atanh); ICALCULATOR_SELECT_FUN(log); ICALCULATOR_SELECT_FUN(log10); ICALCULATOR_SELECT_FUN(sqrt); } // // Vector operators // ICALCULATOR_SELECT_FUN(dot); ICALCULATOR_SELECT_FUN(xrs); // // Special operators: vector construct, vector component // ICALCULATOR_SELECT_FUN(vec); ICALCULATOR_SELECT_FUN(arg); // // min/max type functions - do vector-to-vector for narg>1, vector-to-scalar for n=1 // ICALCULATOR_SELECT_FUN(min); ICALCULATOR_SELECT_FUN(max); ICALCULATOR_SELECT_FUN(sum); // // Return the dimension (size) of the array // ICALCULATOR_SELECT_FUN(dim); return 0; } ifrit-3.4.2/core/icamera.cpp0000755000175700010010000002163412167404425014255 0ustar HomeNone/*========================================================================= Program: Ionization FRont Interactive Tool (IFRIT) Language: C++ Copyright (c) 2002-2012 Nick Gnedin All rights reserved. This file may be distributed and/or modified under the terms of the GNU General Public License version 2 as published by the Free Software Foundation and appearing in the file LICENSE.GPL included in the packaging of this file. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHORS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. =========================================================================*/ #include "icamera.h" #include "icontrolmodule.h" #include "ierror.h" #include "ieventobserver.h" #include "irendertool.h" #include "iviewmodule.h" #include #include #include IOBJECT_DEFINE_TYPE(iCamera,Camera,c,iObjectType::_Helper); IOBJECT_DEFINE_KEY(iCamera,Azimuth,a,Float,1); IOBJECT_DEFINE_KEY(iCamera,ClippingRange,cr,Double,2); IOBJECT_DEFINE_KEY(iCamera,ClippingRangeAuto,cra,Bool,1); IOBJECT_DEFINE_KEY(iCamera,Elevation,e,Float,1); IOBJECT_DEFINE_KEY(iCamera,EyeAngle,ea,Float,1); IOBJECT_DEFINE_KEY(iCamera,Pitch,p,Float,1); IOBJECT_DEFINE_KEY(iCamera,ParallelProjection,pp,Bool,1); IOBJECT_DEFINE_KEY(iCamera,ParallelScale,ps,Float,1); IOBJECT_DEFINE_KEY(iCamera,Roll,r,Float,1); IOBJECT_DEFINE_KEY(iCamera,Reset,rs,Bool,1); IOBJECT_DEFINE_KEY(iCamera,ViewAngle,va,Float,1); IOBJECT_DEFINE_KEY(iCamera,ViewAngleVertical,vav,Bool,1); IOBJECT_DEFINE_KEY(iCamera,ViewUp,u,Double,3); IOBJECT_DEFINE_KEY(iCamera,Yaw,y,Float,1); IOBJECT_DEFINE_KEY(iCamera,Zoom,z,Float,1); IOBJECT_DEFINE_POSITION_KEY(iCamera,FocalPoint,f); IOBJECT_DEFINE_POSITION_KEY(iCamera,Position,x); IOBJECT_DEFINE_KEY(iCamera,SyncProjections,-sp,Bool,1); // // Helper classes // namespace iCamera_Private { class CameraObserver : public iEventObserver { public: vtkTypeMacro(CameraObserver,iEventObserver); static CameraObserver* New(iCamera *c = 0) { IERROR_ASSERT(c); return new CameraObserver(c); } protected: CameraObserver(iCamera *c) : iEventObserver(c->GetViewModule()->GetControlModule()->GetShell()) { mCamera = c; } virtual void ExecuteBody(vtkObject *, unsigned long event, void *) { switch(event) { case ModifiedEvent: { mCamera->Update(); break; } } } private: iCamera *mCamera; }; }; using namespace iCamera_Private; // // Main class // iCamera* iCamera::New(iRenderTool *rt) { IERROR_ASSERT(rt); return new iCamera(rt); } iCamera::iCamera(iRenderTool *rt) : iObject("Camera"), mViewModule(rt->GetViewModule()), mPosition(rt->GetViewModule()), mFocalPoint(rt->GetViewModule()) { mRenderTool = rt; mDevice = vtkCamera::New(); IERROR_ASSERT(mDevice); mObserver = CameraObserver::New(this); IERROR_ASSERT(mObserver); mSyncProjections = false; mDevice->AddObserver(vtkCommand::ModifiedEvent,mObserver); mDevice->ParallelProjectionOn(); mDevice->Modified(); } iCamera::~iCamera() { mObserver->Delete(); mDevice->Delete(); } void iCamera::Update() { // // Update position and focal point // mPosition = mDevice->GetPosition(); mFocalPoint = mDevice->GetFocalPoint(); this->ClearCache(); } void iCamera::Reset() { mRenderTool->ResetCamera(); this->ClearCache(); } void iCamera::OrthogonalizeView() { static const double orts[6][3] = { { -1.0, 0.0, 0.0 }, { 1.0, 0.0, 0.0 }, { 0.0, -1.0, 0.0 }, { 0.0, 1.0, 0.0 }, { 0.0, 0.0, -1.0 }, { 0.0, 0.0, 1.0 } }; // // Orthogonalize the camera position. // int i, j, imax; double d, *v, dmax, pos[3]; imax = 5; dmax = 0.0; v = mDevice->GetDirectionOfProjection(); for(i=0; i<6; i++) { d = vtkMath::Dot(orts[i],v); if(d > dmax) { dmax = d; imax = i; } } d = mDevice->GetDistance(); v = mDevice->GetFocalPoint(); for(j=0; j<3; j++) pos[j] = v[j] - d*orts[imax][j]; mDevice->SetPosition(pos); // // Orthogonalize the view up. // imax = 3; dmax = 0.0; v = mDevice->GetViewUp(); for(i=0; i<6; i++) { d = vtkMath::Dot(orts[i],v); if(d > dmax) { dmax = d; imax = i; } } mDevice->SetViewUp(orts[imax]); } void iCamera::ShiftTo(const iPosition& pos) { int j; double cp[3], fp[3]; mDevice->GetPosition(cp); mDevice->GetFocalPoint(fp); for(j=0; j<3; j++) { cp[j] += (pos[j]-fp[j]); } mDevice->SetPosition(cp); mDevice->SetFocalPoint(pos); } // // Two functions used in saving/restoring the state and in creating new instances with // void iCamera::PackStateBody(iString &s) const { double d, dv[2]; // // Pack projection first as changing projections may reset other properties // this->PackValue(s,KeyParallelProjection(),mDevice->GetParallelProjection()!=0); this->PackValuePosition(s,KeyPosition(),mPosition); this->PackValuePosition(s,KeyFocalPoint(),mFocalPoint); this->PackValue(s,KeyViewUp(),mDevice->GetViewUp(),3); this->PackValue(s,KeyParallelScale(),float(mDevice->GetParallelScale())); this->PackValue(s,KeyViewAngle(),float(mDevice->GetViewAngle())); this->PackValue(s,KeyViewAngleVertical(),mDevice->GetUseHorizontalViewAngle()==0); this->PackValue(s,KeyEyeAngle(),float(mDevice->GetEyeAngle())); this->PackValue(s,KeyClippingRangeAuto(),mRenderTool->GetAdjustCameraClippingRangeAutomatically()); this->PackValue(s,KeySyncProjections(),mSyncProjections); mDevice->GetClippingRange(dv); d = mDevice->GetDistance(); dv[0] /= d; dv[1] /= d; this->PackValue(s,KeyClippingRange(),dv,2); } void iCamera::UnPackStateBody(const iString &s) { bool b; float f; double d, dv[3]; iObject::ReportMissingKeys(false); //optional key if(this->UnPackValue(s,KeySyncProjections(),b)) mSyncProjections = b; iObject::ReportMissingKeys(true); // // UnPack projection first as changing projections may reset other properties // if(this->UnPackValue(s,KeyParallelProjection(),b)) { // // We shouldn't reset unless we actually change projections // if(b != (mDevice->GetParallelProjection()!=0)) { if(mSyncProjections) this->SyncProjections(); else mRenderTool->ResetCamera(); } mDevice->SetParallelProjection(b?1:0); } // // Camera orientation // if(this->UnPackValuePosition(s,KeyPosition(),mPosition)) this->SetPosition(mPosition); if(this->UnPackValuePosition(s,KeyFocalPoint(),mFocalPoint)) this->SetFocalPoint(mFocalPoint); if(this->UnPackValue(s,KeyViewUp(),dv,3)) mDevice->SetViewUp(dv); if(this->UnPackValue(s,KeyParallelScale(),f)) mDevice->SetParallelScale(f); if(this->UnPackValue(s,KeyViewAngle(),f)) mDevice->SetViewAngle(f); if(this->UnPackValue(s,KeyViewAngleVertical(),b)) mDevice->SetUseHorizontalViewAngle(b?0:1); if(this->UnPackValue(s,KeyEyeAngle(),f)) mDevice->SetEyeAngle(f); if(this->UnPackValue(s,KeyClippingRangeAuto(),b)) { mRenderTool->SetAdjustCameraClippingRangeAutomatically(b); this->ClearCache(); } mRenderTool->GetCameraClippingRange(dv); d = mDevice->GetDistance(); dv[0] /= d; dv[1] /= d; if(this->UnPackValue(s,KeyClippingRange(),dv,2)) { dv[0] *= d; dv[1] *= d; mRenderTool->SetCameraClippingRange(dv); this->ClearCache(); } // // "Action" keys // iObject::ReportMissingKeys(false); //action keys are not part of the states if(this->UnPackValue(s,KeyReset(),b) && b) this->Reset(); if(this->UnPackValue(s,KeyAzimuth(),f)) mDevice->Azimuth(f); if(this->UnPackValue(s,KeyElevation(),f)) mDevice->Elevation(f); if(this->UnPackValue(s,KeyYaw(),f)) mDevice->Yaw(f); if(this->UnPackValue(s,KeyPitch(),f)) mDevice->Pitch(f); if(this->UnPackValue(s,KeyRoll(),f)) mDevice->Roll(f); if(this->UnPackValue(s,KeyZoom(),f) && f>1.0e-30) { if(mDevice->GetParallelProjection() != 0) { mDevice->SetParallelScale(mDevice->GetParallelScale()/f); } else { mDevice->Dolly(f); } } iObject::ReportMissingKeys(true); } void iCamera::SetPosition(const iPosition &p) { mDevice->SetPosition(p); } void iCamera::SetFocalPoint(const iPosition &p) { mDevice->SetFocalPoint(p); } void iCamera::SyncProjections() { static const double minDistance = 0.0002; // idiotic VTK limit double r = 1.0e-35 + tan(0.5*iMath::Deg2Rad(mDevice->GetViewAngle())); if(mDevice->GetParallelProjection() != 0) { double d = mDevice->GetParallelScale()/r; if(d > minDistance) mDevice->Dolly(mDevice->GetDistance()/d); } else { mDevice->SetParallelScale(mDevice->GetDistance()*r); } mRenderTool->ResetCameraClippingRange(); } ifrit-3.4.2/core/icamera.h0000755000175700010010000000640412167404407013720 0ustar HomeNone/*========================================================================= Program: Ionization FRont Interactive Tool (IFRIT) Language: C++ Copyright (c) 2002-2012 Nick Gnedin All rights reserved. This file may be distributed and/or modified under the terms of the GNU General Public License version 2 as published by the Free Software Foundation and appearing in the file LICENSE.GPL included in the packaging of this file. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHORS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. =========================================================================*/ // // This class is a merger of iObject with vtkCamera class. But since we cannot inherit, we must decorate // #ifndef ICAMERA_H #define ICAMERA_H #include "iobject.h" #include "iposition.h" class iEventObserver; class iRenderTool; class vtkCamera; class iCamera : public iObject { friend class iExtensionFactory; IPOINTER_AS_PART(ViewModule); public: vtkTypeMacro(iCamera,iObject); static const iObjectType& Type(); static iCamera* New(iRenderTool *rt = 0); IOBJECT_DECLARE_GETSET_POSITION(Position,mPosition); //virtual void SetPosition(const iPosition &p); //inline const iPosition& GetPosition() const { return mPosition; } IOBJECT_DECLARE_GETSET_POSITION(FocalPoint,mFocalPoint); //virtual void SetFocalPoint(const iPosition &p); //inline const iPosition& GetFocalPoint() const { return mFocalPoint; } // // Camera orientation // static const iObjectKey& KeyParallelProjection(); static const iObjectKey& KeyViewUp(); static const iObjectKey& KeyParallelScale(); static const iObjectKey& KeyViewAngle(); static const iObjectKey& KeyViewAngleVertical(); static const iObjectKey& KeyEyeAngle(); static const iObjectKey& KeyClippingRange(); static const iObjectKey& KeyClippingRangeAuto(); static const iObjectKey& KeySyncProjections(); // // action keys // static const iObjectKey& KeyAzimuth(); static const iObjectKey& KeyElevation(); static const iObjectKey& KeyYaw(); static const iObjectKey& KeyPitch(); static const iObjectKey& KeyRoll(); static const iObjectKey& KeyZoom(); static const iObjectKey& KeyReset(); void Reset(); void Update(); void OrthogonalizeView(); void ShiftTo(const iPosition& pos); vtkCamera* GetDevice() const { return mDevice; } protected: virtual ~iCamera(); virtual void PackStateBody(iString &s) const; virtual void UnPackStateBody(const iString &s); private: iCamera(iRenderTool *rt); void SyncProjections(); bool mSyncProjections; vtkCamera *mDevice; iEventObserver *mObserver; iRenderTool *mRenderTool; iPosition mPosition, mFocalPoint; }; #endif ifrit-3.4.2/core/icameraorthoactor.cpp0000755000175700010010000001377712167404425016373 0ustar HomeNone/*========================================================================= Program: Ionization FRont Interactive Tool (IFRIT) Language: C++ Copyright (c) 2002-2012 Nick Gnedin All rights reserved. This file may be distributed and/or modified under the terms of the GNU General Public License version 2 as published by the Free Software Foundation and appearing in the file LICENSE.GPL included in the packaging of this file. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHORS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. =========================================================================*/ #include "icameraorthoactor.h" #include "ierror.h" #include "ioverlayhelper.h" #include "itextactor.h" #include #include #include #include #include #include // // Templates // #include "iarraytemplate.h" #include "igenericproptemplate.h" iCameraOrthoActor* iCameraOrthoActor::New(iRenderTool *rt) { IERROR_ASSERT(rt); return new iCameraOrthoActor(rt); } iCameraOrthoActor::iCameraOrthoActor(iRenderTool *rt) : iGenericProp(false), mOverlayHelper(rt) { int i; for(i=0; i<2; i++) { mLabels[i] = iTextActor::New(rt); IERROR_ASSERT(mLabels[i]); this->AppendComponent(mLabels[i]); mLabels[i]->SetBold(true); mActors[i] = vtkAxisActor2D::New(); IERROR_ASSERT(mActors[i]); this->AppendComponent(mActors[i]); mActors[i]->GetPoint1Coordinate()->SetCoordinateSystemToNormalizedViewport(); mActors[i]->GetPoint2Coordinate()->SetCoordinateSystemToNormalizedViewport(); mActors[i]->SetPoint1(0.05,0.05); mActors[i]->TitleVisibilityOff(); mActors[i]->LabelVisibilityOff(); mActors[i]->TickVisibilityOff(); mActors[i]->GetProperty()->SetColor(0.0,0.0,0.0); mActors[i]->GetProperty()->SetLineWidth(2); } mActors[0]->SetPoint2(0.15,0.05); mActors[1]->SetPoint2(0.05,0.15); } iCameraOrthoActor::~iCameraOrthoActor() { int i; for(i=0; i<2; i++) { mActors[i]->Delete(); mLabels[i]->Delete(); } } void iCameraOrthoActor::UpdateGeometry(vtkViewport* vp) { static const double orts[6][3] = { { -1.0, 0.0, 0.0 }, { 1.0, 0.0, 0.0 }, { 0.0, -1.0, 0.0 }, { 0.0, 1.0, 0.0 }, { 0.0, 0.0, -1.0 }, { 0.0, 0.0, 1.0 } }; vtkCamera *cam = mOverlayHelper->GetCamera(vp); if(cam == 0) { this->Disable(); return; } // // Check direction of projection // double d, vx[3], *vy, dmax; int i, imax = 5, jmax = 3; dmax = 0.0; vtkMath::Cross(cam->GetViewUp(),cam->GetViewPlaneNormal(),vx); for(i=0; i<6; i++) { d = vtkMath::Dot(orts[i],vx); if(d > dmax) { dmax = d; imax = i; } } if(dmax < 0.99999) { this->Disable(); return; } // // Check view up. // dmax = 0.0; vy = cam->GetViewUp(); for(i=0; i<6; i++) { d = vtkMath::Dot(orts[i],vy); if(d > dmax) { dmax = d; jmax = i; } } if(dmax < 0.99999) { this->Disable(); return; } // // We are orthogonal // double as[2]; vp->GetAspect(as); if(as[0] > 1.0) { as[1] /= as[0]; as[0] = 1.0; } static const double off1 = 0.02; static const double off2 = 0.12; double pos1[2], pos2[2]; for(i=0; i<2; i++) { pos1[i] = off1/as[i]; pos2[i] = off2/as[i]; } int mag = mOverlayHelper->GetRenderingMagnification(); if(mag > 1) { int winij[2]; mOverlayHelper->ComputePositionShiftsUnderMagnification(winij); for(i=0; i<2; i++) { pos1[i] = mag*pos1[i]-winij[i]; pos2[i] = mag*pos2[i]-winij[i]; } } if(jmax%2 == 0) // y-neg { if(imax%2 == 0) // x-neg { mActors[0]->SetPoint1(pos2[0],pos2[1]); mActors[0]->SetPoint2(pos1[0]+0.2*(pos2[0]-pos1[0]),pos2[1]); mActors[1]->SetPoint1(pos2[0],pos2[1]); mActors[1]->SetPoint2(pos2[0],pos1[1]+0.2*(pos2[1]-pos1[1])); mLabels[0]->SetPosition(pos1[0],pos2[1]); mLabels[1]->SetPosition(pos2[0],pos1[1]); } else // x-pos { mActors[0]->SetPoint1(pos1[0],pos2[1]); mActors[0]->SetPoint2(pos2[0]-0.2*(pos2[0]-pos1[0]),pos2[1]); mActors[1]->SetPoint1(pos1[0],pos2[1]); mActors[1]->SetPoint2(pos1[0],pos1[1]+0.2*(pos2[1]-pos1[1])); mLabels[0]->SetPosition(pos2[0],pos2[1]); mLabels[1]->SetPosition(pos1[0],pos1[1]); } } else // y-pos { if(imax%2 == 0) // x-neg { mActors[0]->SetPoint1(pos2[0],pos1[1]); mActors[0]->SetPoint2(pos1[0]+0.2*(pos2[0]-pos1[0]),pos1[1]); mActors[1]->SetPoint1(pos2[0],pos1[1]); mActors[1]->SetPoint2(pos2[0],pos2[1]-0.2*(pos2[1]-pos1[1])); mLabels[0]->SetPosition(pos1[0],pos1[1]); mLabels[1]->SetPosition(pos2[0],pos2[1]); } else // x-pos { mActors[0]->SetPoint1(pos1[0],pos1[1]); mActors[0]->SetPoint2(pos2[0]-0.2*(pos2[0]-pos1[0]),pos1[1]); mActors[1]->SetPoint1(pos1[0],pos1[1]); mActors[1]->SetPoint2(pos1[0],pos2[1]-0.2*(pos2[1]-pos1[1])); mLabels[0]->SetPosition(pos2[0],pos1[1]); mLabels[1]->SetPosition(pos1[0],pos2[1]); } } switch(imax/2) { case 0: { mLabels[0]->SetText("X"); break; } case 1: { mLabels[0]->SetText("Y"); break; } case 2: { mLabels[0]->SetText("Z"); break; } }; switch(jmax/2) { case 0: { mLabels[1]->SetText("X"); break; } case 1: { mLabels[1]->SetText("Y"); break; } case 2: { mLabels[1]->SetText("Z"); break; } }; for(i=0; i<2; i++) { mActors[i]->GetProperty()->SetColor(this->GetOverlayHelper()->GetColor(vp).ToVTK()); mActors[i]->GetProperty()->SetLineWidth(2*mag); } } ifrit-3.4.2/core/icameraorthoactor.h0000644000175700010010000000370712167404407016025 0ustar HomeNone/*========================================================================= Program: Ionization FRont Interactive Tool (IFRIT) Language: C++ Copyright (c) 2002-2012 Nick Gnedin All rights reserved. This file may be distributed and/or modified under the terms of the GNU General Public License version 2 as published by the Free Software Foundation and appearing in the file LICENSE.GPL included in the packaging of this file. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHORS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. =========================================================================*/ // // A small actor that shows camera orientation when it is orthogonal // #ifndef ICAMERAORTHOACTOR_H #define ICAMERAORTHOACTOR_H #include "igenericprop.h" #include #include "ipointermacro.h" class iTextActor; class iOverlayHelper; class iRenderTool; class vtkAxisActor2D; class vtkCamera; class iCameraOrthoActor : public iGenericProp { IPOINTER_AS_USER(OverlayHelper); public: vtkTypeMacro(iCameraOrthoActor,vtkActor2D); static iCameraOrthoActor* New(iRenderTool *rt = 0); protected: virtual ~iCameraOrthoActor(); virtual void UpdateGeometry(vtkViewport *vp); private: iCameraOrthoActor(iRenderTool *rv); vtkAxisActor2D *mActors[2]; iTextActor *mLabels[2]; }; #endif ifrit-3.4.2/core/icamerapath.cpp0000755000175700010010000003067412167404426015137 0ustar HomeNone/*========================================================================= Program: Ionization FRont Interactive Tool (IFRIT) Language: C++ Copyright (c) 2002-2012 Nick Gnedin All rights reserved. This file may be distributed and/or modified under the terms of the GNU General Public License version 2 as published by the Free Software Foundation and appearing in the file LICENSE.GPL included in the packaging of this file. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHORS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. =========================================================================*/ #include "icamerapath.h" #include "iactor.h" #include "icontrolmodule.h" #include "ierror.h" #include "iviewmodule.h" #include #include #include #include #include #include #include // // Helper class // class iSplineWidget : public vtkSplineWidget { public: iSplineWidget() { this->HandlePicker->SetTolerance(0.01); this->LinePicker->SetTolerance(0.01); } virtual int GetCurrentHandleIndex(){ return CurrentHandleIndex; } }; // // Main class // iCameraPath* iCameraPath::New(iViewModule *vm) { IERROR_ASSERT(vm); return new iCameraPath(vm); } iCameraPath::iCameraPath(iViewModule *vm) : iEventObserver(vm->GetControlModule()->GetShell()), mViewModule(vm), mNumIntervalsPerSegment(5) { mIsFocalPath = mIsFocalPathToPoint = false; mCamPathWidget = new iSplineWidget; IERROR_ASSERT(mCamPathWidget); mCamPathWidget->SetNumberOfHandles(3); mCamPathWidget->SetResolution(mNumIntervalsPerSegment*2); mCamPathWidget->SetInteractor(this->GetViewModule()->GetInteractor()); mCamPathWidget->GetLineProperty()->SetLineWidth(4.0); mCamPathWidget->GetLineProperty()->SetColor(0.0,0.0,0.0); mCamPathWidget->SetHandlePosition(2,-1.0,0.0,1.0); mCamPathWidget->SetHandlePosition(1,0.0,0.0,1.0); mCamPathWidget->SetHandlePosition(0,1.0,0.0,1.0); mFocPathWidget = new iSplineWidget; IERROR_ASSERT(mFocPathWidget); mFocPathWidget->SetNumberOfHandles(3); mFocPathWidget->SetResolution(mNumIntervalsPerSegment*2); mFocPathWidget->SetInteractor(this->GetViewModule()->GetInteractor()); mFocPathWidget->GetLineProperty()->SetLineWidth(4.0); mFocPathWidget->GetLineProperty()->SetColor(0.4,0.5,0.6); mFocPathWidget->SetHandlePosition(2,-0.3,0.0,0.0); mFocPathWidget->SetHandlePosition(1,0.0,0.0,0.0); mFocPathWidget->SetHandlePosition(0,0.3,0.0,0.0); mCamPathWidget->AddObserver(vtkCommand::InteractionEvent,this); mCamPathWidget->AddObserver(vtkCommand::EnableEvent,this); mCamPathWidget->AddObserver(vtkCommand::DisableEvent,this); mFocPathWidget->AddObserver(vtkCommand::InteractionEvent,this); mFocPathWidget->AddObserver(vtkCommand::EnableEvent,this); mFocPathWidget->AddObserver(vtkCommand::DisableEvent,this); mCamPathData = vtkPolyData::New(); IERROR_ASSERT(mCamPathData); mFocPathData = vtkPolyData::New(); IERROR_ASSERT(mFocPathData); mCamPathHeadActor = iActor::New(true); IERROR_ASSERT(mCamPathHeadActor); mCamPathHeadSource = vtkConeSource::New(); IERROR_ASSERT(mCamPathHeadSource); mCamPathHeadSource->SetResolution(12); mCamPathHeadSource->SetRadius(0.1); mCamPathHeadSource->SetHeight(0.15); mCamPathHeadActor->SetInput(mCamPathHeadSource->GetOutput()); mCamPathHeadActor->GetProperty()->SetColor(0.0,0.68,1.0); mCamPathHeadActor->PickableOff(); mFocPathBandActor = iActor::New(); IERROR_ASSERT(mFocPathBandActor); mFocPathBandSource = vtkPolyData::New(); IERROR_ASSERT(mFocPathBandSource); mFocPathBandActor->SetInput(mFocPathBandSource); mFocPathBandActor->GetProperty()->SetColor(0.4,0.5,0.6); mFocPathBandActor->PickableOff(); mDxPrev[0] = 1.0; mDxPrev[1] = mDxPrev[2] = 0.0; } iCameraPath::~iCameraPath() { this->SetEnabled(false); mCamPathData->Delete(); mFocPathData->Delete(); mCamPathHeadActor->Delete(); mCamPathHeadSource->Delete(); mFocPathBandActor->Delete(); mFocPathBandSource->Delete(); mCamPathWidget->Delete(); mFocPathWidget->Delete(); } void iCameraPath::SetEnabled(bool s) { if(s && !this->GetEnabled()) { mCamPathWidget->SetEnabled(1); mFocPathWidget->SetEnabled(mIsFocalPath?1:0); this->GetViewModule()->AddObject(mCamPathHeadActor); this->GetViewModule()->AddObject(mFocPathBandActor); mFocPathBandActor->SetVisibility(mIsFocalPath?1:0); mCamPathWidget->InvokeEvent(vtkCommand::InteractionEvent); if(mIsFocalPath) mFocPathWidget->InvokeEvent(vtkCommand::InteractionEvent); } if(!s && this->GetEnabled()) { mCamPathWidget->SetEnabled(0); mFocPathWidget->SetEnabled(0); this->GetViewModule()->RemoveObject(mCamPathHeadActor); this->GetViewModule()->RemoveObject(mFocPathBandActor); } } bool iCameraPath::GetEnabled() const { return mCamPathWidget->GetEnabled() != 0; } void iCameraPath::SetNumberOfHandles(int v) { if(v > 1) { mCamPathWidget->SetNumberOfHandles(v); mCamPathWidget->SetResolution(mNumIntervalsPerSegment*(v-1)); if(mIsFocalPath) { mFocPathWidget->SetNumberOfHandles(v); mFocPathWidget->SetResolution(mNumIntervalsPerSegment*(v-1)); mFocPathWidget->InvokeEvent(vtkCommand::InteractionEvent); } } } int iCameraPath::GetNumberOfHandles() const { return mCamPathWidget->GetNumberOfHandles(); } //int iCameraPath::GetNumberOfIntervals() const //{ // return mCamPathWidget->GetResolution(); //} void iCameraPath::SetClosed(bool v) { if(v) { mCamPathWidget->ClosedOn(); mFocPathWidget->ClosedOn(); } else { mCamPathWidget->ClosedOff(); mFocPathWidget->ClosedOff(); } if(mIsFocalPath) mFocPathWidget->InvokeEvent(vtkCommand::InteractionEvent); } bool iCameraPath::GetClosed() const { return mCamPathWidget->GetClosed() != 0; } void iCameraPath::SetFocalPathEnabled(bool s) { mIsFocalPath = s; if(!this->GetEnabled()) return; if(s) { if(mCamPathWidget->GetResolution() != mFocPathWidget->GetResolution()) mFocPathWidget->SetResolution(mCamPathWidget->GetResolution()); if(mCamPathWidget->GetNumberOfHandles() != mFocPathWidget->GetNumberOfHandles()) mFocPathWidget->SetNumberOfHandles(mCamPathWidget->GetNumberOfHandles()); mFocPathWidget->SetEnabled(1); mFocPathBandActor->VisibilityOn(); mFocPathWidget->InvokeEvent(vtkCommand::InteractionEvent); } else { mFocPathWidget->SetEnabled(0); mFocPathBandActor->VisibilityOff(); } } void iCameraPath::SetFocalPathToPoint(bool s) { mIsFocalPathToPoint = s; if(mIsFocalPath) { if(!s) { int i; double x[3], sf; mFocPathWidget->GetHandlePosition(0,x); sf = 0.6/(mFocPathWidget->GetNumberOfHandles()-1); for(i=1; iGetNumberOfHandles(); i++) { x[0] -= sf; mFocPathWidget->SetHandlePosition(i,x); } } mFocPathWidget->InvokeEvent(vtkCommand::InteractionEvent); } } void iCameraPath::SetLineColor(iColor &c) { mCamPathWidget->GetLineProperty()->SetColor(c.ToVTK()); } void iCameraPath::SetHandleOpacity(float v) { mCamPathWidget->GetHandleProperty()->SetOpacity(v); } void iCameraPath::ExecuteBody(vtkObject *caller, unsigned long eventId, void *) { int i; switch (eventId) { case vtkCommand::InteractionEvent: { vtkPoints *cp = this->GetCameraPathPoints(); // // Camera path head // if(caller == mCamPathWidget) { double q1, x1[3], x2[3], dx[3], ax[3]; int i2; cp->GetPoint(0,x1); i2 = 1; while(i2 < mCamPathData->GetNumberOfPoints()) { cp->GetPoint(i2,x2); for(i=0; i<3; i++) dx[i] = x2[i] - x1[i]; if(vtkMath::Norm(dx) > 0) break; i2++; } vtkMath::Normalize(dx); // // Rotate // mCamPathHeadActor->SetOrientation(0.0,0.0,0.0); ax[0] = 0.5*(1+dx[0]); ax[1] = 0.5*dx[1]; ax[2] = 0.5*dx[2]; if(vtkMath::Norm(ax) > 0.0) { mCamPathHeadActor->RotateWXYZ(180.0,ax[0],ax[1],ax[2]); } else { if(vtkMath::Dot(dx,mDxPrev) < 0.0) { // // Flip // mCamPathHeadActor->RotateWXYZ(180.0,0.0,1.0,0.0); } } // // Translate // q1 = mCamPathHeadSource->GetHeight(); for(i=0; i<3; i++) dx[i] = x1[i] - q1*dx[i]; mCamPathHeadActor->SetPosition(dx); } // // Collapse focal path to point // if(caller==mFocPathWidget && mIsFocalPathToPoint) { double x[3]; i = mFocPathWidget->GetCurrentHandleIndex(); if(i<0 || i>=mFocPathWidget->GetNumberOfHandles()) i = 0; mFocPathWidget->GetHandlePosition(i,x); for(i=0; iGetNumberOfHandles(); i++) mFocPathWidget->SetHandlePosition(i,x); } // // Focal path band // if(mIsFocalPath) { vtkPoints *fp = this->GetFocalPathPoints(); int n = cp->GetNumberOfPoints(); int nstep = 1; if(n > 32) { n = 32; nstep = cp->GetNumberOfPoints()/n; } vtkPoints *newPoints = vtkPoints::New(VTK_FLOAT); IERROR_ASSERT(newPoints); vtkCellArray *newLines = vtkCellArray::New(); IERROR_ASSERT(newLines); newPoints->SetNumberOfPoints(2*n); newLines->Allocate(3*n); vtkIdType cell[2]; for(i=0; iSetPoint(2*i+0,cp->GetPoint(i*nstep)); newPoints->SetPoint(2*i+1,fp->GetPoint(i*nstep)); cell[0] = 2*i; cell[1] = 2*i + 1; newLines->InsertNextCell(2,cell); } mFocPathBandSource->SetPoints(newPoints); newPoints->Delete(); mFocPathBandSource->SetLines(newLines); newLines->Delete(); } break; } case vtkCommand::EnableEvent: { if(caller == mCamPathWidget) mCamPathHeadActor->VisibilityOn(); if(caller == mFocPathWidget) mFocPathBandActor->VisibilityOn(); break; } case vtkCommand::DisableEvent: { if(caller == mCamPathWidget) mCamPathHeadActor->VisibilityOff(); if(caller == mFocPathWidget) mFocPathBandActor->VisibilityOff(); break; } } } void iCameraPath::SetCameraPathHandlePosition(int n, double x[3]) { if(n>=0 && nGetNumberOfHandles()) { mCamPathWidget->SetHandlePosition(n,x); } } void iCameraPath::GetCameraPathHandlePosition(int n, double x[3]) const { if(n>=0 && nGetNumberOfHandles()) { mCamPathWidget->GetHandlePosition(n,x); } } void iCameraPath::SetFocalPathHandlePosition(int n, double x[3]) { if(n>=0 && nGetNumberOfHandles()) { mFocPathWidget->SetHandlePosition(n,x); } } void iCameraPath::GetFocalPathHandlePosition(int n, double x[3]) const { if(n>=0 && nGetNumberOfHandles()) { mFocPathWidget->GetHandlePosition(n,x); } } // // Special forms for Animator packing/unpacking // void iCameraPath::SetCameraPathHandlePositions(int dir, const float *x) { if(dir>=0 && dir<3) { double pos[3]; int i, n = mCamPathWidget->GetNumberOfHandles(); for(i=0; iGetHandlePosition(i,pos); pos[dir] = x[i]; mCamPathWidget->SetHandlePosition(i,pos); } } } void iCameraPath::GetCameraPathHandlePositions(float *x1, float *x2, float *x3) const { double pos[3]; int i, n = mCamPathWidget->GetNumberOfHandles(); for(i=0; iGetHandlePosition(i,pos); x1[i] = pos[0]; x2[i] = pos[1]; x3[i] = pos[2]; } } void iCameraPath::SetFocalPathHandlePositions(int dir, const float *x) { if(dir>=0 && dir<3) { double pos[3]; int i, n = mFocPathWidget->GetNumberOfHandles(); for(i=0; iGetHandlePosition(i,pos); pos[dir] = x[i]; mFocPathWidget->SetHandlePosition(i,pos); } } } void iCameraPath::GetFocalPathHandlePositions(float *x1, float *x2, float *x3) const { double pos[3]; int i, n = mFocPathWidget->GetNumberOfHandles(); for(i=0; iGetHandlePosition(i,pos); x1[i] = pos[0]; x2[i] = pos[1]; x3[i] = pos[2]; } } vtkPoints* iCameraPath::GetCameraPathPoints() { mCamPathWidget->GetPolyData(mCamPathData); return mCamPathData->GetPoints(); } vtkPoints* iCameraPath::GetFocalPathPoints() { if(mIsFocalPath) { mFocPathWidget->GetPolyData(mFocPathData); return mFocPathData->GetPoints(); } else return 0; } ifrit-3.4.2/core/icamerapath.h0000755000175700010010000000646012167404407014577 0ustar HomeNone/*========================================================================= Program: Ionization FRont Interactive Tool (IFRIT) Language: C++ Copyright (c) 2002-2012 Nick Gnedin All rights reserved. This file may be distributed and/or modified under the terms of the GNU General Public License version 2 as published by the Free Software Foundation and appearing in the file LICENSE.GPL included in the packaging of this file. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHORS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. =========================================================================*/ // // The camera path with the focal path, focal path band, and a camera path header // #ifndef ICAMERAPATH_H #define ICAMERAPATH_H #include "ieventobserver.h" #include "icolor.h" class iActor; class iSplineWidget; class iViewModule; class vtkConeSource; class vtkPoints; class vtkPolyData; class iCameraPath : public iEventObserver { IPOINTER_AS_PART(ViewModule); public: vtkTypeMacro(iCameraPath,iEventObserver); static iCameraPath* New(iViewModule *vm = 0); virtual void SetEnabled(bool s); bool GetEnabled() const; virtual void SetNumberOfHandles(int n); int GetNumberOfHandles() const; // int GetNumberOfIntervals() const; virtual void SetClosed(bool s); bool GetClosed() const; virtual void SetFocalPathEnabled(bool s); bool GetFocalPathEnabled() const { return mIsFocalPath; } virtual void SetFocalPathToPoint(bool s); bool GetFocalPathToPoint() const { return mIsFocalPathToPoint; } void SetLineColor(iColor &c); void SetHandleOpacity(float v); void SetCameraPathHandlePosition(int n, double x[3]); void GetCameraPathHandlePosition(int n, double x[3]) const; void SetFocalPathHandlePosition(int n, double x[3]); void GetFocalPathHandlePosition(int n, double x[3]) const; // // Special forms for Animator packing/unpacking // void SetCameraPathHandlePositions(int dir, const float *x); void GetCameraPathHandlePositions(float *x1, float *x2, float *x3) const; void SetFocalPathHandlePositions(int dir, const float *x); void GetFocalPathHandlePositions(float *x1, float *x2, float *x3) const; vtkPoints* GetCameraPathPoints(); vtkPoints* GetFocalPathPoints(); protected: virtual ~iCameraPath(); virtual void ExecuteBody(vtkObject *caller, unsigned long event, void *data); private: iCameraPath(iViewModule *vm); iSplineWidget *mCamPathWidget, *mFocPathWidget; iActor *mCamPathHeadActor, *mFocPathBandActor; vtkConeSource *mCamPathHeadSource; vtkPolyData *mCamPathData, *mFocPathData, *mFocPathBandSource; bool mIsFocalPath, mIsFocalPathToPoint; double mDxPrev[3]; const int mNumIntervalsPerSegment; }; #endif // ICAMERAPATH_H ifrit-3.4.2/core/icaption.cpp0000755000175700010010000001254012167404426014457 0ustar HomeNone/*========================================================================= Program: Ionization FRont Interactive Tool (IFRIT) Language: C++ Copyright (c) 2002-2012 Nick Gnedin All rights reserved. This file may be distributed and/or modified under the terms of the GNU General Public License version 2 as published by the Free Software Foundation and appearing in the file LICENSE.GPL included in the packaging of this file. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHORS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. =========================================================================*/ #include "icaption.h" #include "iactor.h" #include "ierror.h" #include "ioverlayhelper.h" #include #include #include #include #include #include #include #include #include // // Templates // #include "iarraytemplate.h" #include "igenericproptemplate.h" bool iCaption::Transparent = true; iCaption* iCaption::New(iRenderTool *rt) { IERROR_ASSERT(rt); return new iCaption(rt); } iCaption::iCaption(iRenderTool *rt) : iFramedTextActor(rt) { this->SetJustification(-1,-1); // // This is the leader (line) from the attachment point to the caption // mLeaderInput = vtkPolyData::New(); IERROR_ASSERT(mLeaderInput); vtkPoints *pts = vtkPoints::New(VTK_DOUBLE); IERROR_ASSERT(pts); pts->SetNumberOfPoints(2); mLeaderInput->SetPoints(pts); pts->Delete(); vtkCellArray *leader = vtkCellArray::New(); IERROR_ASSERT(leader); leader->InsertNextCell(2); leader->InsertCellPoint(0); leader->InsertCellPoint(1); //at the attachment point mLeaderInput->SetLines(leader); leader->Delete(); mLeaderActor = iActor::New(); IERROR_ASSERT(mLeaderActor); this->PrependComponent(mLeaderActor); mLeaderActor->SetInput(mLeaderInput); mAttachmentPoint = vtkCoordinate::New(); IERROR_ASSERT(mAttachmentPoint); mAttachmentPoint->SetCoordinateSystemToWorld(); mAttachmentPoint->SetValue(0.0,0.0,0.0); } iCaption::~iCaption() { mAttachmentPoint->Delete(); mLeaderInput->Delete(); mLeaderActor->Delete(); } void iCaption::SetAttachmentPoint(double x[3]) { mAttachmentPoint->SetValue(x); } const double* iCaption::GetAttachmentPoint() { return mAttachmentPoint->GetValue(); } void iCaption::UpdateGeometry(vtkViewport* vp) { static const int index[5][2] = { { 0, 2 }, { 1, 2 }, { 1, 3 }, { 0, 3 }, { 0, 2 } }; iFramedTextActor::UpdateGeometry(vp); if(!this->IsEnabled()) return; int mag = this->GetOverlayHelper()->GetRenderingMagnification(); if(mag == 1) { this->SetTransparent(Transparent); // // Compute the screen projection of the attachment point // int *vl = mAttachmentPoint->GetComputedViewportValue(vp); int *vs = vp->GetSize(); int j; float pa[3]; for(j=0; j<2; j++) pa[j] = float(vl[j])/vs[j]; // // Define the leader. Have to find the closest point from the // border to the attachment point. We look at the four vertices // and four edge centers. // float d2, d2min, pt[3], ptmin[2]; d2min = VTK_LARGE_FLOAT; pt[2] = pa[2] = 0.0; for(j=0; j<8; j++) { if(j%2 == 0) { pt[0] = wBounds[index[j/2][0]]; pt[1] = wBounds[index[j/2][1]]; } else { pt[0] = 0.5*(wBounds[index[j/2][0]]+wBounds[index[j/2+1][0]]); pt[1] = 0.5*(wBounds[index[j/2][1]]+wBounds[index[j/2+1][1]]); } d2 = vtkMath::Distance2BetweenPoints(pa,pt); if(d2 < d2min) { d2min = d2; ptmin[0] = pt[0]; ptmin[1] = pt[1]; } } // // Find the world coordinates of the nearest point. // vtkCamera *cam = this->GetOverlayHelper()->GetCamera(vp); double x[4], d[3]; double *clip = cam->GetClippingRange(); double *cpos = cam->GetPosition(); vp->SetDisplayPoint(ptmin[0]*vs[0],ptmin[1]*vs[1],0.0); vp->DisplayToWorld(); vp->GetWorldPoint(x); for(j=0; j<3; j++) d[j] = x[j] - cpos[j]; double cdop[3]; cam->GetDirectionOfProjection(cdop); vtkMath::Normalize(cdop); float s = clip[0]/vtkMath::Dot(d,cdop); for(j=0; j<3; j++) x[j] = cpos[j] + s*d[j]; #ifdef I_DEBUG iConsole::PrintDebugMessage(iString("Caption: ")+iString::FromNumber(d2min)+" ("+iString::FromNumber(ptmin[0])+","+iString::FromNumber(ptmin[1])+")"); iConsole::PrintDebugMessage(iString(" ")+iString::FromNumber(s)+" ("+iString::FromNumber(x[0])+","+iString::FromNumber(x[1])+","+iString::FromNumber(x[2])+","+iString::FromNumber(x[3])+")"); #endif vtkPoints *pts = mLeaderInput->GetPoints(); pts->SetPoint(0,mAttachmentPoint->GetValue()); pts->SetPoint(1,x); mLeaderInput->Modified(); mLeaderActor->GetProperty()->SetColor(this->GetOverlayHelper()->GetColor(vp).ToVTK()); } mLeaderActor->GetProperty()->SetLineWidth(2*mag); } ifrit-3.4.2/core/icaption.h0000644000175700010010000000362112167404407014120 0ustar HomeNone/*========================================================================= Program: Ionization FRont Interactive Tool (IFRIT) Language: C++ Copyright (c) 2002-2012 Nick Gnedin All rights reserved. This file may be distributed and/or modified under the terms of the GNU General Public License version 2 as published by the Free Software Foundation and appearing in the file LICENSE.GPL included in the packaging of this file. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHORS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. =========================================================================*/ #ifndef ICAPTION_H #define ICAPTION_H #include "iframedtextactor.h" class iActor; class vtkCoordinate; class vtkPolyData; class iCaption: public iFramedTextActor { public: vtkTypeMacro(iCaption,iFramedTextActor); static iCaption* New(iRenderTool *rt = 0); void SetAttachmentPoint(double x[3]); const double* GetAttachmentPoint(); static bool Transparent; protected: virtual ~iCaption(); virtual void UpdateGeometry(vtkViewport *vp); private: iCaption(iRenderTool *rv); vtkCoordinate *mAttachmentPoint; float mUnmagx1[2], mUnmagx2[2]; // // Leader // vtkPolyData *mLeaderInput; iActor *mLeaderActor; }; #endif // ICAPTION_H ifrit-3.4.2/core/icaptioninteractorstyle.cpp0000755000175700010010000001377412167404426017645 0ustar HomeNone/*========================================================================= Program: Ionization FRont Interactive Tool (IFRIT) Language: C++ Copyright (c) 2002-2012 Nick Gnedin All rights reserved. This file may be distributed and/or modified under the terms of the GNU General Public License version 2 as published by the Free Software Foundation and appearing in the file LICENSE.GPL included in the packaging of this file. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHORS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. =========================================================================*/ #include "icaptioninteractorstyle.h" #include "icaption.h" #include "imarker.h" #include "imarkerfamily.h" #include "irendertool.h" #include "iviewmodule.h" #include "iviewobjectfamily.h" #include #include #include #include #include #include #include #include #include // // Templates (needed for some compilers) // #include "iarraytemplate.h" iCaptionInteractorStyle* iCaptionInteractorStyle::New(iViewModule *vm) { IERROR_ASSERT(vm); return new iCaptionInteractorStyle(vm); } iCaptionInteractorStyle::iCaptionInteractorStyle(iViewModule *vm) : mViewModule(vm) { mInteractionMarker = 0; // // Experimental: gray screen for moving captions // vtkPolyData *data = vtkPolyData::New(); IERROR_ASSERT(data); vtkPoints *pts = vtkPoints::New(VTK_FLOAT); IERROR_ASSERT(pts); pts->SetNumberOfPoints(4); pts->SetPoint(0,0.0,0.0,0.0); pts->SetPoint(1,1.0,0.0,0.0); pts->SetPoint(2,1.0,1.0,0.0); pts->SetPoint(3,0.0,1.0,0.0); data->SetPoints(pts); pts->Delete(); vtkCellArray *cells = vtkCellArray::New(); IERROR_ASSERT(cells); cells->InsertNextCell(4); cells->InsertCellPoint(0); cells->InsertCellPoint(1); cells->InsertCellPoint(2); cells->InsertCellPoint(3); data->SetPolys(cells); cells->Delete(); vtkPolyDataMapper2D *mapper = vtkPolyDataMapper2D::New(); IERROR_ASSERT(mapper); mapper->SetInput(data); data->Delete(); vtkCoordinate *c = vtkCoordinate::New(); IERROR_ASSERT(c); c->SetCoordinateSystemToNormalizedViewport(); mapper->SetTransformCoordinate(c); c->Delete(); mScreen = vtkActor2D::New(); IERROR_ASSERT(mScreen); mScreen->SetMapper(mapper); mapper->Delete(); mScreen->GetPositionCoordinate()->SetCoordinateSystemToNormalizedViewport(); mScreen->SetPosition(0.0,0.0); mScreen->SetLayerNumber(10); mScreen->GetProperty()->SetOpacity(0.7); mScreen->GetProperty()->SetColor(0.5,0.5,0.5); this->GetViewModule()->GetRenderTool()->AddObject(mScreen); mScreen->SetVisibility(0); wNextStyle = 0; wTransparentCaptions = true; } iCaptionInteractorStyle::~iCaptionInteractorStyle() { this->GetViewModule()->GetRenderTool()->RemoveObject(mScreen); mScreen->Delete(); } void iCaptionInteractorStyle::Launch(vtkInteractorStyle *next) { mScreen->SetVisibility(1); wNextStyle = next; wTransparentCaptions = iCaption::Transparent; iCaption::Transparent = false; } void iCaptionInteractorStyle::FindPickedActor(int x, int y) { int i; if(this->CurrentRenderer == 0) return; for(i=0; i<=this->GetViewModule()->GetMarkerFamily()->GetMaxMemberIndex(); i++) if(this->GetViewModule()->GetMarkerFamily()->GetMember(i)->GetMarkerCaption()->GetVisibility() == 1) { int *s = this->CurrentRenderer->GetSize(); float b[4]; this->GetViewModule()->GetMarkerFamily()->GetMember(i)->GetMarkerCaption()->GetBounds(this->CurrentRenderer,b); if(x>b[0]*s[0] && y>b[2]*s[1] && xGetViewModule()->GetMarkerFamily()->GetMember(i); return; } } mInteractionMarker = 0; } // // Rotating - a copy of vtkInteractorStyleTrackballActor::Rotate() with // no changes // void iCaptionInteractorStyle::Rotate() { if(CurrentRenderer==0 || mInteractionMarker==0) { return; } vtkRenderWindowInteractor *rwi = this->Interactor; int *size = CurrentRenderer->GetSize(); float dx = rwi->GetEventPosition()[0] - rwi->GetLastEventPosition()[0]; float dy = rwi->GetEventPosition()[1] - rwi->GetLastEventPosition()[1]; const float *x = mInteractionMarker->GetCaptionPosition(); mInteractionMarker->SetCaptionPosition(x[0]+dx/size[0],x[1]+dy/size[1]); rwi->Render(); } // // Need to overload this function too because it is not declared virtual in the parent class // void iCaptionInteractorStyle::OnLeftButtonDown() { int x = Interactor->GetEventPosition()[0]; int y = Interactor->GetEventPosition()[1]; this->FindPokedRenderer(x, y); this->FindPickedActor(x, y); if(CurrentRenderer!=0 && mInteractionMarker!=0) { this->StartRotate(); } else { this->Finish(); } } void iCaptionInteractorStyle::OnLeftButtonUp() { // // Quantize the position // if(mInteractionMarker != 0) { int *size = CurrentRenderer->GetSize(); const float *x0 = mInteractionMarker->GetCaptionPosition(); float x[2]; x[0] = 10.0*floor(0.1*x0[0]*size[0])/size[0]; x[1] = 10.0*floor(0.1*x0[1]*size[1])/size[1]; mInteractionMarker->SetCaptionPosition(x[0],x[1]); Interactor->Render(); } } void iCaptionInteractorStyle::Finish() { if(mScreen->GetVisibility() != 0) { mScreen->SetVisibility(0); iCaption::Transparent = wTransparentCaptions; Interactor->Render(); if(wNextStyle != 0) { this->GetInteractor()->SetInteractorStyle(wNextStyle); } } } ifrit-3.4.2/core/icaptioninteractorstyle.h0000755000175700010010000000507012167404407017277 0ustar HomeNone/*========================================================================= Program: Ionization FRont Interactive Tool (IFRIT) Language: C++ Copyright (c) 2002-2012 Nick Gnedin All rights reserved. This file may be distributed and/or modified under the terms of the GNU General Public License version 2 as published by the Free Software Foundation and appearing in the file LICENSE.GPL included in the packaging of this file. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHORS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. =========================================================================*/ #ifndef ICAPTIONINTERACTORSTYLE_H #define ICAPTIONINTERACTORSTYLE_H #include #include "ipointermacro.h" class iMarker; class iViewModule; class vtkActor2D; class iCaptionInteractorStyle: public vtkInteractorStyleTrackballActor { IPOINTER_AS_PART(ViewModule); public: vtkTypeMacro(iCaptionInteractorStyle,vtkInteractorStyleTrackballActor); static iCaptionInteractorStyle* New(iViewModule *vm = 0); void Launch(vtkInteractorStyle *next); void FindPickedActor(int x, int y); virtual void Rotate(); virtual void OnLeftButtonUp(); virtual void OnLeftButtonDown(); // // Disable all interactions except left mouse moving the caption around // virtual void Spin(){} virtual void Pan(){} virtual void Dolly(){} virtual void UniformScale(){} virtual void OnLeave(){ this->Finish(); } virtual void OnChar(){ this->Finish(); } virtual void OnMiddleButtonDown(){ this->Finish(); } virtual void OnMiddleButtonUp(){} virtual void OnRightButtonDown(){ this->Finish(); } virtual void OnRightButtonUp(){} protected: virtual ~iCaptionInteractorStyle(); private: iCaptionInteractorStyle(iViewModule *vm); void Finish(); iMarker *mInteractionMarker; vtkActor2D *mScreen; vtkInteractorStyle *wNextStyle; bool wTransparentCaptions; }; #endif // ICAPTIONINTERACTORSTYLE_H ifrit-3.4.2/core/iclipplane.cpp0000755000175700010010000001031312167404426014765 0ustar HomeNone/*========================================================================= Program: Ionization FRont Interactive Tool (IFRIT) Language: C++ Copyright (c) 2002-2012 Nick Gnedin All rights reserved. This file may be distributed and/or modified under the terms of the GNU General Public License version 2 as published by the Free Software Foundation and appearing in the file LICENSE.GPL included in the packaging of this file. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHORS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. =========================================================================*/ #include "iclipplane.h" #include "iactor.h" #include "ierror.h" #include "itransform.h" #include "iviewmodule.h" #include #include #include #include #include #include #include // // Main class // iClipPlane* iClipPlane::New(iViewModule *vm) { IERROR_ASSERT(vm); return new iClipPlane(vm); } iClipPlane::iClipPlane(iViewModule *vm) : mViewModule(vm) { int i, j; // // Set plane parameters // vtkPolyData *pd = vtkPolyData::New(); IERROR_ASSERT(pd); mClipPlaneActor = iActor::New(); IERROR_ASSERT(mClipPlaneActor); static float x1[8][3] = { {1.0,0.0,0.0}, {0.7071,0.7071,0.0}, {0.0,1.0,0.0}, {-0.7071,0.7071,0.0}, {-1.0,0.0,0.0}, {-0.7071,-0.7071,0.0}, {0.0,-1.0,0.0}, {0.7071,-0.7071,0.0} }; static vtkIdType pts1[8] = { 0, 1, 2, 3, 4, 5, 6, 7 }; for(i=0; i<8; i++) for(j=0; j<3; j++) x1[i][j] *= 2.5; vtkPoints *points = vtkPoints::New(VTK_FLOAT); IERROR_ASSERT(points); for(i=0; i<8; i++) points->InsertPoint(i,x1[i]); pd->SetPoints(points); points->Delete(); vtkCellArray *polys = vtkCellArray::New(); IERROR_ASSERT(polys); polys->InsertNextCell(8,pts1); pd->SetPolys(polys); polys->Delete(); pd->Update(); mClipPlaneActor->SetInput(pd); pd->Delete(); mClipPlaneActor->VisibilityOff(); mClipPlaneActor->PickableOff(); mClipPlaneActor->GetProperty()->SetOpacity(0.5); mClipPlaneActor->GetProperty()->SetAmbient(1.0); mClipPlaneActor->GetProperty()->SetDiffuse(1.0); mClipPlaneActor->GetProperty()->SetSpecular(0.7); mClipPlaneActor->GetProperty()->SetSpecularPower(50.0); mClipPlaneActor->GetProperty()->SetColor(0.6,0.7,0.7); mTransform = iTransform::New(); IERROR_ASSERT(mTransform); mClipPlaneActor->SetUserTransform(mTransform); this->GetViewModule()->AddObject(mClipPlaneActor); mDistance = 0.0f; float dir[3] = { 1.0, 0.0, 0.0 }; this->SetDirection(dir); } iClipPlane::~iClipPlane() { this->GetViewModule()->RemoveObject(mClipPlaneActor); mClipPlaneActor->Delete(); mTransform->Delete(); } void iClipPlane::SetGlassPlaneVisible(bool s) { mClipPlaneActor->SetVisibility(s?1:0); } bool iClipPlane::GetGlassPlaneVisible() const { return mClipPlaneActor->GetVisibility() != 0; } void iClipPlane::SetDirection(const float *dir) { int i; double x[3]; double n[3]; for(i=0; i<3; i++) mClipPlaneDirection[i] = dir[i]; vtkMath::Normalize(mClipPlaneDirection); for(i=0; i<3; i++) n[i] = -mClipPlaneDirection[i]; this->SetNormal(n); for(i=0; i<3; i++) x[i] = -mDistance*n[i]; this->SetOrigin(x); // // Move the glass plane // mTransform->Identity(); mTransform->SetDirection(mClipPlaneDirection); mTransform->Translate(0.0,0.0,mDistance); } void iClipPlane::SetDistance(float l) { int i; double x[3]; double n[3]; this->GetNormal(n); mDistance = l; for(i=0; i<3; i++) x[i] = -l*n[i]; this->SetOrigin(x); mTransform->Identity(); mTransform->SetDirection(mClipPlaneDirection); mTransform->Translate(0.0,0.0,mDistance); } ifrit-3.4.2/core/iclipplane.h0000755000175700010010000000437412167404407014443 0ustar HomeNone/*========================================================================= Program: Ionization FRont Interactive Tool (IFRIT) Language: C++ Copyright (c) 2002-2012 Nick Gnedin All rights reserved. This file may be distributed and/or modified under the terms of the GNU General Public License version 2 as published by the Free Software Foundation and appearing in the file LICENSE.GPL included in the packaging of this file. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHORS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. =========================================================================*/ // // A vtkPlane with a glass plane representation // #ifndef ICLIPPLANE_H #define ICLIPPLANE_H #include #include "ipointermacro.h" #include class iActor; class iTransform; class iViewModule; class iClipPlane : public vtkPlane { IPOINTER_AS_PART(ViewModule); public: vtkTypeMacro(iClipPlane,vtkPlane); static iClipPlane* New(iViewModule *vm = 0); void SetDirection(const float *dir); inline void GetDirection(float *dir) const { for(int i=0; i<3; i++) dir[i] = mClipPlaneDirection[i]; } inline const float* GetDirection() const { return mClipPlaneDirection; } void SetDistance(float d); inline float GetDistance() const { return mDistance; } void SetGlassPlaneVisible(bool s); bool GetGlassPlaneVisible() const; protected: virtual ~iClipPlane(); private: iClipPlane(iViewModule *vm); // // Actors displayed by this class // iActor *mClipPlaneActor; iTransform *mTransform; float mDistance, mClipPlaneDirection[3], mClipPlaneActorNormal[3]; }; #endif // ICLIPPLANE_H ifrit-3.4.2/core/icolor.cpp0000755000175700010010000000333112167404426014136 0ustar HomeNone/*========================================================================= Program: Ionization FRont Interactive Tool (IFRIT) Language: C++ Copyright (c) 2002-2012 Nick Gnedin All rights reserved. This file may be distributed and/or modified under the terms of the GNU General Public License version 2 as published by the Free Software Foundation and appearing in the file LICENSE.GPL included in the packaging of this file. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHORS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. =========================================================================*/ #include "icolor.h" iColor iColor::Reverse() const { return iColor(255-mRed,255-mGreen,255-mBlue,mAlpha); } iColor iColor::Shadow() const { int c = (mRed+mGreen+mBlue)/3 > 127 ? 0 : 255; return iColor(c,c,c,mAlpha); } const iColor& iColor::Black() { static const iColor tmp(0,0,0); return tmp; } const iColor& iColor::White() { static const iColor tmp(255,255,255); return tmp; } const iColor& iColor::Invalid() { static const iColor tmp(-1,-1,-1); return tmp; } ifrit-3.4.2/core/icolor.h0000755000175700010010000000675012167404407013612 0ustar HomeNone/*========================================================================= Program: Ionization FRont Interactive Tool (IFRIT) Language: C++ Copyright (c) 2002-2012 Nick Gnedin All rights reserved. This file may be distributed and/or modified under the terms of the GNU General Public License version 2 as published by the Free Software Foundation and appearing in the file LICENSE.GPL included in the packaging of this file. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHORS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. =========================================================================*/ #ifndef ICOLOR_H #define ICOLOR_H class iColor { public: iColor(); iColor(const iColor &c); iColor(int r, int g, int b, int a = 255); iColor(double c[3], double alpha = 1.0); inline int Red() const { return mRed; } inline int Green() const { return mGreen; } inline int Blue() const { return mBlue; } inline int Alpha() const { return mAlpha; } inline int Intensity() const { return (mRed+mGreen+mBlue)/3; } inline void GetRGB(char rgb[3]) const { rgb[0] = (char)mRed; rgb[1] = (char)mGreen; rgb[2] = (char)mBlue; } inline void GetRGB(unsigned char rgb[3]) const { rgb[0] = (unsigned char)mRed; rgb[1] = (unsigned char)mGreen; rgb[2] = (unsigned char)mBlue; } double* ToVTK() const { return (double *)mVTK; } iColor Reverse() const; iColor Shadow() const; friend bool operator==(const iColor &s1, const iColor &s2); friend bool operator!=(const iColor &s1, const iColor &s2); bool IsValid() const; // // Some colors // static const iColor& Black(); static const iColor& White(); static const iColor& Invalid(); private: void Update(); int mRed, mGreen, mBlue, mAlpha; double mVTK[4]; }; inline void iColor::Update() { mVTK[0] = mRed/255.0; mVTK[1] = mGreen/255.0; mVTK[2] = mBlue/255.0; mVTK[3] = mAlpha/255.0; } inline iColor::iColor() { mAlpha = 1; mRed = mGreen = mBlue = 0; this->Update(); } inline iColor::iColor(const iColor &c) { mRed = c.mRed; mGreen = c.mGreen; mBlue = c.mBlue; mAlpha = c.mAlpha; this->Update(); } inline iColor::iColor(int r, int g, int b, int a) { mRed = r; mGreen = g; mBlue = b; mAlpha = a; this->Update(); } inline iColor::iColor(double c[3], double alpha) { mRed = int(255*c[0]); mGreen = int(255*c[1]); mBlue = int(255*c[2]); mAlpha = int(255*alpha); this->Update(); } inline bool operator==(const iColor &s1, const iColor &s2) { return (s1.mRed==s2.mRed) && (s1.mGreen==s2.mGreen) && (s1.mBlue==s2.mBlue) && (s1.mAlpha==s2.mAlpha); } inline bool operator!=(const iColor &s1, const iColor &s2) { return (s1.mRed!=s2.mRed) || (s1.mGreen!=s2.mGreen) || (s1.mBlue!=s2.mBlue) || (s1.mAlpha!=s2.mAlpha); } inline bool iColor::IsValid() const { return (mRed>=0 && mRed<256 && mGreen>=0 && mGreen<256 && mBlue>=0 && mBlue<256 && mAlpha>=0 && mAlpha<256); } #endif // ICOLOR_H ifrit-3.4.2/core/icolorbars.cpp0000755000175700010010000003472712167404426015023 0ustar HomeNone/*========================================================================= Program: Ionization FRont Interactive Tool (IFRIT) Language: C++ Copyright (c) 2002-2012 Nick Gnedin All rights reserved. This file may be distributed and/or modified under the terms of the GNU General Public License version 2 as published by the Free Software Foundation and appearing in the file LICENSE.GPL included in the packaging of this file. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHORS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. =========================================================================*/ #include "icolorbars.h" #include "icontrolmodule.h" #include "idata.h" #include "idatalimits.h" #include "idatareader.h" #include "idatastretch.h" #include "ierror.h" #include "igenericprop.h" #include "imath.h" #include "ioverlayhelper.h" #include "ipaletteset.h" #include "itextactor.h" #include "iviewmodule.h" #include #include #include #include #include #include using namespace iParameter; // // Templates // #include "iarraytemplate.h" #include "igenericproptemplate.h" IOBJECT_DEFINE_TYPE(iColorBars,ColorBars,cb,iObjectType::_Helper); IOBJECT_DEFINE_KEY(iColorBars,Automatic,a,Bool,1); IOBJECT_DEFINE_KEY(iColorBars,BarLeft,bl,Int,3); IOBJECT_DEFINE_KEY(iColorBars,BarRight,br,Int,3); IOBJECT_DEFINE_KEY(iColorBars,Color,c,Color,1); IOBJECT_DEFINE_KEY(iColorBars,Size,s,Float,1); IOBJECT_DEFINE_KEY(iColorBars,SideOffset,so,Float,1); // // helper classes // class iColorBarLabel { friend class iColorBarActor; private: iColorBarLabel(bool left, iRenderTool *parent) { Base = iTextActor::New(parent); IERROR_ASSERT(Base); Power = iTextActor::New(parent); IERROR_ASSERT(Power); Base->SetJustification(left?1:-1); Power->SetJustification(-1); } ~iColorBarLabel() { Base->Delete(); Power->Delete(); } iTextActor *Base, *Power; }; class iColorBarActor : public iGenericProp { IPOINTER_AS_USER(OverlayHelper); public: vtkTypeMacro(iColorBarActor,vtkActor2D); static iColorBarActor* New(bool left = false, iColorBars *parent = 0); void SetSideOffset(float v); inline float GetSideOffset() const { return mOffset; } void SetHeight(float v); inline float GetHeight() const { return mHeight*0.86; } // there is a 0.86 factor in vtkScalarBarActor protected: virtual ~iColorBarActor(); virtual void UpdateGeometry(vtkViewport *vp); private: iColorBarActor(bool left, iColorBars *parent); void UpdatePlacement(); const iColorBarItem *mItem; bool mStarted; float mHeight, mOffset, mWidth4Height; float mXOff, mYOff; float mLabelOff, mTitleOff; int mJmax; bool mIsLeft; iColorBars *mParent; vtkScalarBarActor *mBarActor; iTextActor *mTitleActor; iArray mLabels; }; iColorBarActor* iColorBarActor::New(bool left, iColorBars *parent) { IERROR_ASSERT(parent); return new iColorBarActor(left,parent); } iColorBarActor::iColorBarActor(bool left, iColorBars *parent) : iGenericProp(false), mOverlayHelper(parent->GetViewModule()->GetRenderTool()) { int i; mIsLeft = left; mParent = parent; mItem = 0; mStarted = false; mJmax = 0; mWidth4Height = 0.03/0.7; mHeight = 0.7; mOffset = 0.08; mBarActor = vtkScalarBarActor::New(); IERROR_ASSERT(mBarActor); this->AppendComponent(mBarActor); mBarActor->GetPositionCoordinate()->SetCoordinateSystemToNormalizedViewport(); mBarActor->SetOrientationToVertical(); mBarActor->SetMaximumNumberOfColors(256); mBarActor->SetWidth(mWidth4Height*mHeight); mBarActor->SetHeight(mHeight); mBarActor->SetNumberOfLabels(0); mBarActor->SetTitle(""); mBarActor->PickableOff(); mTitleActor = iTextActor::New(this->GetOverlayHelper()->GetRenderTool()); IERROR_ASSERT(mTitleActor); this->AppendComponent(mTitleActor); mTitleActor->SetAngle(90.0); mTitleActor->SetJustification(left?-1:1,0); mTitleActor->SetBold(true); iColorBarLabel *l; for(i=0; i<10; i++) { l = new iColorBarLabel(left,this->GetOverlayHelper()->GetRenderTool()); IERROR_ASSERT(l); this->AppendComponent(l->Base); this->AppendComponent(l->Power); mLabels.Add(l); } this->UpdatePlacement(); } iColorBarActor::~iColorBarActor() { int i; mBarActor->Delete(); mTitleActor->Delete(); for(i=0; iSetPosition(mTitleOff,0.5); this->Modified(); } void iColorBarActor::SetSideOffset(float v) { if(v>=0.01 && v<=0.3) { mOffset = v; this->UpdatePlacement(); } } void iColorBarActor::SetHeight(float v) { if(v>=0.1 && v<=1.0) { if(v > 0.95) v = 0.95; // make sure labels are visible; mHeight = v/0.86; // there is a 0.86 factor in vtkScalarBarActor this->UpdatePlacement(); } } void iColorBarActor::UpdateGeometry(vtkViewport* viewport) { mItem = mParent->GetItem(mIsLeft); if(mItem==0 || mItem->Count==0 || mItem->Palette==0) { this->Disable(); return; } iDataLimits *lim = mParent->GetViewModule()->GetReader()->GetLimits(iDataType::FindTypeById(mItem->DataTypeId)); if(lim==0 || mItem->Var>=lim->GetNumVars()) { this->Disable(); return; } int j; float w1 = 0.0, h1 = 0.0, w2 = 0.0, h2 = 0.0; if(!mStarted) mStarted = true; int mag = this->GetOverlayHelper()->GetRenderingMagnification(); if(mag == 1) { mBarActor->SetPosition(mXOff,mYOff); mBarActor->SetWidth(mWidth4Height*mHeight); mBarActor->SetHeight(mHeight); int nstep, pow; float dv, voff, vstep, vbound, v; float s1[2], s2[2]; char s[100], *fmt; float vl = iDataStretch::ApplyStretch(lim->GetLowerLimit(mItem->Var),lim->GetStretch(mItem->Var),false); float vu = iDataStretch::ApplyStretch(lim->GetUpperLimit(mItem->Var),lim->GetStretch(mItem->Var),true); switch(lim->GetStretch(mItem->Var)) { case iDataStretch::Log: { // // Log table // int ivl = 1 + (int)floor(vl-0.01); int ivu = 0 + (int)floor(vu+0.01); dv = vu - vl; if(dv<=0.0 || ivl>vu) { this->Disable(); return; } voff = ivl - vl; int ndex = ivu - ivl; if(ndex > 1) nstep = 1 + ndex/mLabels.Size(); else nstep = 1; mJmax = 1 + ndex/nstep; vstep = nstep; for(j=0; jBase->SetText(" 1"); mLabels[j]->Power->SetText(""); } else { mLabels[j]->Base->SetText("10"); mLabels[j]->Power->SetText(s); } mLabels[j]->Base->GetSize(viewport,s1); mLabels[j]->Power->GetSize(viewport,s2); if(w1 < s1[0]) w1 = s1[0]; if(h1 < s1[1]) h1 = s1[1]; if(w2 < s2[0]) w2 = s2[0]; if(h2 < s2[1]) h2 = s2[1]; } break; } default: { // // Lin table // mJmax = 5; voff = 0.0; if(fabs(vl) < 1.0e-3*fabs(vu)) vl = 0.0; if(fabs(vu) < 1.0e-3*fabs(vl)) vu = 0.0; dv = vu - vl; if(fabs(dv) < 1.0e-30*fabs(vu)) // dv is zero { if(vu > 0.0) { vu = vu*1.001; vl = vl*0.999; } else if(vu < 0.0) { vu = vu*0.999; vl = vl*1.001; } else { vu = 1.0; vl = -1.0; } dv = vu - vl; } vstep = dv/(mJmax-1); vbound = (fabs(vl) > fabs(vu)) ? fabs(vl) : fabs(vu); if(fabs(vstep) > 0.03*vbound) { fmt = "%.2g"; } else if(fabs(vstep) > 0.003*vbound) { fmt = "%.3g"; } else { fmt = "%g"; } for(j=0; jBase->SetText(s); mLabels[j]->Power->SetText(""); mLabels[j]->Base->GetSize(viewport,s1); mLabels[j]->Power->GetSize(viewport,s2); if(w1 < s1[0]) w1 = s1[0]; if(h1 < s1[1]) h1 = s1[1]; if(w2 < s2[0]) w2 = s2[0]; if(h2 < s2[1]) h2 = s2[1]; } } } w1 *= 0.8; w2 *= 0.8; h1 *= 0.8; float xpos, ypos; xpos = mLabelOff; for(j=0; j 0.0) { ypos = mYOff + 0.86*mHeight*(voff+vstep*j)/dv; } else { ypos = mYOff + 0.86*mHeight*0.5; } if(!mIsLeft) { mLabels[j]->Base->SetPosition(xpos,ypos-0.5*h1); mLabels[j]->Power->SetPosition(w1+xpos,ypos+0.5*h1); } else { mLabels[j]->Base->SetPosition(xpos-w2,ypos-0.5*h1); mLabels[j]->Power->SetPosition(xpos-w2,ypos+0.5*h1); } } for(j=mJmax; jBase->SetText(""); mLabels[j]->Power->SetText(""); } mTitleActor->SetText(lim->GetName(mItem->Var).ToCharPointer()); mBarActor->SetLookupTable(iPaletteSet::Default()->GetLookupTable(mItem->Palette)); } else { mBarActor->SetWidth(mag*mWidth4Height*mHeight); mBarActor->SetHeight(mag*mHeight); // // Shift positions if under magnification - // int winij[2]; this->GetOverlayHelper()->ComputePositionShiftsUnderMagnification(winij); mBarActor->SetPosition(mag*mXOff-winij[0],mag*mYOff-winij[1]); } } const struct iColorBarItem iColorBars::NullItem = { 0, 0, 0, iMath::_IntMax, 0 }; // // Main class // iColorBars* iColorBars::New(iViewModule *vm) { IERROR_ASSERT(vm); return new iColorBars(vm); } iColorBars::iColorBars(iViewModule *vm) : iObject("ColorBars"), mViewModule(vm) { mAutomatic = true; // // Create manual bars // mManualBars.Add(NullItem); mManualBars.Add(NullItem); mManualBars[0].Priority = -2; mManualBars[1].Priority = -1; mManualBars[0].DataTypeId = mManualBars[1].DataTypeId = 1; mManualBars[0].Count = mManualBars[1].Count = 1; mActors[0] = iColorBarActor::New(false,this); IERROR_ASSERT(mActors[0]); mActors[1] = iColorBarActor::New(true,this); IERROR_ASSERT(mActors[1]); mColor = iColor::Invalid(); } iColorBars::~iColorBars() { int i; for(i=0; i<2; i++) mActors[i]->Delete(); } void iColorBars::SetSideOffset(float v) { int i; for(i=0; i<2; i++) mActors[i]->SetSideOffset(v); this->ClearCache(); } float iColorBars::GetSideOffset() const { return mActors[1]->GetSideOffset(); } void iColorBars::SetSize(float v) { int i; for(i=0; i<2; i++) mActors[i]->SetHeight(v); this->ClearCache(); } float iColorBars::GetSize() const { return mActors[1]->GetHeight(); } void iColorBars::SetColor(iColor c) { int i; mColor = c; for(i=0; i<2; i++) { mActors[i]->GetOverlayHelper()->SetFixedColor(c); mActors[i]->GetOverlayHelper()->SetAutoColor(!c.IsValid()); } this->ClearCache(); } void iColorBars::ShowBar(int priority, int v, const iDataType &dt, int p, bool show) { int i; if((!show && this->Queue().Size()<1) || v<0) return; iDataLimits *lim = this->GetViewModule()->GetReader()->GetLimits(dt); if(lim==0 || (show && v>=lim->GetNumVars())) return; iColorBarItem tmp; tmp.Var = v; tmp.Palette = p; tmp.DataTypeId = dt.GetId(); tmp.Priority = priority; i = this->Queue().Find(tmp); if(i >= 0) { if(show) this->Queue()[i].Count++; else { this->Queue()[i].Count--; if(this->Queue()[i].Count == 0) // delete the entry { this->Queue().iArray::Remove(i); } } } else { if(show) { // // Insert a new one keeping the list ordered by priority // tmp.Count = 1; this->Queue().Add(tmp); } else { // cannot delete non-existing entry } } this->ClearCache(); for(i=0; i<2; i++) mActors[i]->Modified(); } void iColorBars::SetAutomatic(bool automatic) { int i; mAutomatic = automatic; this->ClearCache(); for(i=0; i<2; i++) mActors[i]->Modified(); } void iColorBars::SetBar(int bar, int v, int id, int p) { if(bar>=0 && bar<2) { mManualBars[bar].Var = v; mManualBars[bar].Palette = p; mManualBars[bar].DataTypeId = id; this->ClearCache(); } } void iColorBars::GetBar(int bar, int &v, int &id, int &p) const { if(bar<0 || bar>1) { v = id = p = 0; } else { v = mManualBars[bar].Var; p = mManualBars[bar].Palette; id = mManualBars[bar].DataTypeId; } } // // Two functions used in saving/restoring the state and in creating new instances with // void iColorBars::PackStateBody(iString &s) const { this->PackValue(s,KeyColor(),mColor); this->PackValue(s,KeySideOffset(),this->GetSideOffset()); this->PackValue(s,KeySize(),this->GetSize()); this->PackValue(s,KeyAutomatic(),this->GetAutomatic()); int iv[3]; this->GetBar(0,iv[0],iv[1],iv[2]); iv[0]++; // vars start with 1 iv[2]++; this->PackValue(s,KeyBarRight(),iv,3); this->GetBar(1,iv[0],iv[1],iv[2]); iv[0]++; iv[2]++; this->PackValue(s,KeyBarLeft(),iv,3); } void iColorBars::UnPackStateBody(const iString &s) { int iv[3]; bool a; float f; iColor c; if(this->UnPackValue(s,KeyColor(),c)) this->SetColor(c); if(this->UnPackValue(s,KeySideOffset(),f)) this->SetSideOffset(f); if(this->UnPackValue(s,KeySize(),f)) this->SetSize(f); a = this->GetAutomatic(); this->UnPackValue(s,KeyAutomatic(),a); this->SetAutomatic(false); this->GetBar(0,iv[0],iv[1],iv[2]); iv[0]++; // vars start with 1 iv[2]++; if(this->UnPackValue(s,KeyBarRight(),iv,3)) this->SetBar(0,iv[0]-1,iv[1],iv[2]-1); this->GetBar(1,iv[0],iv[1],iv[2]); iv[0]++; // vars start with 1 iv[2]++; if(this->UnPackValue(s,KeyBarLeft(),iv,3)) this->SetBar(1,iv[0]-1,iv[1],iv[2]-1); this->SetAutomatic(a); } const iColorBarItem* iColorBars::GetItem(bool left) { int i = left ? 1 : 0; if(this->Queue().Size() > i) return &(this->Queue()[i]); else return 0; } vtkActor2D* iColorBars::GetActor(bool left) const { return mActors[left?1:0]; } bool iColorBarItem::operator<(const iColorBarItem &item) const { return Priority < item.Priority; } bool iColorBarItem::operator==(const iColorBarItem &item) const { return (Var==item.Var && DataTypeId==item.DataTypeId && Palette==item.Palette); } ifrit-3.4.2/core/icolorbars.h0000755000175700010010000000660012167404410014446 0ustar HomeNone/*========================================================================= Program: Ionization FRont Interactive Tool (IFRIT) Language: C++ Copyright (c) 2002-2012 Nick Gnedin All rights reserved. This file may be distributed and/or modified under the terms of the GNU General Public License version 2 as published by the Free Software Foundation and appearing in the file LICENSE.GPL included in the packaging of this file. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHORS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. =========================================================================*/ #ifndef ICOLORBARS_H #define ICOLORBARS_H #include "iobject.h" #include "iarray.h" class iColorBarActor; class iColorBarLabel; struct iColorBarItem; class iDataType; class iPalette; class vtkActor2D; namespace iParameter { namespace ColorBarsPriority { const int SurfaceExterior = 0; const int Volume = 1; const int CrossSection = 2; const int SurfaceInterior = 3; const int Field = 4; }; }; struct iColorBarItem { int Var; int Palette; int DataTypeId; int Priority; int Count; bool operator<(const iColorBarItem &item) const; bool operator==(const iColorBarItem &item) const; }; class iColorBars: public iObject { IPOINTER_AS_PART(ViewModule); public: vtkTypeMacro(iColorBars,iObject); static iColorBars* New(iViewModule *vm = 0); static const iObjectType& Type(); IOBJECT_DECLARE_GETSET1(Color,iColor); //virtual void SetColor(iColor c); //inline iColor GetColor() const { return mColor; } IOBJECT_DECLARE_GETSET2(SideOffset,float); //virtual void SetSideOffset(float v); //float GetSideOffset() const; IOBJECT_DECLARE_GETSET2(Size,float); //virtual void SetSize(float v); //float GetSize() const; IOBJECT_DECLARE_GETSET1(Automatic,bool); //virtual void SetAutomatic(bool); //inline bool GetAutomatic() const { return mAutomatic; } void SetBar(int bar, int v, int id, int p); void GetBar(int bar, int &v, int &id, int &p) const; static const iObjectKey& KeyBarLeft(); static const iObjectKey& KeyBarRight(); void ShowBar(int priority, int v, const iDataType &dt, int p, bool s); const iColorBarItem* GetItem(bool left); vtkActor2D* GetActor(bool left) const; protected: virtual ~iColorBars(); virtual void PackStateBody(iString &s) const; virtual void UnPackStateBody(const iString &s); private: iColorBars(iViewModule *vm); iOrderedArray& Queue(); bool mAutomatic; iColor mColor; iOrderedArray mAutomaticBars; iOrderedArray mManualBars; static const iColorBarItem NullItem; iColorBarActor *mActors[2]; }; inline iOrderedArray& iColorBars::Queue() { return mAutomatic ? mAutomaticBars : mManualBars; } #endif // ICOLORBARS_H ifrit-3.4.2/core/icommandinterpreter.cpp0000755000175700010010000001216412167404426016726 0ustar HomeNone/*========================================================================= Program: Ionization FRont Interactive Tool (IFRIT) Language: C++ Copyright (c) 2002-2012 Nick Gnedin All rights reserved. This file may be distributed and/or modified under the terms of the GNU General Public License version 2 as published by the Free Software Foundation and appearing in the file LICENSE.GPL included in the packaging of this file. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHORS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. =========================================================================*/ #include "icommandinterpreter.h" #include "icontrolmodule.h" #include "icontrolscript.h" #include "idirectory.h" #include "ifile.h" #include "ierrorstatus.h" #include "ishell.h" using namespace iParameter; iCommandInterpreter::iCommandInterpreter(iShell *s) : mShell(s), mErrorStatus("Command Interpreter") { mReturnState = 0; mExecuted = false; } iCommandInterpreter::~iCommandInterpreter() { } void iCommandInterpreter::Start() { this->DislayLineOfText("IFrIT Command Interpreter.",CommandInterpreterType::Result); this->DislayLineOfText("Type commands one per line.",CommandInterpreterType::Result); this->DislayLineOfText("Type 'help' for a list of available commands.",CommandInterpreterType::Result); this->Initialize(); } void iCommandInterpreter::Stop() { this->Finalize(); } void iCommandInterpreter::Append(const iString &text, char exec_char) { int i, n; bool exec = false; iString input, output, line; mExecuted = false; input = text; if(exec_char != 0) { int io = input.Length() - 1; while(io>=0 && input.IsWhiteSpace(io)) io--; if(io>=0 && input[io]==exec_char) { // // Remove the semi-colon // input.Replace(io,' '); exec = true; } } // // Clear the error status // mReturnState = 0; this->GetErrorStatus()->Clear(); n = input.Contains('\n'); for(i=0; iAnalyseSpecialCommands(line); // // Redirection sign reads from an external file // if(!line.IsEmpty() && line[0]=='<') { iString s = line.Part(1); s.ReduceWhiteSpace(); iDirectory::ExpandFileName(s,this->GetShell()->GetEnvironment(Environment::Base)); iFile F(s); if(F.Open(iFile::_Read,iFile::_Text)) { iString s; while(F.ReadLine(s)) if(!s.IsEmpty()) { this->DislayLineOfText("==> "+s,CommandInterpreterType::Code); output += s + "\n"; } F.Close(); } else { this->DislayLineOfText("File does not exist.",CommandInterpreterType::Error); mReturnState = -1; return; } line.Clear(); } // // Help, print, and list are executed at once // if(this->IsHelpRequest(line)) { this->RunScript(line); if(!this->GetErrorStatus()->Message().IsEmpty()) { this->DislayLineOfText("ERROR: "+this->GetErrorStatus()->Message(),CommandInterpreterType::Error); mReturnState = -1; return; } line.Clear(); } // // Form a script // if(!line.IsEmpty()) output += line + "\n"; } mBufferedScript += output; if(exec) this->Exec(); } void iCommandInterpreter::Exec() { // // Clear the error status // mReturnState = 0; this->GetErrorStatus()->Clear(); // // Execute the script // this->RunScript(mBufferedScript); if(this->GetErrorStatus()->NoError()) { mExecutedScript += mBufferedScript; mLastExecutedScriptPiece = mBufferedScript; } mBufferedScript.Clear(); mExecuted = true; } void iCommandInterpreter::RunScript(const iString &text, bool reset) { this->GetErrorStatus()->Monitor(this->Script()->GetErrorStatus()); this->Script()->SetText(text); this->Script()->Execute(!reset); // do not reset the script!!! if(this->GetErrorStatus()->IsError()) { this->DislayLineOfText("ERROR: "+this->GetErrorStatus()->Message(),CommandInterpreterType::Error); mReturnState = -1; } } iControlScript* iCommandInterpreter::Script() const { return this->GetShell()->GetControlModule()->GetControlScript(); } bool iCommandInterpreter::IsHelpRequest(const iString &line) const { return (line.Part(0,4)=="help" && (line.Length()==4 || line[4]==' ')) || line.Part(0,5)=="list " || // line.Part(0,6)=="print " || (line.Part(0,2)==".h" && (line.Length()==2 || line[2]==' ')) || line.Part(0,4)==".hp " || line.Part(0,4)==".ho " || // line.Part(0,3)==".p " || line.Part(0,4)==".lp " || (line.Part(0,3)==".lo" && (line.Length()==3 || line[3]==' ')); } ifrit-3.4.2/core/icommandinterpreter.h0000755000175700010010000000571312167404410016366 0ustar HomeNone/*========================================================================= Program: Ionization FRont Interactive Tool (IFRIT) Language: C++ Copyright (c) 2002-2012 Nick Gnedin All rights reserved. This file may be distributed and/or modified under the terms of the GNU General Public License version 2 as published by the Free Software Foundation and appearing in the file LICENSE.GPL included in the packaging of this file. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHORS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. =========================================================================*/ // // Base class for shell-specific interpreters for ControlScript // #ifndef ICOMMANDINTERPRETER_H #define ICOMMANDINTERPRETER_H #include #include "istring.h" #include "ipointermacro.h" #include class iControlScript; class iErrorStatus; class iShell; namespace iParameter { namespace CommandInterpreterType { // // CommandInterpreter parameters // const int Code = 0; const int Result = 1; const int Error = 2; }; }; class iCommandInterpreter : public vtkObjectBase { IPOINTER_AS_PART(Shell); IPOINTER_AS_USER(ErrorStatus); public: vtkTypeMacro(iCommandInterpreter,vtkObjectBase); void Start(); void Stop(); void Append(const iString &text, char exec_char = ';'); void Exec(); virtual void DislayLineOfText(const iString &text, int type) const = 0; inline bool IsExecuted() const { return mExecuted; } inline int GetReturnState() const { return mReturnState; } inline const iString& GetExecutedScript() const { return mExecutedScript; } inline const iString& GetLastExecutedScriptPiece() const { return mLastExecutedScriptPiece; } virtual iControlScript* Script() const; // just in case... (to allow script substitutions) protected: iCommandInterpreter(iShell *s); virtual ~iCommandInterpreter(); virtual bool IsHelpRequest(const iString &line) const; virtual void RunScript(const iString &text, bool reset = false); virtual void Initialize() = 0; virtual void AnalyseSpecialCommands(const iString &line) = 0; virtual void Finalize() = 0; private: // // Private, to make sure they are not changed accidentally // bool mExecuted; int mReturnState; iString mBufferedScript, mExecutedScript, mLastExecutedScriptPiece; }; #endif // ICOMMANDINTERPRETER_H ifrit-3.4.2/core/icommondatadistributors.cpp0000755000175700010010000002537712167404426017636 0ustar HomeNone/*========================================================================= Program: Ionization FRont Interactive Tool (IFRIT) Language: C++ Copyright (c) 2002-2012 Nick Gnedin All rights reserved. This file may be distributed and/or modified under the terms of the GNU General Public License version 2 as published by the Free Software Foundation and appearing in the file LICENSE.GPL included in the packaging of this file. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHORS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. =========================================================================*/ #include "icommondatadistributors.h" #include "iappendpolydatafilter.h" #include "ierror.h" #include "iparallelmanager.h" #include "ireplicatedpolydata.h" #include "iviewsubject.h" #include #include #include #include #include #include // // Templates // #include "iarraytemplate.h" // // Helper class // class iBasicDataDistributorHelper { public: template static bool CollectData(Collector *collector, iArray &localOutputs, vtkDataSet *globalOutput); static vtkDataArray* SplitArray(vtkDataArray *inArray, vtkIdType offset, vtkIdType size); }; template bool iBasicDataDistributorHelper::CollectData(Collector *collector, iArray &localOutputs, vtkDataSet *globalOutput) { IERROR_ASSERT(collector); // // Append the local data // if(localOutputs.Size() == 1) { globalOutput->ShallowCopy(localOutputs[0]); } else { int i; Type *tmpOutput, *lo; collector->RemoveAllInputs(); for(i=0; iShallowCopy(lo); collector->AddInput(tmpOutput); tmpOutput->Delete(); } collector->Update(); collector->RemoveAllInputs(); globalOutput->ShallowCopy(collector->GetOutput()); } return true; } vtkDataArray* iBasicDataDistributorHelper::SplitArray(vtkDataArray *inArray, vtkIdType offset, vtkIdType size) { if(inArray != 0) { vtkDataArray *outArray = inArray->NewInstance(); IERROR_ASSERT(outArray); int nc = inArray->GetNumberOfComponents(); outArray->SetNumberOfComponents(nc); outArray->SetVoidArray(inArray->GetVoidPointer(nc*offset),nc*size,1); return outArray; } else return 0; } // // Abstract field data distributor // iFieldDataDistributor::iFieldDataDistributor(iViewSubjectPipelineDataManager *manager, const iString &type) : iViewSubjectPipelineDataDistributor(manager,type) { mSplitDim = 2; } // // vtkImageData distributor // iImageDataDistributor::iImageDataDistributor(iViewSubjectPipelineDataManager *manager) : iFieldDataDistributor(manager,"vtkImageData") { } bool iImageDataDistributor::DistributeDataBody(vtkDataSet *globalInput, iArray &localInputs) { // // Default implementation: split the data in uniform chunks along the last non-trivial dimensions // vtkImageData *input = vtkImageData::SafeDownCast(globalInput); if(input == 0) return false; int nproc = localInputs.Size(); // // Read input structure and choose the split direction // int i, dims[3], dimsPiece[3]; double org[3], orgPiece[3], spa[3]; input->GetOrigin(org); input->GetSpacing(spa); input->GetDimensions(dims); int mSplitDim = 2; while(mSplitDim>=0 && dims[mSplitDim]<=1) mSplitDim--; if(mSplitDim < 0) { // // Nothing to split // for(i=1; iNewInstance(); IERROR_ASSERT(localInputs[i]); } nproc = 1; mSplitDim = 2; } // // Adjust the number of processors // if(dims[mSplitDim]>0 && nproc>dims[mSplitDim]) { for(i=nproc; iNewInstance(); IERROR_ASSERT(localInputs[i]); } nproc = dims[mSplitDim]; } if(nproc == 1) { // // Nothing to do for 1 proc // localInputs[0] = globalInput->NewInstance(); IERROR_ASSERT(localInputs[0]); localInputs[0]->ShallowCopy(input); localInputs[0]->SetUpdateExtentToWholeExtent(); // not set by ShallowCopy in VTK 5 return true; } mEdges.Resize(nproc-1); // // Split the data between processors // int kstp, kbeg, kend; kstp = (dims[mSplitDim]+nproc-2)/nproc; // This is point data, hence -2 rather than -1 in kstp for(i=0; i<3; i++) { dimsPiece[i] = dims[i]; orgPiece[i] = org[i]; } vtkIdType dataOffset = 1, dataSize; for(i=0; iNewInstance()); IERROR_ASSERT(li); localInputs[i] = li; li->CopyStructure(input); // a better way of setting all parameters li->SetDimensions(dimsPiece); li->SetOrigin(orgPiece); // // We also need to set properties that are not set by default // li->SetWholeExtent(li->GetExtent()); li->SetUpdateExtentToWholeExtent(); array = iBasicDataDistributorHelper::SplitArray(input->GetPointData()->GetScalars(),dataOffset*kbeg,dataSize); if(array != 0) { li->GetPointData()->SetScalars(array); array->Delete(); } array = iBasicDataDistributorHelper::SplitArray(input->GetPointData()->GetVectors(),dataOffset*kbeg,dataSize); if(array != 0) { li->GetPointData()->SetVectors(array); array->Delete(); } array = iBasicDataDistributorHelper::SplitArray(input->GetPointData()->GetTensors(),dataOffset*kbeg,dataSize); if(array != 0) { li->GetPointData()->SetTensors(array); array->Delete(); } } return true; } // // vtkImageData collector // iImageDataCollector::iImageDataCollector(iViewSubjectPipelineDataManager *manager) : iViewSubjectPipelineDataCollector(manager,"vtkImageData") { mCollector = vtkImageAppend::New(); IERROR_ASSERT(mCollector); } iImageDataCollector::~iImageDataCollector() { mCollector->Delete(); } bool iImageDataCollector::CollectDataBody(iArray &localOutputs, vtkDataSet *globalOutput) { mCollector->SetNumberOfThreads(localOutputs.Size()); return iBasicDataDistributorHelper::CollectData(mCollector,localOutputs,globalOutput); } // // vtkPolyData distributor // iPolyDataDistributor::iPolyDataDistributor(iViewSubjectPipelineDataManager *manager) : iViewSubjectPipelineDataDistributor(manager,"vtkPolyData") { } bool iPolyDataDistributor::DistributeDataBody(vtkDataSet *globalInput, iArray &localInputs) { int i; // // Default implementation: split the data in uniform chunks by the particle index. // Only split Vert data, assign Line, Poly, and Strip data to the master thread // vtkPolyData *input = vtkPolyData::SafeDownCast(globalInput); if(input == 0) return false; int nPieces = localInputs.Size(); vtkIdType nParticles = input->GetNumberOfPoints(); if(nPieces > nParticles) nPieces = nParticles; if(nPieces < 1) nPieces = 1; vtkIdType kbeg, kstp = (nParticles+nPieces-1)/nPieces; vtkIdType *inPtr = input->GetVerts()->GetData()->GetPointer(0); if(inPtr == 0) { // // We have no vertices - do not split. // for(i=0; iShallowCopy(input); return true; } vtkCellArray *tmpCells; vtkIdTypeArray *tmpData; vtkPolyData *li; for(i=0; iInitialize(); li->ShallowCopy(input); if(i > 0) { li->SetVerts(0); li->SetLines(0); li->SetPolys(0); li->SetStrips(0); } tmpCells = vtkCellArray::New(); if(tmpCells != 0) { tmpData = vtkIdTypeArray::New(); if(tmpData != 0) { tmpData->SetArray(inPtr+2*kbeg,2*kstp,1); tmpCells->SetCells(kstp,tmpData); li->SetVerts(tmpCells); tmpData->Delete(); } tmpCells->Delete(); } } for(i=nPieces; iGetViewSubject()); IERROR_ASSERT(mCollector); } iPolyDataCollector::~iPolyDataCollector() { mCollector->Delete(); } bool iPolyDataCollector::CollectDataBody(iArray &localOutputs, vtkDataSet *globalOutput) { if(!iBasicDataDistributorHelper::CollectData(mCollector,localOutputs,globalOutput)) return false; if(mDistributor==0 || !mFixStiches) return true; #ifdef I_DEBUG if(iParallelManager::DebugSwitch == 4) return true; #endif // // Remove edges // int splitDim = mDistributor->GetSplitDimension(); const iArray &innerEdges(mDistributor->GetEdges()); int extDown = 0; int next = 1; if(mManager->GetViewSubject()!=0 && mManager->GetViewSubject()->GetDataReplicated()!=0) { extDown = mManager->GetViewSubject()->GetDataReplicated()->GetNumReplicas(2*splitDim); next += mManager->GetViewSubject()->GetDataReplicated()->GetNumReplicas(2*splitDim+1) + extDown; } int i, j, numEdges = innerEdges.Size(); if(numEdges > 0) { int ntot = numEdges*next; double *allEdges = new double[ntot]; IERROR_ASSERT(allEdges); for(j=0; j class iAppendPolyDataFilter; class vtkImageAppend; class iFieldDataDistributor : public iViewSubjectPipelineDataDistributor { public: vtkTypeMacro(iFieldDataDistributor,iViewSubjectPipelineDataDistributor); iFieldDataDistributor(iViewSubjectPipelineDataManager *manager, const iString &type); inline int GetSplitDimension() const { return mSplitDim; } inline const iArray& GetEdges() const { return mEdges; } protected: int mSplitDim; iArray mEdges; }; class iImageDataDistributor : public iFieldDataDistributor { public: vtkTypeMacro(iImageDataDistributor,iFieldDataDistributor); iImageDataDistributor(iViewSubjectPipelineDataManager *manager); protected: virtual bool DistributeDataBody(vtkDataSet *globalInput, iArray &localInputs); }; class iImageDataCollector : public iViewSubjectPipelineDataCollector { public: vtkTypeMacro(iImageDataCollector,iViewSubjectPipelineDataCollector); iImageDataCollector(iViewSubjectPipelineDataManager *manager); protected: virtual ~iImageDataCollector(); virtual bool CollectDataBody(iArray &localOutputs, vtkDataSet *globalOutput); vtkImageAppend *mCollector; }; class iPolyDataDistributor : public iViewSubjectPipelineDataDistributor { public: vtkTypeMacro(iPolyDataDistributor,iViewSubjectPipelineDataDistributor); iPolyDataDistributor(iViewSubjectPipelineDataManager *manager); protected: virtual bool DistributeDataBody(vtkDataSet *globalInput, iArray &localInputs); }; class iPolyDataCollector : public iViewSubjectPipelineDataCollector { public: vtkTypeMacro(iPolyDataCollector,iViewSubjectPipelineDataCollector); iPolyDataCollector(iViewSubjectPipelineDataManager *manager, iFieldDataDistributor *distributor = 0); void FixStiches(bool s){ mFixStiches = s; } protected: virtual ~iPolyDataCollector(); virtual bool CollectDataBody(iArray &localOutputs, vtkDataSet *globalOutput); bool mFixStiches; iFieldDataDistributor *mDistributor; iAppendPolyDataFilter *mCollector; }; #endif // ICOMMONDATADISTRIBUTORS_H ifrit-3.4.2/core/icommoneventobservers.cpp0000755000175700010010000002224512167404426017312 0ustar HomeNone/*========================================================================= Program: Ionization FRont Interactive Tool (IFRIT) Language: C++ Copyright (c) 2002-2012 Nick Gnedin All rights reserved. This file may be distributed and/or modified under the terms of the GNU General Public License version 2 as published by the Free Software Foundation and appearing in the file LICENSE.GPL included in the packaging of this file. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHORS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. =========================================================================*/ #include "icommoneventobservers.h" #include "icontrolmodule.h" #include "idatareader.h" #include "ierror.h" #include "imarker.h" #include "imarkerfamily.h" #include "iparallel.h" #include "ipicker.h" #include "iscript.h" #include "ishellfactory.h" #include "iviewmodule.h" #include "iviewobjectfamily.h" #include #include #include #include // // Templates // #include "iarraytemplate.h" bool iAbortRenderEventObserver::mTheseAreBlocked = false; // // iProgressEventObserver class // iProgressEventObserver* iProgressEventObserver::New(iViewModule *vm) { IERROR_ASSERT(vm); return iRequiredCast(INFO,iShellFactory::CreateEventObserver("Progress",vm)); } iProgressEventObserver::iProgressEventObserver(iViewModule *vm) : iEventObserver(vm->GetControlModule()->GetShell()), mViewModule(vm) { mAborted = false; mMode = _Default; mScript = 0; mProgressValue = 0.0; } void iProgressEventObserver::AttachScript(iScript *s) { mScript = s; } void iProgressEventObserver::ExecuteBody(vtkObject *, unsigned long event, void *data) { switch(event) { case vtkCommand::StartEvent: { this->Started(mMode); break; } case vtkCommand::ProgressEvent: { float f; if(data == 0) f = 0.0; else f = static_cast(data)[0]; this->SetProgress(f); break; } case vtkCommand::EndEvent: { mScript = 0; this->Finished(); break; } } } void iProgressEventObserver::Started(ProgressMode m) { mMode = m; mAborted = false; mProgressValue = 0.0; this->ChildStarted(); } void iProgressEventObserver::SetProgress(float f) { mAborted = this->CheckAbort(); if(mScript!=0 && mScript->CheckAbort()) mAborted = true; if(!mAborted && f>mProgressValue+0.0009) { mProgressValue = f; this->SetProgressBody(f); } } void iProgressEventObserver::Finished() { this->ChildFinished(); } void iProgressEventObserver::SetMode(ProgressMode m) { mMode = m; } const char* iProgressEventObserver::GetLabel() const { switch(mMode) { case _Reading: { return "Reading..."; } case _Projecting: { return "Projecting..."; } case _Rendering: { return "Rendering..."; } case _Writing: { return "Writing..."; } case _Operating: { return "Operating..."; } case _Formatting: { return "Formatting..."; } case _Shifting: { return "Shifting..."; } case _Computing: { return "Computing..."; } default: { return ""; } } } // // iAbortRenderEventObserver class // iAbortRenderEventObserver* iAbortRenderEventObserver::New(iViewModule *vm) { IERROR_ASSERT(vm); return iRequiredCast(INFO,iShellFactory::CreateEventObserver("AbortRender",vm)); } iAbortRenderEventObserver::iAbortRenderEventObserver(iViewModule *vm) : iEventObserver(vm->GetControlModule()->GetShell()), mViewModule(vm) { mCancelled = mInProgress = false; mRenderTimer = vtkTimerLog::New(); IERROR_ASSERT(mRenderTimer); mRenderTime = 0.0f; mInteractive = true; } iAbortRenderEventObserver::~iAbortRenderEventObserver() { mRenderTimer->Delete(); } void iAbortRenderEventObserver::ExecuteBody(vtkObject *caller, unsigned long event, void *) { if(mTheseAreBlocked) return; switch(event) { case vtkCommand::StartEvent: { if(!mInProgress) { mInProgress = true; this->Started(); mCancelled = false; mRenderTimer->StartTimer(); } break; } case vtkCommand::AbortCheckEvent: case vtkCommand::ProgressEvent: { if(mInProgress) { mCancelled = this->CheckAbort(); if(mCancelled) { vtkRenderWindow *rw = vtkRenderWindow::SafeDownCast(caller); if(rw != 0) rw->SetAbortRender(1); vtkProcessObject *po = vtkProcessObject::SafeDownCast(caller); if(po != 0) po->SetAbortExecute(1); } } break; } case vtkCommand::EndEvent: { if(mInProgress) { mRenderTimer->StopTimer(); mRenderTime = mRenderTimer->GetElapsedTime(); mInProgress = false; this->Finished(); if(mCancelled) { // // If rendering was cancelled, then different parts of the pipeline // remain in different stages of completion, which confuses VTK. // To avoid that we modify the time stamp of the data, so that next // rendering starts from scratch. It is not an elegant solution, // but it works. // this->GetViewModule()->GetReader()->ResetPipeline(); } } break; } case vtkCommand::UserEvent: { this->PostFinished(); break; } } } // // iSlaveAbortRenderEventObserver class // iSlaveAbortRenderEventObserver* iSlaveAbortRenderEventObserver::New(iAbortRenderEventObserver *master) { IERROR_ASSERT(master); return new iSlaveAbortRenderEventObserver(master); } iSlaveAbortRenderEventObserver::iSlaveAbortRenderEventObserver(iAbortRenderEventObserver *m) : iEventObserver(m->GetViewModule()->GetControlModule()->GetShell()), mViewModule(m->GetViewModule()) { mMaster = m; mMaster->Register(this); } iSlaveAbortRenderEventObserver::~iSlaveAbortRenderEventObserver() { mMaster->UnRegister(); } void iSlaveAbortRenderEventObserver::ExecuteBody(vtkObject *caller, unsigned long event, void *) { if(mMaster->AbortRenderEventObserversBlocked()) return; switch(event) { case vtkCommand::AbortCheckEvent: case vtkCommand::ProgressEvent: { if(mMaster!=0 && mMaster->IsCancelled()) { vtkProcessObject *po = vtkProcessObject::SafeDownCast(caller); if(po != 0) po->SetAbortExecute(1); } break; } } } // // iPickEventObserver class // iPickEventObserver* iPickEventObserver::New(iViewModule *vm) { IERROR_ASSERT(vm); return iRequiredCast(INFO,iShellFactory::CreateEventObserver("Pick",vm)); } iPickEventObserver::iPickEventObserver(iViewModule *vm) : iEventObserver(vm->GetControlModule()->GetShell()), mViewModule(vm) { } void iPickEventObserver::ExecuteBody(vtkObject *caller, unsigned long eventId, void *) { switch (eventId) { case vtkCommand::StartPickEvent: { this->Started(); break; } case vtkCommand::EndPickEvent: { this->Finished(); break; } } } // // iParallelUpdateEventObserver class // iParallelUpdateEventObserver* iParallelUpdateEventObserver::New(iControlModule *cm) { IERROR_ASSERT(cm); return iRequiredCast(INFO,iShellFactory::CreateEventObserver("ParallelUpdate",cm)); } iParallelUpdateEventObserver::iParallelUpdateEventObserver(iControlModule *cm) : iEventObserver(cm->GetShell()), mControlModule(cm) { } void iParallelUpdateEventObserver::ExecuteBody(vtkObject *, unsigned long eventId, void *) { if(eventId == iParallel::InformationEvent) this->UpdateInformation(); } // // iAnimatorEventObserver class // iAnimatorEventObserver* iAnimatorEventObserver::New(iViewModule *vm) { IERROR_ASSERT(vm); return iRequiredCast(INFO,iShellFactory::CreateEventObserver("Animator",vm)); } iAnimatorEventObserver::iAnimatorEventObserver(iViewModule *vm) : iEventObserver(vm->GetControlModule()->GetShell()), mViewModule(vm) { } void iAnimatorEventObserver::ExecuteBody(vtkObject *, unsigned long eventId, void *) { if(eventId == 0UL) this->OnCameraPath(0); } // // iMarkerEventObserver class // iMarkerEventObserver* iMarkerEventObserver::New(iViewModule *vm) { IERROR_ASSERT(vm); return new iMarkerEventObserver(vm); } iMarkerEventObserver::iMarkerEventObserver(iViewModule *vm) : iEventObserver(vm->GetControlModule()->GetShell()), mViewModule(vm) { } void iMarkerEventObserver::ExecuteBody(vtkObject *caller, unsigned long eventId, void *) { vtkPointWidget *pw = vtkPointWidget::SafeDownCast(caller); if(pw == 0) return; switch (eventId) { case vtkCommand::InteractionEvent: { double *x = pw->GetPosition(); iPosition p(this->GetViewModule()); p = x; this->GetViewModule()->GetMarkerFamily()->GetCurrentMember()->Move(p); break; } case vtkCommand::EndInteractionEvent: { this->GetViewModule()->GetMarkerFamily()->GetCurrentMember()->FinishMoving(); } } } ifrit-3.4.2/core/icommoneventobservers.h0000755000175700010010000001330212167404410016742 0ustar HomeNone/*========================================================================= Program: Ionization FRont Interactive Tool (IFRIT) Language: C++ Copyright (c) 2002-2012 Nick Gnedin All rights reserved. This file may be distributed and/or modified under the terms of the GNU General Public License version 2 as published by the Free Software Foundation and appearing in the file LICENSE.GPL included in the packaging of this file. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHORS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. =========================================================================*/ // // Commonly used observers // #ifndef ICOMMONEVENTOBSERVERS_H #define ICOMMONEVENTOBSERVERS_H #include "ieventobserver.h" class iControlModule; class iScript; class iViewModule; class vtkProcessObject; class vtkTimerLog; class iProgressEventObserver : public iEventObserver { IPOINTER_AS_PART(ViewModule); public: enum ProgressMode { _Default = 0, _Reading = 1, _Projecting = 2, _Rendering = 3, _Writing = 4, _Operating = 5, _Formatting = 6, _Shifting = 7, _Computing = 8 }; vtkTypeMacro(iProgressEventObserver,iEventObserver); static iProgressEventObserver* New(iViewModule *vm = 0); // // Public for manual driving // virtual void Started(ProgressMode mode); virtual void SetProgress(float fraction); virtual void Finished(); void AttachScript(iScript *s); void SetMode(ProgressMode m); inline int GetMode() const { return mMode; } const char* GetLabel() const; inline bool IsAborted() const { return mAborted; } protected: iProgressEventObserver(iViewModule *vm); virtual void ExecuteBody(vtkObject *caller, unsigned long event, void *data); virtual void ChildStarted() = 0; virtual void ChildFinished() = 0; virtual bool CheckAbort() = 0; virtual void SetProgressBody(float fraction) = 0; private: iScript *mScript; ProgressMode mMode; bool mAborted; float mProgressValue; }; class iAbortRenderEventObserver : public iEventObserver { IPOINTER_AS_PART(ViewModule); public: vtkTypeMacro(iAbortRenderEventObserver,iEventObserver); static iAbortRenderEventObserver* New(iViewModule *vm = 0); inline bool IsCancelled() const { return mCancelled; } inline float GetRenderTime() const { return mRenderTime; } void SetInteractive(bool s){ mInteractive = s; } bool IsInteractive() const { return mInteractive; } static void BlockAbortRenderEventObservers(bool s) { mTheseAreBlocked = s; } static bool AbortRenderEventObserversBlocked(){ return mTheseAreBlocked; } virtual void PostFinished() = 0; // can be manually driven protected: iAbortRenderEventObserver(iViewModule *vm); ~iAbortRenderEventObserver(); vtkTimerLog* Timer() const { return mRenderTimer; } virtual void ExecuteBody(vtkObject *caller, unsigned long event, void *data); virtual void Started() = 0; virtual void Finished() = 0; virtual bool CheckAbort() = 0; private: vtkTimerLog *mRenderTimer; float mRenderTime; static bool mTheseAreBlocked; bool mCancelled, mInProgress, mInteractive; }; class iSlaveAbortRenderEventObserver : public iEventObserver { IPOINTER_AS_PART(ViewModule); public: vtkTypeMacro(iSlaveAbortRenderEventObserver,iEventObserver); static iSlaveAbortRenderEventObserver* New(iAbortRenderEventObserver *m = 0); protected: iSlaveAbortRenderEventObserver(iAbortRenderEventObserver *m); virtual ~iSlaveAbortRenderEventObserver(); virtual void ExecuteBody(vtkObject *caller, unsigned long event, void *data); private: iAbortRenderEventObserver *mMaster; }; class iPickEventObserver : public iEventObserver { IPOINTER_AS_PART(ViewModule); public: vtkTypeMacro(iPickEventObserver,iEventObserver); static iPickEventObserver* New(iViewModule *vm = 0); protected: iPickEventObserver(iViewModule *vm); virtual void ExecuteBody(vtkObject *caller, unsigned long event, void *data); virtual void Started() = 0; virtual void Finished() = 0; }; class iParallelUpdateEventObserver : public iEventObserver { IPOINTER_AS_PART(ControlModule); public: vtkTypeMacro(iParallelUpdateEventObserver,iEventObserver); static iParallelUpdateEventObserver* New(iControlModule *cm = 0); virtual void UpdateInformation() = 0; protected: iParallelUpdateEventObserver(iControlModule *cm); virtual void ExecuteBody(vtkObject *caller, unsigned long event, void *data); }; class iAnimatorEventObserver : public iEventObserver { IPOINTER_AS_PART(ViewModule); public: vtkTypeMacro(iAnimatorEventObserver,iEventObserver); static iAnimatorEventObserver* New(iViewModule *vm = 0); virtual void OnCameraPath(int step) = 0; protected: iAnimatorEventObserver(iViewModule *vm); virtual void ExecuteBody(vtkObject *caller, unsigned long event, void *data); }; class iMarkerEventObserver : public iEventObserver { IPOINTER_AS_PART(ViewModule); public: vtkTypeMacro(iMarkerEventObserver,iEventObserver); static iMarkerEventObserver* New(iViewModule *vm = 0); protected: iMarkerEventObserver(iViewModule *vm); virtual void ExecuteBody(vtkObject *caller, unsigned long event, void *data); }; #endif // ICOMMONEVENTOBSERVERS_H ifrit-3.4.2/core/iconsole.cpp0000755000175700010010000000402312167404426014461 0ustar HomeNone/*========================================================================= Program: Ionization FRont Interactive Tool (IFRIT) Language: C++ Copyright (c) 2002-2012 Nick Gnedin All rights reserved. This file may be distributed and/or modified under the terms of the GNU General Public License version 2 as published by the Free Software Foundation and appearing in the file LICENSE.GPL included in the packaging of this file. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHORS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. =========================================================================*/ #include "iconsole.h" #include "ioutputchannel.h" #include "istring.h" #include #ifdef _WIN32 #include #endif void iConsole::Display(MessageType type, const iString &message, const char *file, int line) { iOutputChannel::GetInstance()->Display(type,message,file,line); } void iConsole::Display(MessageType type, const char *message, const char *file, int line) { iOutputChannel::GetInstance()->Display(type,iString(message),file,line); } // // Debugging helpers // #ifdef I_DEBUG void iConsole::PrintDebugMessage(const iString &message) { static int count = 0; iString text = iString::FromNumber(++count,"%6d: ") + message + "\n"; #ifdef _WIN32 OutputDebugString(text.ToCharPointer()); #else cout << text.ToCharPointer(); cout.flush(); #endif } #endif ifrit-3.4.2/core/iconsole.h0000755000175700010010000000357612167404410014133 0ustar HomeNone/*========================================================================= Program: Ionization FRont Interactive Tool (IFRIT) Language: C++ Copyright (c) 2002-2012 Nick Gnedin All rights reserved. This file may be distributed and/or modified under the terms of the GNU General Public License version 2 as published by the Free Software Foundation and appearing in the file LICENSE.GPL included in the packaging of this file. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHORS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. =========================================================================*/ // // This class encapsulates some of the console functions // #ifndef ICONSOLE_H #define ICONSOLE_H class iString; class iConsole { public: enum MessageType { _Info, _Warning, _LowError, _HighError, _FatalError, _Notification }; // // Use this function to report errors and display text // static void Display(MessageType type, const iString &message, const char *file = 0, int line = 0); static void Display(MessageType type, const char *message, const char *file = 0, int line = 0); // // Debugging helper // #ifdef I_DEBUG static void PrintDebugMessage(const iString &message); #endif }; #endif // ICONSOLE_H ifrit-3.4.2/core/icontourfilter.cpp0000755000175700010010000001174712167404426015731 0ustar HomeNone/*========================================================================= Program: Ionization FRont Interactive Tool (IFRIT) Language: C++ Copyright (c) 2002-2012 Nick Gnedin All rights reserved. This file may be distributed and/or modified under the terms of the GNU General Public License version 2 as published by the Free Software Foundation and appearing in the file LICENSE.GPL included in the packaging of this file. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHORS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. =========================================================================*/ #include "icontourfilter.h" #include #include #include #include #include #include // // Templates // #include "igenericfiltertemplate.h" iContourFilter::iContourFilter(iViewSubject *vo) : iGenericFilter(vo,1,true,false) { mMethod = 0; mCurVar = 0; vtkContourFilter *w0 = vtkContourFilter::New(); IERROR_ASSERT(w0); w0->UseScalarTreeOn(); w0->ComputeNormalsOn(); w0->ComputeScalarsOff(); w0->ComputeGradientsOff(); if(vo->IsCreatingMainPipeline()) { w0->AddObserver(vtkCommand::ProgressEvent,vo->GetViewModule()->GetAbortRenderEventObserver()); } else { w0->AddObserver(vtkCommand::ProgressEvent,vo->GetViewModule()->GetSlaveAbortRenderEventObserver()); } vtkMarchingContourFilter *w1 = vtkMarchingContourFilter::New(); IERROR_ASSERT(w1); w1->UseScalarTreeOn(); w1->ComputeNormalsOn(); w1->ComputeScalarsOff(); w1->ComputeGradientsOff(); if(vo->IsCreatingMainPipeline()) { w1->AddObserver(vtkCommand::ProgressEvent,vo->GetViewModule()->GetAbortRenderEventObserver()); } else { w1->AddObserver(vtkCommand::ProgressEvent,vo->GetViewModule()->GetSlaveAbortRenderEventObserver()); } mWorkers[0] = w0; mWorkers[1] = w1; } iContourFilter::~iContourFilter() { mWorkers[0]->Delete(); mWorkers[1]->Delete(); } void iContourFilter::SetMethod(int n) { if(n>=0 && n<2 && n!=mMethod) { mWorkers[mMethod]->GetOutput()->Initialize(); // erase old data mMethod = n; this->Modified(); } } void iContourFilter::SetCurrentVar(int n) { if(n>=0 && n!=mCurVar) { mCurVar = n; this->Modified(); } } float iContourFilter::GetLevel() const { return iRequiredCast(INFO,mWorkers[0])->GetValue(0); } void iContourFilter::SetLevel(float v) { iRequiredCast(INFO,mWorkers[0])->SetValue(0,v); iRequiredCast(INFO,mWorkers[1])->SetValue(0,v); this->Modified(); } void iContourFilter::ProduceOutput() { vtkDataSet *input = this->GetInput(); vtkPolyData *output = this->GetOutput(); // // VTK contouring filters always make the isosurface of the first component. We simple shift the data by mCurVar values // so that the current value is always the 0 component. // int numComp; if(input->GetPointData()==0 || input->GetPointData()->GetScalars()==0 || (numComp=input->GetPointData()->GetScalars()->GetNumberOfComponents())<1 || mCurVar<0 || mCurVar>=numComp) { output->Initialize(); return; } vtkDataSet *newInput = input->NewInstance(); IERROR_ASSERT(newInput); newInput->ShallowCopy(input); vtkFloatArray *scalars = iRequiredCast(INFO,input->GetPointData()->GetScalars()); vtkFloatArray *newScalars = vtkFloatArray::New(); IERROR_ASSERT(newScalars); newScalars->SetNumberOfComponents(numComp); newScalars->SetArray(scalars->GetPointer(mCurVar),scalars->GetSize(),1); newInput->GetPointData()->SetScalars(newScalars); newScalars->Delete(); mWorkers[mMethod]->SetInput(newInput); newInput->Delete(); mWorkers[mMethod]->Update(); // // Are there normals? Not all combinations of inputs/filters/VTK versions create those // if(mWorkers[mMethod]->GetOutput()->GetPointData()->GetNormals()==0 || mWorkers[mMethod]->GetOutput()->GetPointData()->GetNormals()->GetNumberOfTuples()==0) { vtkPolyDataNormals *nf = vtkPolyDataNormals::New(); IERROR_ASSERT(nf); nf->ConsistencyOn(); nf->ComputePointNormalsOn(); nf->ComputeCellNormalsOff(); nf->SetInput(mWorkers[mMethod]->GetOutput()); nf->Update(); mWorkers[mMethod]->GetOutput()->GetPointData()->SetNormals(nf->GetOutput()->GetPointData()->GetNormals()); nf->Delete(); } output->ShallowCopy(mWorkers[mMethod]->GetOutput()); } ifrit-3.4.2/core/icontourfilter.h0000644000175700010010000000367312167404410015363 0ustar HomeNone/*========================================================================= Program: Ionization FRont Interactive Tool (IFRIT) Language: C++ Copyright (c) 2002-2012 Nick Gnedin All rights reserved. This file may be distributed and/or modified under the terms of the GNU General Public License version 2 as published by the Free Software Foundation and appearing in the file LICENSE.GPL included in the packaging of this file. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHORS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. =========================================================================*/ #ifndef ICONTOURFILTER_H #define ICONTOURFILTER_H #include "igenericfilter.h" #include class vtkPolyDataAlgorithm; class iContourFilter : public iGenericFilter { IGENERICFILTER_DECLARE(iContourFilter,vtkDataSetToPolyDataFilter); public: inline int GetMethod() const { return mCurVar; } void SetMethod(int n); inline int GetCurrentVar() const { return mCurVar; } void SetCurrentVar(int n); float GetLevel() const; void SetLevel(float); protected: virtual ~iContourFilter(); virtual void ProduceOutput(); private: int mCurVar, mMethod; vtkPolyDataAlgorithm *mWorkers[2]; }; #endif // ICONTOURFILTER_H ifrit-3.4.2/core/icontrolmodule.cpp0000755000175700010010000012303012167404426015705 0ustar HomeNone/*========================================================================= Program: Ionization FRont Interactive Tool (IFRIT) Language: C++ Copyright (c) 2002-2012 Nick Gnedin All rights reserved. This file may be distributed and/or modified under the terms of the GNU General Public License version 2 as published by the Free Software Foundation and appearing in the file LICENSE.GPL included in the packaging of this file. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHORS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. =========================================================================*/ #include "icontrolmodule.h" #include "ianimator.h" #include "icamera.h" #include "icolorbars.h" #include "icommoneventobservers.h" #include "icontrolscript.h" #include "icrosssectionviewsubject.h" #include "idata.h" #include "idatareader.h" #include "idatasubject.h" #include "ierror.h" #include "ieventobserver.h" #include "ierrorstatus.h" #include "iextensionfactory.h" #include "ifile.h" #include "iimagecomposer.h" #include "imarker.h" #include "imarkerfamily.h" #include "ipaletteset.h" #include "iparallel.h" #include "iparallelmanager.h" #include "iparticlegroup.h" #include "iparticlesviewsubject.h" #include "ipicker.h" #include "ipiecewisefunction.h" #include "irendertool.h" #include "ishell.h" #include "isurfaceviewsubject.h" #include "itensorfieldviewsubject.h" #include "ivectorfieldviewsubject.h" #include "iviewmodule.h" #include "iviewobject.h" #include "iviewobjectfamily.h" #include "ivolumeviewsubject.h" #include #include #include #include #include #include #include // // templates // #include "iarraytemplate.h" #include "iviewfamilytemplate.h" using namespace iParameter; int iControlModule::mIdCounter = 0; IOBJECT_DEFINE_TYPE(iControlModule,ControlModule,cm,iObjectType::_Module); IOBJECT_DEFINE_KEY(iControlModule,AutoRender,ar,Bool,1); IOBJECT_DEFINE_KEY(iControlModule,OptimizationMode,om,Int,1); IOBJECT_DEFINE_KEY(iControlModule,SynchronizeCameras,sc,Bool,1); IOBJECT_DEFINE_KEY(iControlModule,SynchronizeInteractors,si,Bool,1); #define BACKWARD_COMPATIBLE #define COMPATIBILITY_MODE 12 // // Helper functions hidden in a private namespace // namespace iControlModule_Private { template bool SetCurrentObject(Family *fam, int obj) { if(obj>=0 && obj<=fam->GetMaxMemberIndex()) { fam->SetCurrentMemberIndex(obj); return true; } else return false; } template void ExecuteForObject(Family *fam, const iString &command, int objOption, bool &executeOk) { switch(objOption) { case ObjectOption::One: { fam->GetCurrentMember()->UnPackState(command); executeOk = fam->GetCurrentMember()->UnPackedSomething(); break; } case ObjectOption::All: { int j; for(j=0; j<=fam->GetMaxMemberIndex(); j++) { fam->GetMember(j)->UnPackState(command); executeOk = executeOk || fam->GetMember(j)->UnPackedSomething(); } break; } } } template bool CreateObject(Family *fam, iViewModule *module) { int i = fam->CreateMember(); if(i == -1) return false; fam->GetMember(i)->CopyState(fam->GetCurrentMember()); fam->Show(fam->IsVisible()); fam->SetCurrentMemberIndex(i); module->ClearCache(); return true; } template bool DeleteObject(Family *fam, iViewModule *module, int obj) { if(obj == -1) obj = fam->GetCurrentMemberIndex(); if(!fam->DeleteMember(obj)) return false; module->ClearCache(); return true; } template bool SaveObject(Family *fam, const iObjectType &type, iFile &F, const iString &prefix, int k) { int i; iString ws, state; for(i=0; i<=fam->GetMaxMemberIndex(); i++) { ws = prefix + type.FullName() + " " + iString::FromNumber(k) + " " + iString::FromNumber(i) + " "; fam->GetMember(i)->PackCompleteState(state); ws += state; if(!F.WriteLine(ws)) return false; } return true; } bool Error(iFile &F) { F.Close(); return false; } bool OnQueryFailed() { #ifdef I_DEBUG int ooo = 0; #endif return false; } }; using namespace iControlModule_Private; // // #define LOAD_OBJECT(_getfam_,_type_,_show_) \ if(ws == _type_.FullName()) \ { \ k = line.Section(" ",1,1).ToInt(ok); \ if(!ok) return Error(F); \ if(k>=0 && kGetMember(k); \ i = line.Section(" ",2,2).ToInt(ok); \ if(!ok) return Error(F); \ while(i > vm->_getfam_->GetMaxMemberIndex()) if(vm->_getfam_->CreateMember()==-1) return Error(F); \ vm->_getfam_->GetMember(i)->UnPackCompleteState(line.Section(" ",3)); \ this->GetShell()->OnInitAtom(); \ if(_show_) \ { \ vm->_getfam_->Show(_show_); \ this->GetShell()->OnLoadStateFileAtom(60+(20*(kk+1)/nvm)); \ k++; \ } \ } \ } // // Helper class. Probably should not be here. // class iInteractorEventObserver : public iEventObserver { IPOINTER_AS_PART(ControlModule); public: vtkTypeMacro(iInteractorEventObserver,iEventObserver); static iInteractorEventObserver* New(iControlModule *cm = 0) { IERROR_ASSERT(cm); return new iInteractorEventObserver(cm); } void Activate(bool s) { mActive = s; } protected: iInteractorEventObserver(iControlModule *cm) : iEventObserver(cm->GetShell()), mControlModule(cm) { mInUpdate = mActive = false; } virtual void ExecuteBody(vtkObject *caller, unsigned long event1, void *callData) { if(!mActive || mInUpdate) return; vtkRenderWindowInteractor *iren, *driver = vtkRenderWindowInteractor::SafeDownCast(caller); if(this->GetControlModule()!=0 && driver!=0) { int i; mInUpdate = true; for(i=0; iGetControlModule()->GetNumberOfViewModules(); i++) if((iren=this->GetControlModule()->GetViewModule(i)->GetInteractor()) != driver) { iren->SetControlKey(driver->GetControlKey()); iren->SetShiftKey(driver->GetShiftKey()); iren->SetEventPosition(driver->GetEventPosition()); iren->SetKeySym(driver->GetKeySym()); iren->InvokeEvent(event1,callData); } mInUpdate = false; } } bool mInUpdate, mActive; }; // // Main class // iControlModule* iControlModule::New(iShell *s) { IERROR_ASSERT(s); iControlModule *cm = new iControlModule(s); if(cm != 0) { cm->FinishInitialization(); } return cm; } iControlModule::iControlModule(iShell *s) : iObject("ControlModule"), mShell(s) { mId = mIdCounter++; mInExecute = false; mBlockBroadcasts = true; mAutoRender = mSyncInteractors = mExecuteOk = false; // // Parallel performance - this must be first, since many components are parallel workers as well // mParallelManager = iParallelManager::New(this); IERROR_ASSERT(mParallelManager); mParallelObserver = iParallelUpdateEventObserver::New(this); IERROR_ASSERT(mParallelObserver); mParallelManager->AddObserver(iParallel::InformationEvent,mParallelObserver); mCurrentSubject = 0; // // Start with NULL view module family // mViewModules = 0; } void iControlModule::FinishInitialization() { // // Create observer for synchronizing interactors // mInteractorObserver = iInteractorEventObserver::New(this); IERROR_ASSERT(mInteractorObserver); // // Create script - must be created before VM family, since VM Animators will be children of CM script // mControlScript = iControlScript::New(this); // // Composer must be created before view modules // mComposer = iImageComposer::New(this); IERROR_ASSERT(mComposer); // // ViewModule family must be created after ControlModule is fully created // mViewModules = iFamily::New(this); IERROR_ASSERT(mViewModules); // // Allow broadcasts // mBlockBroadcasts = false; } iControlModule::~iControlModule() { int i; mControlScript->Delete(); mComposer->Delete(); mInteractorObserver->Delete(); // // Deleting view modules is tricky: we need to delete clones first so that // data reader and limits are not deleted before the view object are. // for(i=0; i<=mViewModules->GetMaxMemberIndex(); i++) if(mViewModules->GetMember(i)->IsClone()) mViewModules->DeleteMember(i); mViewModules->Delete(); mParallelObserver->Delete(); mParallelManager->Delete(); } bool iControlModule::Execute(const iString &command, bool render, int option, int mod) { if(mInExecute) return true; // Protect from concurrent calls from a multitheaded shell mInExecute = true; int j; mExecuteOk = false; render = render || mAutoRender; // // Is it a ControlModule command? // iString pre = command.Section(iObjectKey::PrefixSeparator(),0,0); if(iControlModule::Type().IsMatch(pre)) { iObject::ReportMissingKeys(false); //commands are not complete states this->UnPackState(command); iObject::ReportMissingKeys(true); mExecuteOk = true; if(render) { for(j=0; j<=mViewModules->GetMaxMemberIndex(); j++) { mViewModules->GetMember(j)->Render(); } } mInExecute = false; return mExecuteOk; } // // Set modes // int objOption = option & ObjectOption::Mask; int modOption = option & ModuleOption::Mask; int renOption = option & RenderOption::Mask; // // Check that modes are valid // if( (objOption!=ObjectOption::One && objOption!=ObjectOption::All) || (modOption!=ModuleOption::One && modOption!=ModuleOption::All && modOption!=ModuleOption::Clones) || (renOption!=RenderOption::One && renOption!=RenderOption::All && renOption!=RenderOption::Clones && renOption!=RenderOption::Auto)) { IERROR_LOW("Invalid option."); // // Continue after an error with default ones // objOption = ObjectOption::One; modOption = ModuleOption::One; renOption = RenderOption::Auto; } // // Loop over view modules // iDataReader *r = mViewModules->GetCurrentMember()->GetReader(); iObject::ReportMissingKeys(false); //commands are not complete states // // Execute and Set renOption to prefered value if it is Set to Auto initially // if(mod == -1) mod = mViewModules->GetCurrentMemberIndex(); for(j=0; j<=mViewModules->GetMaxMemberIndex(); j++) { switch(modOption) { case ModuleOption::One: { if(j == mod) this->ExecuteForViewModule(mViewModules->GetMember(j),command,render,objOption,renOption); break; } case ModuleOption::All: { if(renOption == RenderOption::Auto) renOption = RenderOption::All; this->ExecuteForViewModule(mViewModules->GetMember(j),command,render,objOption,renOption); break; } case ModuleOption::Clones: { if(renOption == RenderOption::Auto) renOption = RenderOption::Clones; if(r == mViewModules->GetMember(j)->GetReader()) this->ExecuteForViewModule(mViewModules->GetMember(j),command,render,objOption,renOption); break; } } } iObject::ReportMissingKeys(true); #ifdef I_CHECK1 if(renOption == RenderOption::Auto) IERROR_LOW("Improper RenderOption."); #endif // // Execute changes the state of the object. So, if the command is non-empty, we need to // clear the cached state // if(!command.IsEmpty()) { this->ClearCache(); } // // Don't render if not asked explicitly // if(!render) { mInExecute = false; return mExecuteOk; } // // Render // for(j=0; j<=mViewModules->GetMaxMemberIndex(); j++) { switch(renOption) { case RenderOption::One: { if(j == mod) mViewModules->GetMember(j)->Render(); break; } case RenderOption::All: { mViewModules->GetMember(j)->Render(); break; } case RenderOption::Clones: { if(r == mViewModules->GetMember(j)->GetReader()) mViewModules->GetMember(j)->Render(); break; } } } mInExecute = false; return mExecuteOk; } iObject* iControlModule::FindObject(const iObjectType &type, int mod, int obj) { if(mod == -1) mod = mViewModules->GetCurrentMemberIndex(); iViewModule *module = mViewModules->GetMember(mod); if(module == 0) return 0; iObject *object = this->FindSingleObject(type,module); if(object != 0) return object; if(type.IsMatch(iMarker::Type())) { return module->GetMarker(obj); } if(type.IsMatch(iParticleGroup::Type())) { if(obj == -1) return module->GetParticlesViewSubject()->GetCurrentGroup(); else return module->GetParticlesViewSubject()->GetGroup(obj); } object = this->FindViewSubject(type,module,obj); return object; } iObject* iControlModule::FindSingleObject(const iObjectType &type, iViewModule *module) { if(type.IsMatch(iControlModule::Type())) { return this; } if(type.IsMatch(iViewModule::Type())) { return module; } if(type.IsMatch(iAnimator::Type())) { return module->GetAnimator(); } if(type.IsMatch(iCamera::Type())) { return module->GetRenderTool()->GetCamera(); } if(type.IsMatch(iColorBars::Type())) { return module->GetColorBars(); } if(type.IsMatch(iDataReader::Type())) { return module->GetReader(); } if(iDataSubject::IsTypeMatch(type.FullName())) { mDataSubjectName = iDataSubject::GetDataSubjectName(type.FullName()); return module->GetReader()->GetSubject(iDataType::FindTypeByName(mDataSubjectName)); } if(type.IsMatch(iImageComposer::Type())) { return mComposer; } if(type.IsMatch(iPicker::Type())) { return module->GetPicker(); } return 0; } iViewObjectFamily* iControlModule::FindViewObjectFamily(const iObjectType &type, iViewModule *module) const { int i = 0; iViewObjectFamily *fam; while((fam = module->GetViewObjectFamily(i++)) != 0) { if(type.IsMatch(fam->GetParent()->GetObjectType())) { return fam; } } return 0; } iViewSubject* iControlModule::FindViewSubject(const iObjectType &type, iViewModule *module, int obj) const { iViewObjectFamily *fam = this->FindViewObjectFamily(type,module); if(fam != 0) { if(obj == -1) return fam->GetCurrentMember()->GetViewSubject(); else return fam->GetMember(obj)->GetViewSubject(); } return 0; } void iControlModule::ExecuteForViewModule(iViewModule *module, const iString &command, bool /*render*/, int objOption, int &renOption) { const iObjectType *ptype = iObjectTypeRegistry::FindType(command.Section(iObjectKey::PrefixSeparator(),0,0)); if(ptype == 0) { if(renOption == RenderOption::Auto) renOption = RenderOption::One; return; } iObject *object = this->FindSingleObject(*ptype,module); if(object != 0) { this->GetErrorStatus()->Monitor(object->GetErrorStatus()); object->UnPackState(command); mExecuteOk = object->UnPackedSomething() && this->GetErrorStatus()->NoError(); if(renOption == RenderOption::Auto) renOption = RenderOption::One; if(ptype->IsMatch(iDataReader::Type()) || ptype->IsMatch(iDataSubject::Type())) { if(renOption == RenderOption::Auto) renOption = RenderOption::Clones; } return; } if(ptype->IsMatch(iMarker::Type())) { iMarkerFamily *fam = module->GetMarkerFamily(); ExecuteForObject(fam,command,objOption,mExecuteOk); if(mExecuteOk) module->GetMarkerFamily()->UpdateLegend(); if(renOption == RenderOption::Auto) renOption = RenderOption::One; return; } if(ptype->IsMatch(iParticleGroup::Type())) { iParticlesViewSubject *fam = module->GetParticlesViewSubject(); ExecuteForObject(fam,command,objOption,mExecuteOk); if(renOption == RenderOption::Auto) renOption = RenderOption::One; return; } iViewObjectFamily *fam = this->FindViewObjectFamily(*ptype,module); if(fam != 0) { ExecuteForObject(fam,command,objOption,mExecuteOk); } if(renOption == RenderOption::Auto) renOption = RenderOption::One; } bool iControlModule::CreateObject(const iObjectType &type, bool render, int mod, int vmtype) { if(mod == -1) mod = mViewModules->GetCurrentMemberIndex(); iViewModule *module = mViewModules->GetMember(mod); if(module == 0) return false; render = render || mAutoRender; if(type.IsMatch(iViewModule::Type())) { int i = mViewModules->CreateMember(); if(i != -1) { // // Set the type of the instance created // if(vmtype==ModuleType::Clone || vmtype==ModuleType::Copy) { mViewModules->GetMember(i)->CopyState(module); mViewModules->GetMember(i)->BecomeClone(module); } // // If a copy, unclone // if(vmtype == ModuleType::Copy) mViewModules->GetMember(i)->BecomeClone(0); // // Update composer // mComposer->UpdateWindowList(); if(render) mViewModules->GetMember(i)->Render(); int j; for(j=0; j<=mViewModules->GetMaxMemberIndex(); j++) mViewModules->GetMember(j)->UpdateWindowNumber(); mViewModules->GetCurrentMember()->UpdateIcon(); } return i != -1; } if(type.IsMatch(iMarker::Type())) { iMarkerFamily *fam = module->GetMarkerFamily(); if(fam->GetMaxMemberIndex()==0 && !fam->IsVisible()) { fam->Show(true); module->ClearCache(); } else { if(!iControlModule_Private::CreateObject(fam,module)) return false; } if(render) module->Render(); return true; } if(type.IsMatch(iParticleGroup::Type())) { int i = module->GetParticlesViewSubject()->CreateGroup(); if(i == -1) return false; module->ClearCache(); if(render) module->Render(); return true; } iViewObjectFamily *fam = this->FindViewObjectFamily(type,module); if(fam!=0 && !fam->IsSingleInstance()) { return iControlModule_Private::CreateObject(fam,module); } #ifdef I_CHECK1 IERROR_LOW("This object cannot be created."); #endif return false; } bool iControlModule::DeleteObject(const iObjectType &type, bool render, int mod, int obj) { if(mod == -1) mod = mViewModules->GetCurrentMemberIndex(); iViewModule *module = mViewModules->GetMember(mod); if(module == 0) return false; if(type.IsMatch(iViewModule::Type())) { int j; bool ok; // // First check whether it is the only non-cloned one, then it cannot be deleted // if(!module->IsClone()) { ok = true; for(j=0; ok && j<=mViewModules->GetMaxMemberIndex(); j++) if(!mViewModules->GetMember(j)->IsClone()) ok = false; if(ok) return false; } // // If this is not a clone, delete all its clones // if(!module->IsClone()) { while(module->mClones.Size() > 0) { if(!mViewModules->DeleteMember(module->mClones[0]->GetWindowNumber())) { for(j=0; j<=mViewModules->GetMaxMemberIndex(); j++) mViewModules->GetMember(j)->UpdateWindowNumber(); mComposer->UpdateWindowList(); return false; } } } // // Now delete the window itself // ok = mViewModules->DeleteMember(mod); for(j=0; j<=mViewModules->GetMaxMemberIndex(); j++) mViewModules->GetMember(j)->UpdateWindowNumber(); mComposer->UpdateWindowList(); this->SetCurrentViewModuleIndex(-1); return ok; } if(type.IsMatch(iMarker::Type())) { iMarkerFamily *fam = module->GetMarkerFamily(); if(fam->GetMaxMemberIndex()==0 && fam->IsVisible()) { fam->Show(false); module->ClearCache(); } else { iControlModule_Private::DeleteObject(fam,module,obj); } if(render) module->Render(); return true; } if(type.IsMatch(iParticleGroup::Type())) { if(obj == -1) obj = module->GetParticlesViewSubject()->GetCurrentGroupIndex(); if(!module->GetParticlesViewSubject()->DeleteGroup(obj)) return false; module->ClearCache(); if(render) module->Render(); return true; } iViewObjectFamily *fam = this->FindViewObjectFamily(type,module); if(fam!=0 && !fam->IsSingleInstance()) { iControlModule_Private::DeleteObject(fam,module,obj); return true; } #ifdef I_CHECK1 IERROR_LOW("This object cannot be deleted."); #endif return false; } bool iControlModule::SetCurrentViewModuleIndex(int mod) { int oldcw = mViewModules->GetCurrentMemberIndex(); if(mod>=-1 && mod<=mViewModules->GetMaxMemberIndex() && mod!=oldcw) { mViewModules->SetCurrentMemberIndex(mod); mViewModules->GetMember(oldcw)->UpdateIcon(); mViewModules->GetCurrentMember()->UpdateIcon(); return true; } else return (mod == oldcw); } void iControlModule::Show(const iObjectType &type, bool show, bool render, int mod) { if(mod == -1) mod = mViewModules->GetCurrentMemberIndex(); iViewModule *module = mViewModules->GetMember(mod); if(module == 0) return; if(type.IsMatch(iMarker::Type())) { module->GetMarkerFamily()->Show(show); if(render || mAutoRender) module->Render(); return; } iViewObjectFamily *fam = this->FindViewObjectFamily(type,module); if(fam != 0) { fam->Show(show); if(render || mAutoRender) module->Render(); return; } } float iControlModule::GetMemorySize(int mod) const { int i; float s = 0.0; if(mod == -2) { for(i=0; i<=mViewModules->GetMaxMemberIndex(); i++) s += mViewModules->GetMember(i)->GetMemorySize(); } else if(mod>-2 && mod<=mViewModules->GetMaxMemberIndex()) { if(mod == -1) mod = mViewModules->GetCurrentMemberIndex(); mViewModules->GetMember(mod)->GetMemorySize(); } return s; } float iControlModule::GetUpdateTime(int mod) const { float s = 0.0; if(mod>-1 && mod<=mViewModules->GetMaxMemberIndex()) { if(mod == -1) mod = mViewModules->GetCurrentMemberIndex(); mViewModules->GetMember(mod)->GetUpdateTime(); } return s; } void iControlModule::FlyTo(const iObjectType &type, float time, int mod, int obj) const { if(mod == -1) mod = mViewModules->GetCurrentMemberIndex(); iViewModule *module = mViewModules->GetMember(mod); if(module == 0) return; const double *pos; iViewSubject *object = this->FindViewSubject(type,module,obj); if(object != 0) { pos = object->GetPosition(); } else { if(type == iPicker::Type()) pos = module->GetPicker()->GetPosition(); else return; } this->FlyTo(pos,time,mod); } void iControlModule::FlyTo(const double *pos, float time, int mod) const { if(mod == -1) mod = mViewModules->GetCurrentMemberIndex(); iViewModule *module = mViewModules->GetMember(mod); if(module==0 || pos==0) return; if(time > 1.0e-30) { // // Gradual fly-to // int n = round(time/module->GetRenderer()->GetLastRenderTimeInSeconds()); if(n > 60) n = 60; if(n < 10) n = 0; module->GetInteractor()->SetNumberOfFlyFrames(n); module->GetInteractor()->FlyTo(module->GetRenderer(),pos[0],pos[1],pos[2]); } else { // // A jump // int j; vtkCamera *cam = module->GetRenderer()->GetActiveCamera(); double cf[3], cp[3]; cam->GetPosition(cp); cam->GetFocalPoint(cf); for(j=0; j<3; j++) cp[j] += (pos[j]-cf[j]); cam->SetFocalPoint(pos); cam->SetPosition(cp); module->Render(); } } void iControlModule::PackStateBody(iString &s) const { this->PackValue(s,KeyAutoRender(),mAutoRender); this->PackValue(s,KeySynchronizeInteractors(),mSyncInteractors); this->PackValue(s,KeyOptimizationMode(),this->GetOptimizationMode()); } void iControlModule::UnPackStateBody(const iString &s) { int i; bool b; if(this->UnPackValue(s,KeyAutoRender(),b)) this->SetAutoRender(b); if(this->UnPackValue(s,KeySynchronizeInteractors(),b)) this->SetSynchronizeInteractors(b); if(this->UnPackValue(s,KeyOptimizationMode(),i)) this->SetOptimizationMode(i); // // Action keys // iObject::ReportMissingKeys(false); //action keys are not part of the states if(this->UnPackValue(s,KeySynchronizeCameras(),b) && b) this->SynchronizeCameras(); iObject::ReportMissingKeys(true); } void iControlModule::QueryState(const iObjectType &type, iString &state, int vis, int obj) { iObject *o = this->FindObject(type,vis,obj); o->PackState(state); } // // Give access to piecewise functions directly for higher efficiency // bool iControlModule::QueryValue(const iObjectKey &key, iFunctionMapping* &f, int mod, int obj) const { if(mod == -1) mod = mViewModules->GetCurrentMemberIndex(); iViewModule *module = mViewModules->GetMember(mod); if(module == 0) return OnQueryFailed(); if(key.Type().IsMatch(iParticleGroup::Type())) { if(obj == -1) obj = module->GetParticlesViewSubject()->GetCurrentGroupIndex(); if(key == iParticleGroup::KeySizeFunction()) { f = module->GetParticlesViewSubject()->GetGroup(obj)->GetSizeFunction(); return true; } } if(key.Type().IsMatch(iParticlesViewSubject::Type())) { if(obj == -1) obj = module->GetParticlesViewSubject()->GetCurrentGroupIndex(); if(key == iParticlesViewSubject::KeySizeFunction()) { f = module->GetParticlesViewSubject()->GetGroup(obj)->GetSizeFunction(); return true; } } if(key.Type().IsMatch(iVolumeViewSubject::Type())) { if(obj == -1) obj = module->GetViewObjectFamily(ViewSubject::Id::Volume)->GetCurrentMemberIndex(); if(key == iVolumeViewSubject::KeyOpacityFunction()) { f = module->GetVolumeViewSubject(obj)->GetOpacityFunction(); return true; } } f = 0; return OnQueryFailed(); } // // Give access to range collections directly for higher efficiency // bool iControlModule::QueryValue(const iObjectKey &key, iRangeMapping* &f, int mod, int /*obj*/) const { if(mod == -1) mod = mViewModules->GetCurrentMemberIndex(); iViewModule *module = mViewModules->GetMember(mod); if(module == 0) return OnQueryFailed(); if(key.Type().IsMatch(iParticlesViewSubject::Type())) { if(key == iParticlesViewSubject::KeySplitRanges()) { f = module->GetParticlesViewSubject()->GetSplitRanges(); return true; } } f = 0; return OnQueryFailed(); } // // Query images // bool iControlModule::QueryValue(const iObjectKey &key, iImage &im, int mod, int /*obj*/) const { if(mod == -1) mod = mViewModules->GetCurrentMemberIndex(); iViewModule *module = mViewModules->GetMember(mod); if(module == 0) return OnQueryFailed(); if(key.Type().IsMatch(iAnimator::Type())) { if(key == iAnimator::KeyTitlePageImage()) { im = module->GetAnimator()->GetTitlePageImage(); return true; } if(key == iAnimator::KeyLogoImage()) { im = module->GetAnimator()->GetLogoImage(); return true; } } return OnQueryFailed(); } // // Get any query as a portion of the state string // bool iControlModule::QueryValueAsString(const iObjectKey &key, iString &val, int mod, int obj) { iObject *o = this->FindObject(key,mod,obj); if(o != 0) { iString ws; o->PackState(ws); int index, ind = key.FindInString(ws,index); if(ind >=0) { if(index < 0) { val = key.FieldSeparator() + ws.Part(ind).Section(key.FieldSeparator(),1).Section(key.FieldSeparator()+key.Delimiter(),0,0) + key.FieldSeparator(); } else { val = ws.Part(ind).Section(key.FieldSeparator(),index+1,index+1); } return true; } else return OnQueryFailed(); } else return OnQueryFailed(); } // // generic QueryValue functions // #define ICONTROLMODULE_QUERYVALUE_DEFINITION(_type_) \ bool iControlModule::QueryValue(const iObjectKey &key, _type_ *val, int n, int mod, int obj) \ { \ iObject *o = this->FindObject(key,mod,obj); \ if(o != 0) \ { \ iString ws; \ o->PackState(ws); \ iObject::ReportMissingKeys(false); \ bool ret = o->UnPackValue(ws,key,val,n); \ iObject::ReportMissingKeys(true); \ return (ret?true:OnQueryFailed()); \ } \ else return OnQueryFailed(); \ } \ bool iControlModule::QueryValue(const iObjectKey &key, int index, _type_ &val, int n, int mod, int obj) \ { \ if(index<0 || index>=n) return OnQueryFailed(); \ iObject *o = this->FindObject(key,mod,obj); \ if(o != 0) \ { \ iString ws; \ o->PackState(ws); \ _type_ *tmp = new _type_[n]; IERROR_ASSERT(tmp); \ iObject::ReportMissingKeys(false); \ bool ret = o->UnPackValue(ws,key,tmp,n); \ iObject::ReportMissingKeys(true); \ val = tmp[index]; \ delete [] tmp; \ return (ret?true:OnQueryFailed()); \ } \ else return OnQueryFailed(); \ } // // Packing/unpacking helpers - mostly moved iObject helpers into public interface // #define ICONTROLMODULE_PACKCOMMAND_DEFINITION(_type1_,_type2_) \ void iControlModule::PackCommand(iString &s, const iObjectKey &key, _type1_ *val, int n) const \ { \ this->PackValue(s,key,val,n,-1,true); \ } \ void iControlModule::PackCommand(iString &s, const iObjectKey &key, _type2_ val) const \ { \ this->PackValue(s,key,val,-1,true); \ } \ void iControlModule::PackCommand(iString &s, const iObjectKey &key, int index, _type2_ val) const \ { \ this->PackValue(s,key,val,index,true); \ } ICONTROLMODULE_QUERYVALUE_DEFINITION(int); ICONTROLMODULE_QUERYVALUE_DEFINITION(bool); ICONTROLMODULE_QUERYVALUE_DEFINITION(float); ICONTROLMODULE_QUERYVALUE_DEFINITION(double); ICONTROLMODULE_QUERYVALUE_DEFINITION(iColor); ICONTROLMODULE_QUERYVALUE_DEFINITION(iString); ICONTROLMODULE_PACKCOMMAND_DEFINITION(int,int); ICONTROLMODULE_PACKCOMMAND_DEFINITION(bool,bool); ICONTROLMODULE_PACKCOMMAND_DEFINITION(float,float); ICONTROLMODULE_PACKCOMMAND_DEFINITION(double,double); ICONTROLMODULE_PACKCOMMAND_DEFINITION(iColor,iColor); ICONTROLMODULE_PACKCOMMAND_DEFINITION(iString,const iString&); // // Saving and restoring the state // bool iControlModule::SaveStateToFile(const iString &filename) const { int j, k; iViewObjectFamily *fam; iString prefix = ""; iString state, ws; iFile F(filename); if(!F.Open(iFile::_Write,iFile::_Text)) return false; this->GetShell()->OnLoadStateFileAtom(0); // // Compatibility mode // if(!F.WriteLine("CompatibilityMode "+iString::FromNumber(COMPATIBILITY_MODE))) return Error(F); // // Save the state of this ControlModule // this->PackCompleteState(state); ws = prefix + iControlModule::Type().FullName() + " " + state; if(!F.WriteLine(ws)) return Error(F); // // Save ViewModules with their window geometries, animators, data readers, limits, // particle splitters, and all view objects // this->GetShell()->OnLoadStateFileAtom(5); for(k=0; k<=mViewModules->GetMaxMemberIndex(); k++) { // // Visual module location // ws = prefix + iViewModule::Type().FullName() + " " + iString::FromNumber(k) + " " + iString::FromNumber(mViewModules->GetMember(k)->GetRenderWindow()->GetPosition()[0]) + " " + iString::FromNumber(mViewModules->GetMember(k)->GetRenderWindow()->GetPosition()[1]) + " "; // // Visual module parameters // mViewModules->GetMember(k)->PackCompleteState(state); ws += state; if(!F.WriteLine(ws)) return Error(F); this->GetShell()->OnLoadStateFileAtom(5+(75*k+5)/(mViewModules->GetMaxMemberIndex()+1)); // // Animator // ws = prefix + iAnimator::Type().FullName() + " " + iString::FromNumber(k) + " "; mViewModules->GetMember(k)->GetAnimator()->PackCompleteState(state); ws += state; if(!F.WriteLine(ws)) return Error(F); this->GetShell()->OnLoadStateFileAtom(5+(75*k+10)/(mViewModules->GetMaxMemberIndex()+1)); // // Camera // ws = prefix + iCamera::Type().FullName() + " " + iString::FromNumber(k) + " "; mViewModules->GetMember(k)->GetRenderTool()->GetCamera()->PackCompleteState(state); ws += state; if(!F.WriteLine(ws)) return Error(F); this->GetShell()->OnLoadStateFileAtom(5+(75*k+15)/(mViewModules->GetMaxMemberIndex()+1)); // // Color Bars // ws = prefix + iColorBars::Type().FullName() + " " + iString::FromNumber(k) + " "; mViewModules->GetMember(k)->GetColorBars()->PackCompleteState(state); ws += state; if(!F.WriteLine(ws)) return Error(F); this->GetShell()->OnLoadStateFileAtom(5+(75*k+20)/(mViewModules->GetMaxMemberIndex()+1)); // // Data reader // ws = prefix + iDataReader::Type().FullName() + " " + iString::FromNumber(k) + " "; mViewModules->GetMember(k)->GetReader()->PackCompleteState(state); ws += state; if(!F.WriteLine(ws)) return Error(F); this->GetShell()->OnLoadStateFileAtom(5+(75*k+25)/(mViewModules->GetMaxMemberIndex()+1)); // // Picker // ws = prefix + iPicker::Type().FullName() + " " + iString::FromNumber(k) + " "; mViewModules->GetMember(k)->GetPicker()->PackCompleteState(state); ws += state; if(!F.WriteLine(ws)) return Error(F); this->GetShell()->OnLoadStateFileAtom(5+(75*k+30)/(mViewModules->GetMaxMemberIndex()+1)); // // Save view objects // for(j=0; jGetMember(k)->GetNumberOfViewObjectFamilies(); j++) { fam = mViewModules->GetMember(k)->GetViewObjectFamily(j); if(!SaveObject(fam,fam->GetParent()->GetObjectType(),F,prefix,k)) return Error(F); this->GetShell()->OnLoadStateFileAtom(5+(75*k+30+(40*(j+1))/mViewModules->GetMember(k)->GetNumberOfViewObjectFamilies())/(mViewModules->GetMaxMemberIndex()+1)); } // // Don't save single invisible marker // if(mViewModules->GetMember(k)->GetMarkerFamily()->GetMaxMemberIndex()>0 || mViewModules->GetMember(k)->GetMarkerFamily()->GetMember(0)->IsVisible()) { if(!SaveObject(mViewModules->GetMember(k)->GetMarkerFamily(),iMarker::Type(),F,prefix,k)) return Error(F); } this->GetShell()->OnLoadStateFileAtom(5+(75*k+75)/(mViewModules->GetMaxMemberIndex()+1)); } // // Save the state of ImageComposer // mComposer->PackCompleteState(state); ws = prefix + iImageComposer::Type().FullName() + " " + state; if(!F.WriteLine(ws)) return Error(F); this->GetShell()->OnLoadStateFileAtom(82); // // Save the palettes // iPaletteSet::Default()->PackCompleteState(state); ws = prefix + iPaletteSet::Type().FullName() + " " + state; this->GetShell()->OnLoadStateFileAtom(85); this->GetShell()->OnLoadStateFileAtom(90); bool ret = this->GetShell()->SaveShellStateToFile(F); this->GetShell()->OnLoadStateFileAtom(100); F.Close(); return ret; } bool iControlModule::LoadStateFromFile(const iString &filename) { bool ok; int k, i, j, i1, i2; int CompatibilityMode = 0; iViewObjectFamily *fam; iString line, ws; iFile F(filename); if(!F.Open(iFile::_Read,iFile::_Text)) return false; // // ***************** Pre-Pass **************************** // // Find the Compatibility parameter and restore this control module // F.Rewind(); while(F.ReadLine(line)) { line.ReduceWhiteSpace(); ws = line.Section(" ",0,0); if(ws == "CompatibilityMode") { i = line.Section(" ",1,1).ToInt(ok); if(!ok || i<10 || i>COMPATIBILITY_MODE) return Error(F); CompatibilityMode = i; break; } if(ws == iControlModule::Type().FullName()) { this->UnPackCompleteState(line.Section(" ",1)); this->GetShell()->OnInitAtom(); } } this->GetShell()->OnLoadStateFileAtom(5); // // ***************** Pass 1 **************************** // // Count the number of view modules. // F.Rewind(); int nvm = 0, kvmMax = 0; while(F.ReadLine(line)) { line.ReduceWhiteSpace(); ws = line.Section(" ",0,0); if(ws == iViewModule::Type().FullName()) { k = line.Section(" ",1,1).ToInt(ok); if(!ok) return Error(F); if(k > kvmMax) kvmMax = k; nvm++; } } if(kvmMax+1 != nvm) return Error(F); // // Create missing view modules, destroy extra ones. // while(mViewModules->GetMaxMemberIndex() > kvmMax) { if(!mViewModules->DeleteMember(mViewModules->GetMaxMemberIndex())) return Error(F); } this->GetShell()->OnLoadStateFileAtom(10); while(mViewModules->GetMaxMemberIndex() < kvmMax) { if(mViewModules->CreateMember() == -1) return Error(F); this->GetShell()->OnLoadStateFileAtom(10+(30*(mViewModules->GetMaxMemberIndex()+1)/nvm)); } // // set all window numbers // for(k=0; kGetMember(k)->UpdateWindowNumber(); } // // ***************** Pass 2 **************************** // // Restore view modules // int kk = 0; F.Rewind(); while(F.ReadLine(line)) { line.ReduceWhiteSpace(); ws = line.Section(" ",0,0); if(ws == iViewModule::Type().FullName()) { k = line.Section(" ",1,1).ToInt(ok); if(!ok) return Error(F); if(k>=0 && kGetMember(k)->GetRenderWindow()->SetPosition(i1,i2); // // View module parameters // mViewModules->GetMember(k)->UnPackCompleteState(line.Section(" ",4)); this->GetShell()->OnInitAtom(); this->GetShell()->OnLoadStateFileAtom(40+(10*(kk+1)/nvm)); kk++; } } } this->GetShell()->OnLoadStateFileAtom(50); // // ***************** Pass 3 **************************** // // Restore animators, cameras, color bars, data readers, and pickers // kk = 0; F.Rewind(); while(F.ReadLine(line)) { line.ReduceWhiteSpace(); ws = line.Section(" ",0,0); if(ws == iAnimator::Type().FullName()) { k = line.Section(" ",1,1).ToInt(ok); if(!ok) return Error(F); if(k>=0 && kGetMember(k)->GetAnimator()->UnPackCompleteState(line.Section(" ",2)); this->GetShell()->OnInitAtom(); } } if(ws == iCamera::Type().FullName()) { k = line.Section(" ",1,1).ToInt(ok); if(!ok) return Error(F); if(k>=0 && kGetMember(k)->GetRenderTool()->GetCamera()->UnPackCompleteState(line.Section(" ",2)); this->GetShell()->OnInitAtom(); } } if(ws == iColorBars::Type().FullName()) { k = line.Section(" ",1,1).ToInt(ok); if(!ok) return Error(F); if(k>=0 && kGetMember(k)->GetColorBars()->UnPackCompleteState(line.Section(" ",2)); this->GetShell()->OnInitAtom(); } } if(ws == iDataReader::Type().FullName()) { k = line.Section(" ",1,1).ToInt(ok); if(!ok) return Error(F); if(k>=0 && kGetMember(k)->GetReader()->UnPackCompleteState(line.Section(" ",2)); this->GetShell()->OnInitAtom(); } } if(ws == iPicker::Type().FullName()) { k = line.Section(" ",1,1).ToInt(ok); if(!ok) return Error(F); if(k>=0 && kGetMember(k)->GetPicker()->UnPackCompleteState(line.Section(" ",2)); this->GetShell()->OnInitAtom(); this->GetShell()->OnLoadStateFileAtom(50+(10*(kk+1)/nvm)); } } } this->GetShell()->OnLoadStateFileAtom(60); // // ***************** Pass 4 **************************** // // Restore view objects, palettes, and the image composer // kk = 0; F.Rewind(); while(F.ReadLine(line)) { line.ReduceWhiteSpace(); ws = line.Section(" ",0,0); j = 0; while((fam = mViewModules->GetMember(0)->GetViewObjectFamily(j)) != 0) { LOAD_OBJECT(GetViewObjectFamily(j),fam->GetParent()->GetObjectType(),false); j++; } LOAD_OBJECT(GetMarkerFamily(),iMarker::Type(),true); if(ws == iImageComposer::Type().FullName()) { mComposer->UnPackCompleteState(line.Section(" ",1)); this->GetShell()->OnInitAtom(); } if(ws == iPaletteSet::Type().FullName()) { iPaletteSet::Default()->UnPackCompleteState(line.Section(" ",1)); this->GetShell()->OnInitAtom(); } // // Deprecated format // if(ws == "Palette") { k = line.Section(" ",1,1).ToInt(ok); if(!ok) return Error(F); ok = true; if(k<0 || k>=100000) ok = false; // // Do not read reversed palettes saved under CompatibilityMode=11 // if(CompatibilityMode==11 && line.Section(" ",2,2).Section("/",0,0).Find("*reversed")>-1) ok = false; while(k>=iPaletteSet::Default()->GetNumberOfPalettes() && ok) { ok = iPaletteSet::Default()->AddEmptyPalette(); } if(ok) { ws = line.Section(" ",2); if(!iPaletteSet::Default()->UnPackValuePalette(ws,iPaletteSet::Default()->GetPalette(k))) return Error(F); } } } this->GetShell()->OnLoadStateFileAtom(80); for(k=0; k<=mViewModules->GetMaxMemberIndex(); k++) { j = 0; while((fam = mViewModules->GetMember(k)->GetViewObjectFamily(j++)) != 0) { fam->Show(false); } } this->GetShell()->OnLoadStateFileAtom(90); bool ret = this->GetShell()->LoadShellStateFromFile(F); this->GetShell()->OnLoadStateFileAtom(100); F.Close(); return ret; } iEventObserver* iControlModule::GetInteractorObserver() const { return mInteractorObserver; } int iControlModule::GetNumberOfViewModules() const { return 1 + mViewModules->GetMaxMemberIndex(); } int iControlModule::GetCurrentViewModuleIndex() const { return mViewModules->GetCurrentMemberIndex(); } iViewModule* iControlModule::GetViewModule() const { return mViewModules->GetCurrentMember(); } iViewModule* iControlModule::GetViewModule(int mod) const { if(mod == -1) mod = mViewModules->GetCurrentMemberIndex(); return mViewModules->GetMember(mod); } iAnimatorScript* iControlModule::GetAnimatorScript(int mod) const { if(mod == -1) mod = mViewModules->GetCurrentMemberIndex(); iViewModule *module = mViewModules->GetMember(mod); if(module == 0) return 0; else return module->GetAnimator()->GetScript(); } void iControlModule::SynchronizeCameras(int mod) { if(mod == -1) mod = mViewModules->GetCurrentMemberIndex(); iViewModule *module = mViewModules->GetMember(mod); if(module == 0) return; int i; vtkCamera *c = module->GetRenderer()->GetActiveCamera(); double *fp = c->GetFocalPoint(); double *cp = c->GetPosition(); double *vu = c->GetViewUp(); double ps = c->GetParallelScale(); for(i=0; i<=mViewModules->GetMaxMemberIndex(); i++) { c = mViewModules->GetMember(i)->GetRenderer()->GetActiveCamera(); c->SetFocalPoint(fp); c->SetPosition(cp); c->SetViewUp(vu); c->SetParallelScale(ps); mViewModules->GetMember(i)->Render(); } } // // We add/remove observers so that in the non-sync mode no extra callbacks take place. // void iControlModule::SetSynchronizeInteractors(bool s) { mSyncInteractors = s; mInteractorObserver->Activate(s); this->ClearCache(); } void iControlModule::SetOptimizationMode(int m) { iDataConsumer::SetGlobalOptimizationMode(m); vtkMapper::SetGlobalImmediateModeRendering((m==DataConsumerOptimizationMode::OptimizeForMemory)?1:0); vtkDataObject::SetGlobalReleaseDataFlag((m==DataConsumerOptimizationMode::OptimizeForMemory)?1:0); this->ClearCache(); // // We need to reset everything // int j; for(j=0; j<=mViewModules->GetMaxMemberIndex(); j++) mViewModules->GetMember(j)->GetReader()->ResetPipeline(); } int iControlModule::GetOptimizationMode() const { return iDataConsumer::GetGlobalOptimizationMode(); } ifrit-3.4.2/core/icontrolmodule.h0000755000175700010010000002106412167404410015347 0ustar HomeNone/*========================================================================= Program: Ionization FRont Interactive Tool (IFRIT) Language: C++ Copyright (c) 2002-2012 Nick Gnedin All rights reserved. This file may be distributed and/or modified under the terms of the GNU General Public License version 2 as published by the Free Software Foundation and appearing in the file LICENSE.GPL included in the packaging of this file. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHORS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. =========================================================================*/ #ifndef ICONTROLMODULE_H #define ICONTROLMODULE_H #include "iobject.h" #include "iarray.h" #include "iimage.h" #include "ipointermacro.h" class iAnimatorScript; class iControlScript; class iDataType; class iDataSubject; class iEventObserver; class iFile; templateclass iFamily; class iFunctionMapping; class iHistogram; class iImageComposer; class iInteractorEventObserver; class iLimits; struct iLimitsDataHolder; class iParallelManager; class iParallelUpdateEventObserver; class iRangeMapping; class iShell; class iViewModule; class iViewObject; class iViewObjectFamily; class iViewSubject; namespace iParameter { namespace ModuleType { const int New = 0; const int Copy = 1; const int Clone = 2; }; namespace ObjectOption { const int Mask = 0x00F; const int One = 0x1; const int All = 0x2; }; namespace ModuleOption { const int Mask = 0x0F0; const int One = 0x10; const int All = 0x20; const int Clones = 0x30; }; namespace RenderOption { const int Mask = 0xF00; const int One = 0x100; const int All = 0x200; const int Clones = 0x300; const int Auto = 0xF00; } const int DefaultOption = ObjectOption::One | ModuleOption::One | RenderOption::Auto; }; #define ICONTROLMODULE_QUERYVALUE_DECLARATION(_type_) \ bool QueryValue(const iObjectKey &key, _type_ *val, int n, int mod = -1, int obj = -1); \ bool QueryValue(const iObjectKey &key, int index, _type_ &val, int n, int mod = -1, int obj = -1); \ inline bool QueryValue(const iObjectKey &key, _type_ &val, int mod = -1, int obj = -1){ return this->QueryValue(key,&val,1,mod,obj); } #define ICONTROLMODULE_PACKCOMMAND_DECLARATION(_type1_,_type2_) \ void PackCommand(iString &s, const iObjectKey &key, _type1_ *val, int n) const; \ void PackCommand(iString &s, const iObjectKey &key, _type2_ val) const; \ void PackCommand(iString &s, const iObjectKey &key, int index, _type2_ val) const; class iControlModule : public iObject { friend class iExtensionFactory; IPOINTER_AS_PART(Shell); public: vtkTypeMacro(iControlModule,iObject); static iControlModule* New(iShell *s = 0); static const iObjectType& Type(); IOBJECT_DECLARE_GETSET1(AutoRender,bool); //void SetAutoRender(bool s); //inline bool GetAutoRender() const { return mAutoRender; } IOBJECT_DECLARE_GETSET(SynchronizeInteractors,mSyncInteractors,bool); //void SetSynchronizeInteractors(int m); //inline int GetSynchronizeInteractors() const { return mSyncInteractors; } IOBJECT_DECLARE_GETSET2(OptimizationMode,int); //void SetOptimizationMode(int m); //int GetOptimizationMode() const; // // Action keys // static const iObjectKey& KeySynchronizeCameras(); void SynchronizeCameras(int mod = -1); virtual bool LoadStateFromFile(const iString &filename); virtual bool SaveStateToFile(const iString &filename) const; // // Execute a packed command // bool Execute(const iString &command, bool render, int option = iParameter::DefaultOption, int mod = -1); // // A simple wrapper // inline void Render(int renMode = iParameter::RenderOption::Auto) { this->Execute("",true, iParameter::ObjectOption::One | iParameter::ModuleOption::One | renMode); } // // Manipulating objects // virtual bool CreateObject(const iObjectType &type, bool render, int mod = -1, int vmtype = iParameter::ModuleType::New); virtual bool DeleteObject(const iObjectType &type, bool render, int mod = -1, int obj = -1); // virtual bool SetCurrentData(const iObjectType &type, int obj = -1, int mod = -1); // virtual bool SetCurrentData(int dc, int mod = -1); // virtual bool SetCurrentDataType(const iDataType &type, int mod = -1); virtual void Show(const iObjectType &type, bool show, bool render, int mod = -1); // // Get the value corresponding to the key - shortcuts for Getting and unpacking the state // ICONTROLMODULE_QUERYVALUE_DECLARATION(int) ICONTROLMODULE_QUERYVALUE_DECLARATION(bool) ICONTROLMODULE_QUERYVALUE_DECLARATION(float) ICONTROLMODULE_QUERYVALUE_DECLARATION(double) ICONTROLMODULE_QUERYVALUE_DECLARATION(iColor) ICONTROLMODULE_QUERYVALUE_DECLARATION(iString) // // Special query function // bool QueryValue(const iObjectKey &key, iFunctionMapping* &f, int mod = -1, int obj = -1) const; bool QueryValue(const iObjectKey &key, iRangeMapping* &f, int mod = -1, int obj = -1) const; bool QueryValue(const iObjectKey &key, iImage &im, int mod = -1, int obj = -1) const; bool QueryValueAsString(const iObjectKey &key, iString &s, int mod = -1, int obj = -1); // // Query the whole state of the object // void QueryState(const iObjectType &type, iString &state, int mod = -1, int obj = -1); // // Packing helpers - mostly moved iObject helpers into public interface // ICONTROLMODULE_PACKCOMMAND_DECLARATION(int,int) ICONTROLMODULE_PACKCOMMAND_DECLARATION(bool,bool) ICONTROLMODULE_PACKCOMMAND_DECLARATION(float,float) ICONTROLMODULE_PACKCOMMAND_DECLARATION(double,double) ICONTROLMODULE_PACKCOMMAND_DECLARATION(iColor,iColor) ICONTROLMODULE_PACKCOMMAND_DECLARATION(iString,const iString&) // // Additional commands // void FlyTo(const iObjectType &type, float time, int mod = -1, int obj = -1) const; void FlyTo(const double *pos, float time, int mod = -1) const; // // mod = -2: sum up all view modules // mod = -1: use the current one // float GetUpdateTime(int mod = -1) const; float GetMemorySize(int mod = -2) const; // // Access to components // int GetNumberOfViewModules() const; int GetCurrentViewModuleIndex() const; iViewModule* GetViewModule() const; iViewModule* GetViewModule(int mod) const; bool SetCurrentViewModuleIndex(int mod); iAnimatorScript* GetAnimatorScript(int mod = -1) const; inline iImageComposer* GetImageComposer() const { return mComposer; } inline iControlScript* GetControlScript() const { return mControlScript; } inline iParallelManager* GetParallelManager() const { return mParallelManager; } iEventObserver* GetInteractorObserver() const; protected: virtual ~iControlModule(); virtual void PackStateBody(iString &s) const; virtual void UnPackStateBody(const iString &s); private: iControlModule(iShell *s); void FinishInitialization(); void ExecuteForViewModule(iViewModule *module, const iString &command, bool render, int objMode, int &renMode); iObject* FindSingleObject(const iObjectType &type, iViewModule *module); iObject* FindObject(const iObjectKey &key, int mod = -1, int obj = -1); iObject* FindObject(const iObjectType &type, int mod = -1, int obj = -1); iViewSubject* FindViewSubject(const iObjectType &type, iViewModule *module, int obj = -1) const; iViewObjectFamily* FindViewObjectFamily(const iObjectType &type, iViewModule *module) const; iFamily *mViewModules; bool mAutoRender, mSyncInteractors, mBlockBroadcasts, mExecuteOk, mInExecute; mutable iString mDataSubjectName; iDataSubject *mCurrentSubject; iImageComposer *mComposer; iInteractorEventObserver *mInteractorObserver; static int mIdCounter; int mId; // // Control script // iControlScript *mControlScript; // // Parallel objects // iParallelUpdateEventObserver *mParallelObserver; iParallelManager *mParallelManager; }; inline void iControlModule::SetAutoRender(bool s) { mAutoRender = s; this->ClearCache(); } inline iObject* iControlModule::FindObject(const iObjectKey &key, int mod, int obj) { return this->FindObject(key.Type(),mod,obj); } #endif // ICONTROLMODULE_H ifrit-3.4.2/core/icontrolscript.cpp0000755000175700010010000011024412167404426015727 0ustar HomeNone/*========================================================================= Program: Ionization FRont Interactive Tool (IFRIT) Language: C++ Copyright (c) 2002-2012 Nick Gnedin All rights reserved. This file may be distributed and/or modified under the terms of the GNU General Public License version 2 as published by the Free Software Foundation and appearing in the file LICENSE.GPL included in the packaging of this file. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHORS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. =========================================================================*/ #include "icontrolscript.h" #include "ianimator.h" #include "ianimatorscript.h" #include "icalculatorparser.h" #include "icontrolmodule.h" #include "idatareader.h" #include "idirectory.h" #include "ierror.h" #include "ierrorstatus.h" #include "ifile.h" #include "iobjecthelp.h" #include "ishell.h" #include "ishellfactory.h" #include "iviewmodule.h" // // Templates (needed for some compilers) // #include "iarraytemplate.h" #include "icalculatortemplate.h" #include "iscriptkittemplate.h" using namespace iParameter; #define curScript iRequiredCast(INFO,self) #define curRender curScript->GetAutoRender() #define curControl curScript->GetControlModule() #define curVisual curScript->GetControlModule()->GetViewModule() namespace iControlScript_Private { // // Parser that recognizes object keys as variables // class Parser : public iCalculatorParser { public: Parser() : iCalculatorParser(false) { } protected: virtual bool IsVariableLetter(char c) const { return (this->iCalculatorParser::IsVariableLetter(c) || c==':'); } }; class Calculator : public iScriptKit::Calculator { public: Calculator(iControlScript *script) : iScriptKit::Calculator(script) { } protected: virtual iCalculatorParser* CreateParser() const { return new Parser; } }; template T* QueryKeyData(const iControlScript *script, const iObjectKey *key, int dim) { T* data = new T[dim]; if(data != 0) { if(script->GetControlModule()->QueryValue(*key,data,dim)) return data; else { delete [] data; return 0; } } else return 0; } template bool UpdateVariableFromKeyData(iScriptKit::Value *val, T *data, int dim) { if(val==0 || data==0) return false; if(!val->Morph(dim)) return false; // // Fill it in // int i; iScriptKit::Calculator::number_t *arr = val->CalculatorValue()->Data(); for(i=0; i::ConvertFromNative(data[i]); } delete [] data; return true; } // // Show/hide a ViewSubject // bool Show(iScript *self, const iString &arg) { const iObjectType *tmp = iObjectTypeRegistry::FindType(arg); if(tmp != 0) { curControl->Show(*tmp,true,true); return true; } else { self->GetErrorStatus()->Set("Invalid object name."); return false; } } bool Hide(iScript *self, const iString &arg) { const iObjectType *tmp = iObjectTypeRegistry::FindType(arg); if(tmp != 0) { curControl->Show(*tmp,false,curRender); return true; } else { self->GetErrorStatus()->Set("Invalid object name."); return false; } } // // Create/delete an object // bool Create(iScript *self, const iString &arg) { const iObjectType *tmp = iObjectTypeRegistry::FindType(arg.Section(" ",0,0)); if(tmp != 0) { int vmtype = ModuleType::New; if(*tmp == iViewModule::Type()) { iString v = arg.Section(" ",1); v.ReduceWhiteSpace(); if(v == "/copy") vmtype = ModuleType::Copy; if(v == "/clone") vmtype = ModuleType::Clone; } if(!curControl->CreateObject(*tmp,curRender,-1,vmtype)) { self->GetErrorStatus()->Set("Object cannot be created - perhaps, there is not enough memory."); return false; } else return true; } else { self->GetErrorStatus()->Set("Invalid object name."); return false; } } bool Remove(iScript *self, const iString &arg) { const iObjectType *tmp = iObjectTypeRegistry::FindType(arg); if(tmp != 0) { if(!curControl->DeleteObject(*tmp,curRender)) { self->GetErrorStatus()->Set("It is not allowed to delete this object."); return false; } else return true; } else { self->GetErrorStatus()->Set("Invalid object name."); return false; } } // // Save/restore state // bool SaveState(iScript *self, const iString &arg) { iString filename(arg); if(filename.IsEmpty()) { filename = curControl->GetShell()->GetEnvironment(Environment::Base) + "ifrit.ini"; } else if(filename[0] == '+') { filename.Replace(0,1,curControl->GetShell()->GetEnvironment(Environment::Base)); } if(!curControl->SaveStateToFile(filename)) { self->GetErrorStatus()->Set("Saving state to a file failed."); return false; } else return true; } bool LoadState(iScript *self, const iString &arg) { iString filename(arg); if(filename.IsEmpty()) { filename = curControl->GetShell()->GetEnvironment(Environment::Base) + "ifrit.ini"; } else if(filename[0] == '+') { filename.Replace(0,1,curControl->GetShell()->GetEnvironment(Environment::Base)); } if(!curControl->LoadStateFromFile(filename)) { self->GetErrorStatus()->Set("Loading state from a file failed."); return false; } else return true; } // // Make a window current // bool Current(iScript *self, short, int val) { if(!curControl->SetCurrentViewModuleIndex(val-1)) { self->GetErrorStatus()->Set("Incorrect ViewModule index."); return false; } else return true; } // // Set default render mode // bool Render(iScript *self, short, bool val) { curScript->SetAutoRender(val); return true; } }; using namespace iControlScript_Private; iControlScript* iControlScript::New(iControlModule *cm, iScript *parent) { IERROR_ASSERT(cm); return iShellFactory::CreateControlScript(cm,parent); } iControlScript::iControlScript(iControlModule *cm, iScript *parent) : iBasicScript(parent), mControlModule(cm) { // // Alias words (shortcuts) // this->CreateAliasWord(".e","exec"); this->CreateAliasWord(".s","show"); this->CreateAliasWord(".q","hide"); this->CreateAliasWord(".h","help"); this->CreateAliasWord(".lo","list objects"); this->CreateAliasWord(".lp","list properties"); this->CreateAliasWord(".ho","help object"); this->CreateAliasWord(".hp","help property"); this->CreateAliasWord(".p","print"); this->CreateAliasWord(".c","create"); this->CreateAliasWord(".d","delete"); this->CreateAliasWord(".r","render"); this->CreateAliasWord(".u","current-window"); this->CreateAliasWord(".a","animate"); this->CreateAliasWord(".ss","save-state"); this->CreateAliasWord(".ls","load-state"); this->CreateAliasWord(".eo","exec-all-objects"); this->CreateAliasWord(".ew","exec-all-windows"); #ifdef ISCRIPT_BACKWARD_COMPATIBLE // // Backward compatibility // this->CreateAliasWord("Vector","VectorField"); this->CreateAliasWord("Tensor","TensorField"); #endif // // Parameter words // this->AddConstant(new iScriptKit::Constant(this,"off",false)); this->AddConstant(new iScriptKit::Constant(this,"on",true)); // // Command words // // // Statements // this->AddPrototype< iScriptKit::FunctionCallStatement >("exec",Exec); this->AddPrototype< iScriptKit::FunctionCallStatement >("show",Show); this->AddPrototype< iScriptKit::FunctionCallStatement >("hide",Hide); this->AddPrototype< iScriptKit::FunctionCallStatement >("print",Print); // prints anything this->AddPrototype< iScriptKit::FunctionCallStatement >("create",Create); this->AddPrototype< iScriptKit::FunctionCallStatement >("delete",Remove); this->AddPrototype< iScriptKit::FunctionCallStatement >("animate",Animate); this->AddPrototype< iScriptKit::FunctionCallStatement >("exec-all-objects",ExecAllObjects); this->AddPrototype< iScriptKit::FunctionCallStatement >("exec-all-windows",ExecAllWindows); this->AddPrototype< iScriptKit::FunctionCallStatement >("save-state",SaveState); this->AddPrototype< iScriptKit::FunctionCallStatement >("load-state",LoadState); this->AddPrototype< iScriptKit::FunctionCallStatement >("embed animator-script",EmbedAnimatorScript); // // Help statements // this->AddPrototype< iScriptKit::FunctionCallStatement >("help",Help); this->AddPrototype< iScriptKit::SimpleStatement >("list objects",ListObjects); this->AddPrototype< iScriptKit::FunctionCallStatement >("list properties",ListProperties); this->AddPrototype< iScriptKit::FunctionCallStatement >("help object",HelpObject); this->AddPrototype< iScriptKit::FunctionCallStatement >("help property",HelpProperty); // // Genuine assignment operations to pre-defined variables // this->AddPrototype< iScriptKit::FunctionCallAssignmentStatement >("render",Render); this->AddPrototype< iScriptKit::FunctionCallAssignmentStatement >("current-window",Current); mAutoRender = true; } iControlScript::~iControlScript() { } iScriptKit::Calculator* iControlScript::CreateCalculatorBody() { return new Calculator(this); } bool iControlScript::SatisfyRequestForVariables(const iString &list) { iString w; const iObjectKey *key; int i, n = list.Contains(',') + 1; for(i=0; i -1) { // // Could be a key // key = iObjectKeyRegistry::FindKey(w,true); if(key != 0) { if(this->FindVariable(key->PrefixedFullName()) == 0) { switch(key->Argument()) { case iObjectKey::_Int: case iObjectKey::_OffsetInt: { this->AddVariable(new iScriptKit::Constant(this,key->PrefixedFullName(),0,0)); this->AddVariable(new iScriptKit::Constant(this,key->PrefixedShortName(),0,0)); break; } case iObjectKey::_Bool: { this->AddVariable(new iScriptKit::Constant(this,key->PrefixedFullName(),0,0)); this->AddVariable(new iScriptKit::Constant(this,key->PrefixedShortName(),0,0)); break; } case iObjectKey::_Float: { this->AddVariable(new iScriptKit::Constant(this,key->PrefixedFullName(),0,0)); this->AddVariable(new iScriptKit::Constant(this,key->PrefixedShortName(),0,0)); break; } case iObjectKey::_Double: { this->AddVariable(new iScriptKit::Constant(this,key->PrefixedFullName(),0,0)); this->AddVariable(new iScriptKit::Constant(this,key->PrefixedShortName(),0,0)); break; } case iObjectKey::_Color: { this->AddVariable(new iScriptKit::Constant(this,key->PrefixedFullName(),0,0)); this->AddVariable(new iScriptKit::Constant(this,key->PrefixedShortName(),0,0)); break; } default: { this->GetErrorStatus()->Set("The object property "+key->PrefixedFullName()+" is not allowed in expressions"); return false; } } } this->UpdateObjectKey(key); } } } return true; } void iControlScript::UpdateObjectKey(const iObjectKey *key) const { iScriptKit::Value *val; val = this->FindVariable(key->PrefixedFullName()); if(val != 0) this->UpdateObjectKeyVariable(key,val); val = this->FindVariable(key->PrefixedShortName()); if(val != 0) this->UpdateObjectKeyVariable(key,val); } void iControlScript::UpdateObjectKeyVariable(const iObjectKey *key, iScriptKit::Value *val) const { int dim = key->Dimension(); if(dim <= 0) { iString s; if(this->GetControlModule()->QueryValueAsString(*key,s)) { int n = s.Contains(iObjectKey::FieldSeparator()) - 1; if(dim<0 || n<1) { dim = 1; } else { // // Arrays w/o bound checking // dim = n; } } else { // // This key is missing - that can only be if it is an empty array // return; } } bool ok = false; switch(key->Argument()) { case iObjectKey::_Int: case iObjectKey::_OffsetInt: { int *data = QueryKeyData(this,key,dim); ok = UpdateVariableFromKeyData(val,data,dim); break; } case iObjectKey::_Bool: { bool *data = QueryKeyData(this,key,dim); ok = UpdateVariableFromKeyData(val,data,dim); break; } case iObjectKey::_Float: { float *data = QueryKeyData(this,key,dim); ok = UpdateVariableFromKeyData(val,data,dim); break; } case iObjectKey::_Double: { double *data = QueryKeyData(this,key,dim); ok = UpdateVariableFromKeyData(val,data,dim); break; } case iObjectKey::_Color: { int *idata = 0; iColor *data = QueryKeyData(this,key,dim); if(data != 0) { // // Transform to ints // idata = new int[dim]; if(idata != 0) { int i; for(i=0; iGetErrorStatus()->Set("Unable to update the object property; this is a bug."); } } // // Actually do Exec // bool iControlScript::ExecBody(iScript *self, const iString &request, int mode) { const iObjectKey *key = iObjectKeyRegistry::FindKey(request.Section(iObjectKey::FieldSeparator(),0,0),true); if(key == 0) { self->GetErrorStatus()->Set("Request does not start with a valid object property."); return false; } // // Mini-parser: replaces expressions in between of special symbols {} with their values. // iString w, ex(request); int ic, io; // // Remove trailing white space // io = ex.Length() - 1; while(ex.IsWhiteSpace(io)) io--; ex = ex.Part(0,io+1); while((ic=ex.Find('}')) >= 0) { w = ex.Part(0,ic+1); io = w.Find('{'); if(io == -1) { self->GetErrorStatus()->Set("No opening { in front of the closing } found.",0); return false; } w = ex.Part(io+1,ic-io-1); if(!self->GetCalculator()->Evaluate(w)) { self->GetErrorStatus()->Set(self->GetCalculator()->GetErrorMessage()); return false; } if(self->GetCalculator()->GetResultSize() != 1) { self->GetErrorStatus()->Set("Only scalar (1-dimensional) expressions are allowed inside object properties."); return false; } ex.Replace(io,ic-io+1,iString::FromNumber(self->GetCalculator()->GetResultData()[0])); } // // Execute the command // self->GetErrorStatus()->Monitor(curControl->GetErrorStatus()); if(!curControl->Execute(ex,curRender,mode) && curControl->GetErrorStatus()->NoError()) { self->GetErrorStatus()->Set("Incorrect command syntax or invalid parameter."); } if(self->GetErrorStatus()->NoError()) { curScript->UpdateObjectKey(key); return true; } else return false; } // // Exec a ControlModule command // bool iControlScript::Exec(iScript *self, const iString &request) { return ExecBody(self,request,ObjectOption::One|ModuleOption::One|RenderOption::Auto); } bool iControlScript::ExecAllObjects(iScript *self, const iString &request) { return ExecBody(self,request,ObjectOption::All|ModuleOption::One|RenderOption::Auto); } bool iControlScript::ExecAllWindows(iScript *self, const iString &request) { return ExecBody(self,request,ObjectOption::All|ModuleOption::All|RenderOption::Auto); } // // Print anything // bool iControlScript::Print(iScript *self, const iString &arg) { if(self->IsEmbedded()) return true; int i; iString w(arg); w.ReduceWhiteSpace(); if(w == "/all") { iArray list; self->QueryVariables(list); for(i=0; iOutputText(""+list[i]->Name()+"{"+list[i]->GetTypeAsText()+"}: "+list[i]->GetValueAsText()); } return true; } int io = 0, ic = -1; while(io < arg.Length()) { ic = arg.Find(',',ic+1); if(ic == -1) ic = arg.Length(); w = arg.Part(io,ic-io); if(w.Contains('(') != w.Contains(')')) // inside parentheses { if(ic < arg.Length()) continue; else { curScript->OutputText("Unmatched parenthesis."); return false; } } w.RemoveWhiteSpace(); // // Is it a complete type? // if(w.EndsWith(iObjectKey::PrefixSeparator())) { w = w.Part(0,w.Length()-iObjectKey::PrefixSeparator().Length()); const iObjectType *type = iObjectTypeRegistry::FindType(w); if(type != 0) { int i, lmax = 0; iString s, s1, out; const iObjectKey *ptr; iObjectKeyRegistry::InitTraversal(type); while((ptr=iObjectKeyRegistry::GetNextKey()) != 0) if(ptr->UnprefixedFullName().Part(0,9) != "___old___") { if(lmax < ptr->UnprefixedFullName().Length()) lmax = ptr->UnprefixedFullName().Length(); } for(i=0; iFullName() + ":

"; iObjectKeyRegistry::InitTraversal(type); while((ptr=iObjectKeyRegistry::GetNextKey()) != 0) if(ptr->UnprefixedFullName().Part(0,9) != "___old___") { s1.Clear(); curControl->QueryValueAsString(*ptr,s1); if(!s1.IsEmpty()) out += "" + ptr->UnprefixedFullName() + "" + s.Part(0,lmax-ptr->UnprefixedFullName().Length()) + " : $$" + s1 + "
"; } out.Replace("$"," "); curScript->OutputText(out); io = ic + 1; continue; } } // // Is it a single property? // const iObjectKey *key = iObjectKeyRegistry::FindKey(w); if(key != 0) { iString s1, out = "" + key->PrefixedFullName() + "" + " : "; curControl->QueryValueAsString(*key,s1); out += s1 + "
"; curScript->OutputText(out); io = ic + 1; continue; } // // Is it a variable? // iScriptKit::Value *val = curScript->FindVariable(w); if(val != 0) { curScript->OutputText(""+val->Name()+"{"+val->GetTypeAsText()+"} : "+val->GetValueAsText()); io = ic + 1; continue; } // // Is it an expression? // if(self->GetCalculator()->Compile(w)) { if(self->GetCalculator()->Link() && self->GetCalculator()->Execute()) { if(self->GetCalculator()->GetResult()->Use() == 1) { iScriptKit::Constant c(self,self->GetCalculator()->GetResult()); curScript->OutputText("{"+c.GetTypeAsText()+"}: "+c.GetValueAsText()); } else { iScriptKit::Constant c(self,self->GetCalculator()->GetResult()); curScript->OutputText("{"+c.GetTypeAsText()+"} : "+c.GetValueAsText()); } } else { curScript->OutputText(self->GetCalculator()->GetErrorMessage()); return false; } io = ic + 1; continue; } // // Could not make sense of it, just print it. // curScript->OutputText(w); io = ic + 1; } return true; } bool iControlScript::Animate(iScript *self, const iString &arg) { static const iString all("/all"); static const iString clones("/clones"); if(self->IsEmbedded()) return true; if(!curVisual->GetReader()->IsFileAnimatable()) { self->GetErrorStatus()->Set("Please, load an animatable file for the Animator to work."); return false; } if(!arg.IsEmpty() && arg!=all && arg!=clones) { iString fname(arg); iDirectory::ExpandFileName(fname,curControl->GetShell()->GetEnvironment(Environment::Base)); iFile f(fname); if(!f.Open(iFile::_Read,iFile::_Text)) { self->GetErrorStatus()->Set("Animation script file is not found."); return false; } iString st, tmp; while(f.ReadLine(tmp)) st += tmp + "\n"; if(st.IsEmpty()) { self->GetErrorStatus()->Set("Animation script file is empty or unreadable."); return false; } f.Close(); curVisual->GetAnimator()->GetScript()->SetText(st); } if(arg == all) { int i, n = curControl->GetNumberOfViewModules(); for(i=0; iGetAnimator()->AddFollower(curControl->GetViewModule(i)->GetAnimator()); } } if(arg == clones) { int i, n = curControl->GetNumberOfViewModules(); for(i=0; iGetViewModule(i)->IsClone(curVisual)) { curVisual->GetAnimator()->AddFollower(curControl->GetViewModule(i)->GetAnimator()); } } self->GetErrorStatus()->Monitor(curVisual->GetAnimator()->GetErrorStatus()); curVisual->GetAnimator()->Animate(); curVisual->GetAnimator()->RemoveAllFollowers(); return true; } bool iControlScript::EmbedAnimatorScript(iScript *self, const iString &arg) { if(self->IsEmbedded()) return true; if(!curVisual->GetReader()->IsFileAnimatable()) { self->GetErrorStatus()->Set("Please, load an animatable file for the Animator to work."); return false; } iString v(arg); // // Replace %% with \n // v.Replace("%%","\n"); self->GetErrorStatus()->Monitor(curVisual->GetAnimator()->GetErrorStatus()); curVisual->GetAnimator()->GetScript()->SetText(v); curScript->mAllowChildAccess = true; curVisual->GetAnimator()->Animate(); curScript->mAllowChildAccess = false; return true; } // // Help functions // bool iControlScript::Help(iScript *self, const iString &arg) { if(self->IsEmbedded()) return true; iString w(arg); w.RemoveWhiteSpace(); if(w == "exec") { curScript->OutputText(curScript->GetHelpString(iControlScript::_Exec)); return true; } if(w == "print") { curScript->OutputText(curScript->GetHelpString(iControlScript::_Print)); return true; } if(w=="create" || w=="delete") { curScript->OutputText(curScript->GetHelpString(iControlScript::_CreateDelete)); return true; } if(w == "current") { curScript->OutputText(curScript->GetHelpString(iControlScript::_Current)); return true; } if(w == "control") { curScript->OutputText(curScript->GetHelpString(iControlScript::_Control)); return true; } if(w.IsEmpty()) { curScript->OutputText(curScript->GetHelpString(iControlScript::_Root)); return true; } return Print(self,arg); } bool iControlScript::HelpObject(iScript *self, const iString &arg) { if(self->IsEmbedded()) return true; const iObjectType *tmp = iObjectTypeRegistry::FindType(arg); if(tmp != 0) { if(tmp->GetHelp() != 0) curScript->OutputText(tmp->GetHelp()->GetHTML()); else curScript->OutputText("No help is available for this item."); return true; } else { self->GetErrorStatus()->Set("Invalid object name."); return false; } } bool iControlScript::HelpProperty(iScript *self, const iString &arg) { if(self->IsEmbedded()) return true; const iObjectKey *tmp = iObjectKeyRegistry::FindKey(arg); if(tmp != 0) { if(tmp->GetHelp() != 0) curScript->OutputText(tmp->GetHelp()->GetHTML()); else curScript->OutputText("No help is available for this item."); return true; } else { self->GetErrorStatus()->Set("Invalid object property."); return false; } } bool iControlScript::ListObjects(iScript *self) { if(self->IsEmbedded()) return true; const int lmax = 10; int i; iString out, s; const iObjectType *ptr; for(i=0; iShortName() + s.Part(0,lmax-2-ptr->ShortName().Length()) + "$$" + ptr->FullName(); } out += "
"; out.Replace("$"," "); curScript->OutputText(out); return true; } bool iControlScript::ListProperties(iScript *self, const iString &arg) { if(self->IsEmbedded()) return true; const int lmax1 = 12, lmax2 = 10; int i; iString out, v, s; const iObjectKey *ptr; const iObjectType *tmp = iObjectTypeRegistry::FindType(arg); if(tmp != 0) { for(i=0; iUnprefixedFullName().Part(0,9) != "___old___") { switch(ptr->Argument()) { case iObjectKey::_OffsetInt: case iObjectKey::_Int: { v = "int"; break; } case iObjectKey::_Bool: { v = "bool"; break; } case iObjectKey::_Float: { v = "float"; break; } case iObjectKey::_Double: { v = "double"; break; } case iObjectKey::_Color: { v = "color"; break; } case iObjectKey::_String: { v = "string"; break; } case iObjectKey::_Any: { v = "any"; break; } } out += "" + s.Part(0,6-v.Length()) + v + "["; if(ptr->Dimension() > 0) { v = iString::FromNumber(ptr->Dimension()); } else { v = "*"; } out += v + "]" + s.Part(0,lmax1-8-v.Length()) + "$$" + ptr->UnprefixedShortName() + s.Part(0,lmax2-ptr->UnprefixedShortName().Length()) + "$$" + ptr->UnprefixedFullName() + "
"; } out += "Use 0/1 for false/true for bool values and int.int.int for an RGB color (like 255.0.0 for red). Strings must not be included in quotes and contain slash characters (/). Use @@ if you need a slash character.
"; out.Replace("$"," "); curScript->OutputText(out); return true; } else { self->GetErrorStatus()->Set("Invalid object name."); return false; } } // // This is whether the actual help text lives // const iString& iControlScript::GetHelpString(_HelpId id) const { static const iString none = "No help available for this item"; static const iString help[6] = { // "Control Script understands the same flow control operators as the AnimatorScript. Type help control for the full description of the flow control. IFrIT consists of a collection of objects; each object is controlled by a set of properties.
" "Available commands:
" " help [topic]
" "gives help on a specific topic. The short form of help is .h.
" " list objects
" "lists all available objects (short form .lo). Type help object <object-name> (short form .ho) for help on a specific object.
" " list properties <object-name>
" "lists all properties for an object specified by <object-name> (short form .lp). Type help property <object-name>:<property-name> (short form .hp) to get help on a specific property.
" " exec <request>
" "executes a request (short form .e). Type help exec for more info.
" " show <object-name>
" " hide <object-name>
" "shows/hides an object <object-name> in the scene (short forms .s/.q).
" " print <query>
" "prints values of variables and properties (short form .p). Type help print for more info.
" " create <object-name>
" " delete <object-name>
" "creates a new instance/deletes the current instance of an object <object-name> (short forms .c and .d). Type help create for more info.
" " [set] current-window <id>
" "sets the viewization window specified by <id> as current (short form .u). Type help current for more info.
" " save-state [file-name]
" " load-state [file-name]
" "saves/loads the complete state of IFrIT from a file <file-name> (short forms .ss and .ls). If the file name is not specified, the default is used.
" " animate [script-file-name]
" "animate the scene using the AnimatorScript from file <script-file-name> if it is specified, or using the current Animator settings otherwise (short form .a).
" " render <state>
" "toggles whether the scene is rendered after each command (short form .r). <state> takes only two values: on or off.
" " < <script-file-name>
" "inserts the contents of <script-file-name> (which must contain valid ControlScript commands) into the current script as if they were typed one after another on the command line. If <script-file-name> starts with the plus sign (+), the name of the IFrIT base directory will be prepended to the name of the file.
", // "Format:
" " exec <request> [request ...]
" "This command executes one or more control module requests for the current object. A request has the following form:
" " <object-name>:<property-name>/<value>[/value...]
" "Here <object-name> is the string that encapsulates the object to which this request is addressed to (use list objects to get the list of all available objects), <property-name> is the property that serves the request (use list properties <object-name> to get the list of all properties for the object <object-name>), and <value> is the value to be assigned to the property (can be an array). For example, the following command:
" " exec Camera:ParallelProjection/0
" "will set the projection in the viewization window to perspective. The same command can be typed in a short form as:
" " .e c:pp/0
" "where .e is the short form for exec. Two special forms of the exec command: exec-all-objects (short form .eo) and exec-all-windows (short form .ew) will execute the request for all instances of the object in the current viewization window and for all instances in all windows respectively.
", // "Format:
" " print <query>
" "This command prints the value of <query>, which can be a script expression, a property in the form <object-name>:<property-name>, or the whole object <object-name>: (the semi-colon at the end is required, to separate an object from a regular variable). Use list objects to get the list of all available objects and list properties <object-name> to get the list of all available properties for a given object <object-name>.
", // "Format:
" " create <object-name>
" " delete <object-name>
" "These commands create or remove a new instance of a viewization object <object-name>. The valid values for <object-name> are Surface, CrossSection, ParticlesGroup, and View (other objects cannot have multiple instances). For view modules, an additional option /copy or /clone is permitted, in order to create a copy or a clone of the current view module.
", // "Format:
" " [set] current-window = <id>
" "This command sets the viewization window #<id> as current. Here <id> is an integer number from 1 to the number of windows available. For example, the following 2 commands create a new viewization window (module) as a clone of the furst one, and make the second window current:
" " create View /clone
" " current-window = 2
", // "Variable declaration:
" " var <type>[[dim]] <name1> [, name2 ...]
" "declares a variable(s) of type <type> and name(s) <name1> (<name2> ...) with the optional dimension <dim>. More than one variable of the same type can be declared in a single statement. <type> is either int, real, or bool. For example, the following statement declares two integer arrays p and q with 5 elements each:
" " var int[5] p, q
" "Declared variables can be assigned values and can be used in expressions:
" " q[1] = 3
" " p += (1,2,3,4,5)
" " q[2] *= q[1]*sin(q[3]^2)

" "Loop statements:
" " loop <count>
" " ...
" " end
" "or
" " for <var> to <count>
" " ...
" " end
" "repeat the statements within the body of the loop <count> times. The second form also uses the variable <var> (which must be declared) as a loop index, taking consequitive values from 1 to <count>.

" "Conditional statement:
" " if <boolean-expression> then
" " ...
" " else
" " ...
" " endif
" "behaves as expected. Use usual C-style comparison operators to compare numbers: < > <= >= && || !=.

" "The text of the AnimatorScript can be embedded into the body of the ControlScript using the embedding statement:
" " embed animator-script
" " > first-animator-script-statement
" " > second-animator-script-statement
" " > ...
" " > last-animator-script-statement

" }; if(id>=0 && id<8) return help[id]; else return none; } ifrit-3.4.2/core/icontrolscript.h0000755000175700010010000000700212167404410015362 0ustar HomeNone/*========================================================================= Program: Ionization FRont Interactive Tool (IFRIT) Language: C++ Copyright (c) 2002-2012 Nick Gnedin All rights reserved. This file may be distributed and/or modified under the terms of the GNU General Public License version 2 as published by the Free Software Foundation and appearing in the file LICENSE.GPL included in the packaging of this file. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHORS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. =========================================================================*/ // // IFrIT control script class - maps control commands to function calls // #ifndef ICONTROLSCRIPT_H #define ICONTROLSCRIPT_H #include "ibasicscript.h" #include "ipointermacro.h" class iControlModule; class iObjectKey; class iControlScript: public iBasicScript { IPOINTER_AS_PART(ControlModule); public: enum _HelpId { _Root = 0, _Exec = 1, _Print = 2, _CreateDelete = 3, _Current = 4, _Control = 5 }; vtkTypeMacro(iControlScript,iBasicScript); static iControlScript* New(iControlModule *cm = 0, iScript *parent = 0); virtual const iString& GetHelpString(_HelpId id) const; void SetAutoRender(bool s){ mAutoRender = s; } inline bool GetAutoRender() const { return mAutoRender; } protected: iControlScript(iControlModule *cm, iScript *parent); virtual ~iControlScript(); // // Factory method: replace the calculator with the one that understands key values // virtual iScriptKit::Calculator* CreateCalculatorBody(); // // Convert keys into calculator variables // virtual bool SatisfyRequestForVariables(const iString &vars); private: // // Own console functions for re-directing the output into special windows // virtual void OutputText(const iString &s) const = 0; virtual void OutputError(const iString &s) const = 0; // // Helper for using object keys as script variables // void UpdateObjectKey(const iObjectKey *key) const; void UpdateObjectKeyVariable(const iObjectKey *key, iScriptKit::Value *val) const; static bool ExecBody(iScript *self, const iString &request, int mode); bool mAutoRender; // // Basic functions // static bool Exec(iScript *self, const iString &request); static bool ExecAllObjects(iScript *self, const iString &request); static bool ExecAllWindows(iScript *self, const iString &request); static bool Print(iScript *self, const iString &arg); static bool Animate(iScript *self, const iString &arg); static bool EmbedAnimatorScript(iScript *self, const iString &arg); // // Help functions // static bool Help(iScript *self, const iString &arg); static bool HelpObject(iScript *self, const iString &arg); static bool HelpProperty(iScript *self, const iString &arg); static bool ListObjects(iScript *self); static bool ListProperties(iScript *self, const iString &arg); }; #endif // ICONTROLCRIPT_H ifrit-3.4.2/core/icrosssectionpipeline.cpp0000755000175700010010000001311512167404427017266 0ustar HomeNone/*========================================================================= Program: Ionization FRont Interactive Tool (IFRIT) Language: C++ Copyright (c) 2002-2012 Nick Gnedin All rights reserved. This file may be distributed and/or modified under the terms of the GNU General Public License version 2 as published by the Free Software Foundation and appearing in the file LICENSE.GPL included in the packaging of this file. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHORS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. =========================================================================*/ #include "icrosssectionpipeline.h" #include "icrosssectionviewsubject.h" #include "ierror.h" #include "iorthopolygonplanefilter.h" #include "iorthoslicer.h" #include "iorthotextureplanefilter.h" #include // // Templates (needed for some compilers) // #include "iarraytemplate.h" #include "igenericfiltertemplate.h" #include "iviewsubjectpipelinetemplate.h" // // Main class // iCrossSectionPipeline::iCrossSectionPipeline(iCrossSectionViewSubject *s) : iViewSubjectPipeline(s,1) { mParent = s; // // Do VTK stuff // mSlicer = this->CreateFilter(); mPolygonConverter = this->CreateFilter(); mTextureConverter = this->CreateFilter(); mSlicer->SetDir(mParent->GetDir()); mSlicer->SetCurrentVar(mParent->GetVar()); mPolygonConverter->SetInput(mSlicer->GetOutput()); mTextureConverter->SetInput(mSlicer->GetOutput()); this->UpdateContents(_All); } iCrossSectionPipeline::~iCrossSectionPipeline() { } void iCrossSectionPipeline::ProduceOutput() { vtkPolyData *output = this->GetOutput(); vtkImageData *input = vtkImageData::SafeDownCast(this->GetInput()); if(input == 0) { IERROR_FATAL("iCrossSectionPipeline is configured incorrectly."); return; } if(mSlicer->GetInput() != input) { mSlicer->SetInput(input); } switch(mParent->GetActualMethod()) { case 0: { mPolygonConverter->Update(); output->ShallowCopy(mPolygonConverter->GetOutput()); break; } case 1: { // // Need to assign texture offsets first // this->SetTextureOffset(input); mTextureConverter->Update(); output->ShallowCopy(mTextureConverter->GetOutput()); break; } default: return; } } void iCrossSectionPipeline::SerialPostProcess(int index) { if(index==0 && mParent->GetActualMethod()==1) { mTextureConverter->UpdateBoundaryConditions(); } } void iCrossSectionPipeline::SetTextureOffset(vtkImageData *input) { // // Assign texture offsets // if(mParent->GetMethod() == 1) { double org[3], globalOrg[3], spa[3]; int dims[3], globalDims[3]; int Uidx, Vidx; int Axis = mParent->GetDir(); iOrthoSlicer::GetUV(Axis,Uidx,Vidx); input->GetOrigin(org); input->GetSpacing(spa); input->GetDimensions(dims); vtkImageData *globalInput = vtkImageData::SafeDownCast(mGlobalInput); if(globalInput == 0) { IERROR_LOW("Incompatible global input."); return; } globalInput->GetOrigin(globalOrg); globalInput->GetDimensions(globalDims); if(dims[Axis] != globalDims[Axis]) { // // Split along Axis // mTextureConverter->SetTexturePiece(mParent->GetTextureData(),0,0,globalOrg,globalDims); } else { int offx = round((org[Uidx]-globalOrg[Uidx])/spa[Uidx]); int offy = round((org[Vidx]-globalOrg[Vidx])/spa[Vidx]); mTextureConverter->SetTexturePiece(mParent->GetTextureData(),offx,offy,globalOrg,globalDims); } } } void iCrossSectionPipeline::UpdateMethod() { switch(mParent->GetActualMethod()) { case 0: { mPolygonConverter->Modified(); break; } case 1: { mTextureConverter->Modified(); break; } default: return; } this->Modified(); } void iCrossSectionPipeline::UpdateDir() { mSlicer->SetDir(mParent->GetDir()); mSlicer->SetPos(mParent->GetLocation()); this->Modified(); } void iCrossSectionPipeline::UpdateVar() { mSlicer->SetCurrentVar(mParent->GetVar()); this->Modified(); } void iCrossSectionPipeline::UpdatePos() { mSlicer->SetPos(mParent->GetLocation()); this->Modified(); } void iCrossSectionPipeline::UpdateInterpolateData() { mPolygonConverter->SetInterpolation(mParent->GetInterpolateData()); mSlicer->SetInterpolation(mParent->GetInterpolateData()); this->Modified(); } void iCrossSectionPipeline::UpdateSampleRate() { mSlicer->SetSampleRate(mParent->GetSampleRate()); this->Modified(); } float iCrossSectionPipeline::GetContentsMemorySize() const { float s = 0.0f; s += mSlicer->GetMemorySize(); s += mPolygonConverter->GetMemorySize(); s += mTextureConverter->GetMemorySize(); return s; } void iCrossSectionPipeline::UpdateContents(int n, int) { if(n==_All || n==_Dir) this->UpdateDir(); if(n==_All || n==_InterpolateData) this->UpdateInterpolateData(); if(n==_All || n==_Method) this->UpdateMethod(); if(n==_All || n==_Pos) this->UpdatePos(); if(n==_All || n==_SampleRate) this->UpdateSampleRate(); if(n==_All || n==_Var) this->UpdateVar(); } ifrit-3.4.2/core/icrosssectionpipeline.h0000755000175700010010000000500012167404410016715 0ustar HomeNone/*========================================================================= Program: Ionization FRont Interactive Tool (IFRIT) Language: C++ Copyright (c) 2002-2012 Nick Gnedin All rights reserved. This file may be distributed and/or modified under the terms of the GNU General Public License version 2 as published by the Free Software Foundation and appearing in the file LICENSE.GPL included in the packaging of this file. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHORS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. =========================================================================*/ #ifndef ICROSSSECTIONPIPELINE_H #define ICROSSSECTIONPIPELINE_H #include "iviewsubjectpipeline.h" class iCrossSectionViewSubject; class iOrthoPolygonPlaneFilter; class iOrthoSlicer; class iOrthoTexturePlaneFilter; class vtkImageData; class iCrossSectionPipeline : public iViewSubjectPipeline { friend class iCrossSectionViewSubject; public: enum { _Dir = iViewSubjectPipeline::__Last, _InterpolateData, _Method, _Pos, _SampleRate, _Var, __Last }; vtkTypeMacro(iCrossSectionPipeline,iViewSubjectPipeline); virtual void UpdateContents(int n, int info = 0); virtual void SerialPostProcess(int index); protected: iCrossSectionPipeline(iCrossSectionViewSubject *s); virtual ~iCrossSectionPipeline(); virtual void ProduceOutput(); virtual float GetContentsMemorySize() const; // // Pipeline operation // virtual void UpdateDir(); virtual void UpdateInterpolateData(); virtual void UpdateMethod(); virtual void UpdatePos(); virtual void UpdateSampleRate(); virtual void UpdateVar(); void SetTextureOffset(vtkImageData *input); iCrossSectionViewSubject *mParent; // // VTK stuff // iOrthoSlicer *mSlicer; iOrthoPolygonPlaneFilter *mPolygonConverter; iOrthoTexturePlaneFilter *mTextureConverter; }; #endif // ICROSSSECTIONPIPELINE_H ifrit-3.4.2/core/icrosssectionviewsubject.cpp0000755000175700010010000002724712167404427020026 0ustar HomeNone/*========================================================================= Program: Ionization FRont Interactive Tool (IFRIT) Language: C++ Copyright (c) 2002-2012 Nick Gnedin All rights reserved. This file may be distributed and/or modified under the terms of the GNU General Public License version 2 as published by the Free Software Foundation and appearing in the file LICENSE.GPL included in the packaging of this file. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHORS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. =========================================================================*/ #include "icrosssectionviewsubject.h" #include "icamera.h" #include "icolorbars.h" #include "icommondatadistributors.h" #include "icontrolmodule.h" #include "icrosssectionpipeline.h" #include "idataexplorer.h" #include "idatalimits.h" #include "ierror.h" #include "ilookuptable.h" #include "imarker.h" #include "imarkerfamily.h" #include "iorthoslicer.h" #include "irendertool.h" #include "ireplicatedactor.h" #include "iuniformgriddata.h" #include "iviewmodule.h" #include "iviewsubjectparallelpipeline.h" #include #include #include // // Templates // #include "iarraytemplate.h" using namespace iParameter; IVIEWSUBJECT_DEFINE_TYPE(iCrossSectionViewSubject,CrossSection,x); IOBJECT_DEFINE_KEY(iCrossSectionViewSubject,Dir,d,Int,1); IOBJECT_DEFINE_KEY(iCrossSectionViewSubject,InterpolateData,id,Bool,1); IOBJECT_DEFINE_KEY(iCrossSectionViewSubject,SpecialLocation,loc,Int,1); IOBJECT_DEFINE_KEY(iCrossSectionViewSubject,Method,m,Int,1); IOBJECT_DEFINE_KEY(iCrossSectionViewSubject,OverTheEdgeFlag,oe,Bool,1); IOBJECT_DEFINE_KEY(iCrossSectionViewSubject,SampleRate,-sr,Int,1); IOBJECT_DEFINE_KEY(iCrossSectionViewSubject,Var,v,OffsetInt,1); IOBJECT_DEFINE_DISTANCE_KEY(iCrossSectionViewSubject,Location,l); // // Inherited keys // IVIEWSUBJECT_DEFINE_INHERITED_KEYS_COMMON(iCrossSectionViewSubject); IVIEWSUBJECT_DEFINE_INHERITED_KEYS_SHADING(iCrossSectionViewSubject); IVIEWSUBJECT_DEFINE_INHERITED_KEYS_POSITION(iCrossSectionViewSubject); IVIEWSUBJECT_DEFINE_INHERITED_KEYS_PALETTE(iCrossSectionViewSubject,1); // // iCrossSectionViewSubject class // iCrossSectionViewSubject::iCrossSectionViewSubject(iViewModule *vm, const iDataType &type, const iString &name) : iSolidViewSubject(vm,type,name,1,ViewSubject::Flag::NoColor|ViewSubject::Flag::NoOpacity|ViewSubject::Flag::NoReplicating|ViewSubject::Flag::HasPosition) { mSubjectId = ViewSubject::Id::CrossSection; mVar = 0; mDir = 2; mPosition[0] = mPosition[1] = mPosition[2] = -1.0; mMethod = 1; mInterpolateData = true; mOverTheEdgeFlag = false; mSampleRate = 1; mForcePolygonalMethod = false; // // Do VTK stuff // mTexture = vtkTexture::New(); IERROR_ASSERT(mTexture); mTextureData = vtkImageData::New(); IERROR_ASSERT(mTextureData); mActors[0]->SetScalarVisibility(true); mActors[0]->ColorByArrayComponent(0,0); mActors[0]->GetProperty()->SetColor(1.0,1.0,1.0); mActors[0]->GetProperty()->SetOpacity(1.0); this->SetShading(false); mTexture->SetLookupTable(mActors[0]->GetLookupTable()); mTexture->SetQualityTo32Bit(); mTextureData->SetScalarTypeToFloat(); mTexture->SetInput(mTextureData); } iCrossSectionViewSubject::~iCrossSectionViewSubject() { this->ShowColorBars(false); mTexture->Delete(); mTextureData->Delete(); } void iCrossSectionViewSubject::ConfigureBody() { // // Create pipeline (must be created after the object is fully created) // this->AddMainPipeline(1); mActors[0]->SetInput(this->Pipeline()->GetOutput(0)); } void iCrossSectionViewSubject::FinishInitialization() { this->SetMethod(mMethod); this->SetInterpolateData(mInterpolateData); this->SetDir(mDir); } void iCrossSectionViewSubject::ResetPipeline() { } void iCrossSectionViewSubject::SetMethod(int m) { switch(m) { case 0: { mActors[0]->SetTexture(0); break; } case 1: { mActors[0]->SetTexture(mTexture); this->UpdateTextureSize(); break; } default: return; } mMethod = m; this->Pipeline()->UpdateContents(iCrossSectionPipeline::_Method); this->ClearCache(); } void iCrossSectionViewSubject::ForcePolygonalMethod(bool s) { mForcePolygonalMethod = s; this->Pipeline()->UpdateContents(iCrossSectionPipeline::_Method); } void iCrossSectionViewSubject::ShowColorBarsBody(bool show) { this->GetViewModule()->GetColorBars()->ShowBar(ColorBarsPriority::CrossSection,this->GetVar(),this->GetDataType(),mPalettes[0],show); } void iCrossSectionViewSubject::SetDir(int d) { this->DetachFromMarker(); if(d>=0 && d<3) { mDir = d; this->Pipeline()->UpdateContents(iCrossSectionPipeline::_Dir); if(mMethod == 1) this->UpdateTextureSize(); this->ClearCache(); } } void iCrossSectionViewSubject::SetVar(int v) { if(v>=0 && vGetLimits()->GetNumVars() && v!=this->GetVar()) { this->ShowColorBars(false); mVar = v; this->ShowColorBars(true); this->Pipeline()->UpdateContents(iCrossSectionPipeline::_Var); this->SyncWithData(this->Request(mVar)); this->ClearCache(); } } void iCrossSectionViewSubject::SetLocation(const iDistance &p) { return this->SetLocation(p.OpenGLDistance()); } void iCrossSectionViewSubject::SetLocation(double p) { iPosition pos(this->GetViewModule()); pos[mDir] = p; this->SetPosition(pos); } void iCrossSectionViewSubject::UpdatePosition(const iPosition &) { double minPos, maxPos; iUniformGridData *input = iUniformGridData::SafeDownCast(this->GetData()); if(input != 0) { double min[3], max[3]; input->GetBounds(min,max); minPos = min[mDir]; maxPos = max[mDir]; } else { minPos = -1.0; maxPos = 1.0; } if(mPosition[mDir] > maxPos) { mPosition[mDir] = maxPos; mOverTheEdgeFlag = true; } else if(mPosition[mDir] < minPos) { mPosition[mDir] = minPos; mOverTheEdgeFlag = true; } else { mOverTheEdgeFlag = false; } this->Pipeline()->UpdateContents(iCrossSectionPipeline::_Pos); } void iCrossSectionViewSubject::SetInterpolateData(bool s) { mInterpolateData = s; if(mInterpolateData) { mTexture->InterpolateOn(); mActors[0]->GetProperty()->SetInterpolationToGouraud(); } else { mTexture->InterpolateOff(); mActors[0]->GetProperty()->SetInterpolationToFlat(); } this->Pipeline()->UpdateContents(iCrossSectionPipeline::_InterpolateData); this->ClearCache(); } void iCrossSectionViewSubject::SetSampleRate(int p) { mSampleRate = p; this->Pipeline()->UpdateContents(iCrossSectionPipeline::_SampleRate); this->ClearCache(); } void iCrossSectionViewSubject::ShowBody(bool show) { if(show) { this->UpdateTextureSize(); mActors[0]->VisibilityOn(); this->ShowColorBars(true); } else { this->ShowColorBars(false); mActors[0]->VisibilityOff(); } } float iCrossSectionViewSubject::GetExtraMemorySize() const { return mTextureData->GetActualMemorySize(); } // // Two functions used in saving/restoring the state and in creating new instances with // void iCrossSectionViewSubject::SolidViewSubjectPackStateBody(iString &s) const { this->PackValue(s,KeyInterpolateData(),mInterpolateData); this->PackValue(s,KeyVar(),this->GetVar()); this->PackValue(s,KeyDir(),mDir); this->PackValue(s,KeyMethod(),mMethod); this->PackValue(s,KeySampleRate(),this->GetSampleRate()); this->PackValue(s,KeyOverTheEdgeFlag(),mOverTheEdgeFlag); iDistance dist(this->GetViewModule(),false); dist = mPosition[mDir]; this->PackValueDistance(s,KeyLocation(),dist); } void iCrossSectionViewSubject::SolidViewSubjectUnPackStateBody(const iString &s) { int i; bool b; if(this->UnPackValue(s,KeyInterpolateData(),b)) this->SetInterpolateData(b); if(this->UnPackValue(s,KeyVar(),i)) this->SetVar(i); if(this->UnPackValue(s,KeyDir(),i)) this->SetDir(i); if(this->UnPackValue(s,KeyMethod(),i)) this->SetMethod(i); if(this->UnPackValue(s,KeySampleRate(),i)) this->SetSampleRate(i); iDistance dist(this->GetViewModule(),false); if(this->UnPackValueDistance(s,KeyLocation(),dist)) this->SetLocation(dist); // // Special "action" keys // iObject::ReportMissingKeys(false); //action keys are not part of the states if(this->UnPackValue(s,KeySpecialLocation(),i)) this->PlaceAtSpecialLocation(i); iObject::ReportMissingKeys(true); } void iCrossSectionViewSubject::PlaceAtSpecialLocation(int n) { switch(n) { case 0: case 1: { if(this->IsThereData()) { iDataExplorer *de = iDataExplorer::New(this->GetViewModule()); if(de != 0) { de->SetActiveDataType(this->GetDataType()); de->SetInputComponent(this->GetVar()); const iDataExplorer::Info &di = de->GetInfo(true); if(n == 0) { if(di.CellMin >= 0) this->SetPosition(*di.PosMin); } else { if(di.CellMax >= 0) this->SetPosition(*di.PosMax); } de->Delete(); this->GetViewModule()->GetRenderTool()->GetCamera()->ShiftTo(mPosition); } } break; } case 2: case 3: case 4: { this->SetLocation(0.5*(n-3)); break; } } } bool iCrossSectionViewSubject::CanBeShown() const { iUniformGridData *data = iUniformGridData::SafeDownCast(this->GetData()); return (data!=0 && this->GetVar()GetLimits()->GetNumVars()); } void iCrossSectionViewSubject::ViewSubjectSyncWithData(const iDataSyncRequest &r) { this->Pipeline()->SetNthInput(0,this->GetData()); if(mMethod == 1) this->UpdateTextureSize(); if(r.Var()==-1 || r.Var()==this->GetVar()) { // this replaces SetPal if(this->GetVar() < this->GetLimits()->GetNumVars()) { mActors[0]->SyncWithLimits(this->GetLimits(),this->GetVar()); } } } void iCrossSectionViewSubject::UpdateTextureSize() { int dims[3], dimsOut[3], oldDimsOut[3]; int u, v; iUniformGridData *data = iUniformGridData::SafeDownCast(this->GetData()); if(data == 0) return; data->GetNumCells(dims); iOrthoSlicer::GetUV(mDir,u,v); // // Texture dimensions - make them a power of 2 for OpenGL // int xs = 1; int ys = 1; while(xs < dims[u]) xs = xs << 1; while(ys < dims[v]) ys = ys << 1; // // if the BC are not periodic, expand the texture to allow for padding // bool per[3]; this->GetLimits()->GetPeriodicities(per); if(!per[u] && xsGetDimensions(oldDimsOut); if(oldDimsOut[0]!=dimsOut[0] || oldDimsOut[1]!=dimsOut[1] || oldDimsOut[2]!=dimsOut[2]) { mTextureData->Initialize(); mTextureData->SetDimensions(dimsOut); mTextureData->AllocateScalars(); } } void iCrossSectionViewSubject::RemoveInternalDataForExtraComponents() { mTextureData->Initialize(); } iViewSubjectPipeline* iCrossSectionViewSubject::CreatePipeline(int) { return new iCrossSectionPipeline(this); } void iCrossSectionViewSubject::ConfigureMainPipeline(iViewSubjectPipeline *p, int) { iViewSubjectParallelPipeline *pp = iRequiredCast(INFO,p); iImageDataDistributor *idd = new iImageDataDistributor(pp->GetDataManager()); pp->GetDataManager()->AddDistributor(idd); iPolyDataCollector *pdc = new iPolyDataCollector(pp->GetDataManager(),idd); pdc->FixStiches(false); // cannot fix stiches in flat mode pp->GetDataManager()->AddCollector(pdc); } ifrit-3.4.2/core/icrosssectionviewsubject.h0000755000175700010010000000756412167404410017463 0ustar HomeNone/*========================================================================= Program: Ionization FRont Interactive Tool (IFRIT) Language: C++ Copyright (c) 2002-2012 Nick Gnedin All rights reserved. This file may be distributed and/or modified under the terms of the GNU General Public License version 2 as published by the Free Software Foundation and appearing in the file LICENSE.GPL included in the packaging of this file. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHORS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. =========================================================================*/ // // Header file for iCrossSectionViewSubject class // #ifndef ICROSSSECTIONVIEWSUBJECT_H #define ICROSSSECTIONVIEWSUBJECT_H #include "isolidviewsubject.h" class vtkImageData; class vtkTexture; class iCrossSectionViewSubject : public iSolidViewSubject { friend class iAbstractExtension; friend class iObjectFactory; public: vtkTypeMacro(iCrossSectionViewSubject,iSolidViewSubject); static const iObjectType& Type(); IOBJECT_DECLARE_GETSET1(Dir,int); // virtual void SetDir(int d); // inline int GetDir() const { return mDir; } IOBJECT_DECLARE_GETSET(Var,mVar,int); // virtual void SetVar(int v); // inline int GetVar() const { return mVar; } IOBJECT_DECLARE_GET1(OverTheEdgeFlag,bool); // inline int GetOverTheEdgeFlag() const { return mOverTheEdgeFlag; } IOBJECT_DECLARE_GETSET1(SampleRate,int); // virtual void SetSampleRate(int p); // inline int GetSampleRate() const { return mSampleRate }; IOBJECT_DECLARE_GETSET1(Method,int); // virtual void SetMethod(int m); // inline int GetMethod() const { return mMethod; } IOBJECT_DECLARE_GETSET1(InterpolateData,bool); // virtual void SetInterpolateData(bool s); // inline bool GetInterpolateData(){ return mInterpolateData; } virtual void SetLocation(double p); virtual void SetLocation(const iDistance &p); inline double GetLocation() const { return mPosition[mDir]; } static const iObjectKey& KeyLocation(bool opengl = false); // // Action keys // virtual void PlaceAtSpecialLocation(int n); static const iObjectKey& KeySpecialLocation(); // inline vtkLookupTable* GetColorLookupTable() const { return mColorLookupTable; } inline vtkImageData* GetTextureData() const { return mTextureData; } void ForcePolygonalMethod(bool s); inline int GetActualMethod() const { if(mForcePolygonalMethod) return 0; else return mMethod; } // // Inherited members // virtual iViewSubjectPipeline* CreatePipeline(int id); ISOLIDVIEWSUBJECT_DECLARE_INHERITED_KEYS; ISOLIDVIEWSUBJECT_DECLARE_INHERITED_MEMBERS; protected: iCrossSectionViewSubject(iViewModule *vm, const iDataType &type, const iString &name); virtual ~iCrossSectionViewSubject(); virtual void ConfigureBody(); virtual void ConfigureMainPipeline(iViewSubjectPipeline *p, int id); virtual void FinishInitialization(); virtual float GetExtraMemorySize() const; virtual void RemoveInternalDataForExtraComponents(); void UpdateTextureSize(); virtual void UpdatePosition(const iPosition &oldPos); bool mInterpolateData, mOverTheEdgeFlag; int mVar, mDir, mMethod, mSampleRate; bool mForcePolygonalMethod; // // VTK stuff // vtkTexture *mTexture; vtkImageData *mTextureData; }; #endif // ICROSSSECTIONVIEWSUBJECT_H ifrit-3.4.2/core/icubeaxesactor.cpp0000755000175700010010000000746512167404427015665 0ustar HomeNone/*========================================================================= Program: Ionization FRont Interactive Tool (IFRIT) Language: C++ Copyright (c) 2002-2012 Nick Gnedin All rights reserved. This file may be distributed and/or modified under the terms of the GNU General Public License version 2 as published by the Free Software Foundation and appearing in the file LICENSE.GPL included in the packaging of this file. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHORS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. =========================================================================*/ #include "icubeaxesactor.h" #include "iaxis.h" #include "ierror.h" #include "ioverlayhelper.h" #include #include #include #include #include #include // // Templates // #include "iarraytemplate.h" #include "igenericproptemplate.h" iCubeAxesActor* iCubeAxesActor::New(iRenderTool *rt) { IERROR_ASSERT(rt); return new iCubeAxesActor(rt); } iCubeAxesActor::iCubeAxesActor(iRenderTool *rt) : iGenericProp(true), mOverlayHelper(rt) { // // Replace axes // this->XAxis->Delete(); this->YAxis->Delete(); this->ZAxis->Delete(); this->XAxis = iAxis::New(rt); this->XAxis->GetPositionCoordinate()->SetCoordinateSystemToDisplay(); this->XAxis->GetPosition2Coordinate()->SetCoordinateSystemToDisplay(); this->XAxis->AdjustLabelsOff(); this->YAxis = iAxis::New(rt); this->YAxis->GetPositionCoordinate()->SetCoordinateSystemToDisplay(); this->YAxis->GetPosition2Coordinate()->SetCoordinateSystemToDisplay(); this->YAxis->AdjustLabelsOff(); this->ZAxis = iAxis::New(rt); this->ZAxis->GetPositionCoordinate()->SetCoordinateSystemToDisplay(); this->ZAxis->GetPosition2Coordinate()->SetCoordinateSystemToDisplay(); this->ZAxis->AdjustLabelsOff(); this->XAxis->SetLabelTextProperty(this->AxisLabelTextProperty); this->YAxis->SetLabelTextProperty(this->AxisLabelTextProperty); this->ZAxis->SetLabelTextProperty(this->AxisLabelTextProperty); this->XAxis->SetTitleTextProperty(this->AxisTitleTextProperty); this->YAxis->SetTitleTextProperty(this->AxisTitleTextProperty); this->ZAxis->SetTitleTextProperty(this->AxisTitleTextProperty); this->SetFlyModeToOuterEdges(); this->SetLabelFormat("%6.2g"); this->ScalingOff(); float b = 1.0; this->SetBounds(-b,b,-b,b,-b,b); this->SetNumberOfLabels(5); this->UseRangesOn(); this->GetProperty()->SetColor(0.0,0.0,0.0); } iCubeAxesActor::~iCubeAxesActor() { } void iCubeAxesActor::UpdateGeometry(vtkViewport *) { // // Do nothing here, we work entirely by replacing axes // } int iCubeAxesActor::RenderOpaqueGeometry(vtkViewport *vp) { int mag = mOverlayHelper->GetRenderingMagnification(); if(mag == 1) { return this->vtkCubeAxesActor2D::RenderOpaqueGeometry(vp); } else { // // Block rebuilding when working under magnification // int ret = 0; if(this->XAxisVisibility != 0) ret += this->XAxis->RenderOpaqueGeometry(vp); if(this->YAxisVisibility != 0) ret += this->YAxis->RenderOpaqueGeometry(vp); if(this->ZAxisVisibility != 0) ret += this->ZAxis->RenderOpaqueGeometry(vp); return ret; } } ifrit-3.4.2/core/icubeaxesactor.h0000644000175700010010000000355112167404410015307 0ustar HomeNone/*========================================================================= Program: Ionization FRont Interactive Tool (IFRIT) Language: C++ Copyright (c) 2002-2012 Nick Gnedin All rights reserved. This file may be distributed and/or modified under the terms of the GNU General Public License version 2 as published by the Free Software Foundation and appearing in the file LICENSE.GPL included in the packaging of this file. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHORS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. =========================================================================*/ #ifndef ICUBEAXESACTOR_H #define ICUBEAXESACTOR_H #include "igenericprop.h" #include #include "ipointermacro.h" class iOverlayHelper; class iRenderTool; class vtkViewport; class iCubeAxesActor: public iGenericProp { IPOINTER_AS_USER(OverlayHelper); public: vtkTypeMacro(iCubeAxesActor,vtkCubeAxesActor2D); static iCubeAxesActor* New(iRenderTool *rt = 0); virtual int RenderOpaqueGeometry(vtkViewport *vp); protected: virtual ~iCubeAxesActor(); virtual void UpdateGeometry(vtkViewport *vp); private: iCubeAxesActor(iRenderTool *rv); }; #endif // ICUBEAXESACTOR_H ifrit-3.4.2/core/idata.cpp0000755000175700010010000001331012167404427013730 0ustar HomeNone/*========================================================================= Program: Ionization FRont Interactive Tool (IFRIT) Language: C++ Copyright (c) 2002-2012 Nick Gnedin All rights reserved. This file may be distributed and/or modified under the terms of the GNU General Public License version 2 as published by the Free Software Foundation and appearing in the file LICENSE.GPL included in the packaging of this file. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHORS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. =========================================================================*/ #include "idata.h" #include "idirectory.h" #include "ishell.h" #include // // Templates // #include "iarraytemplate.h" using namespace iParameter; namespace iData_Private { iDataInfo& AllData() { static iDataInfo tmp; return tmp; } iSearchableArray& Keywords() { static iSearchableArray array; return array; } }; using namespace iData_Private; // // DataType class // iDataType::iDataType(int id, const iString& tname, const iString& sname, int rank, const iString &keywords, const iString &env) : mId(id), mTextName(tname), mShortName(sname), mRank(rank), mKeywords(keywords) { int i, n; mName = tname.Substitute(" ",""); for(i=0; iGetEnvironment(Environment::Data); } else { return mEnv + iDirectory::Separator(); } } else return null; } // // DataInfo class // iDataInfo::iDataInfo() { } iDataInfo::iDataInfo(const iDataInfo &set) { int i; for(i=0; i &arr(info.mArr); // cache for speed for(i=0; iIsNull()) mArr.AddUnique(arr[i]); return *this; } iDataInfo& iDataInfo::operator-=(const iDataType &type) { if(!type.IsNull()) mArr.Remove(&type); return *this; } bool iDataInfo::Includes(const iDataType &type) const { return mArr.Find(&type) >= 0; } int iDataInfo::Index(const iDataType &type) const { int i; for(i=0; i=0 && i { public: iDataTypePointer(const iDataType *ptr = 0) : iPointer::Ordered(ptr){} }; class iDataInfo { public: static const iDataInfo& None(); static const iDataInfo& Any(); iDataInfo(); iDataInfo(const iDataInfo &info); iDataInfo(const iDataType &type); ~iDataInfo(); void Erase(); inline int Count() const { return mArr.Size(); } const iDataType& Type(int i) const; int Index(const iDataType &type) const; iDataInfo& operator=(const iDataInfo &info); iDataInfo& operator+=(const iDataType &type); iDataInfo& operator+=(const iDataInfo &info); iDataInfo& operator-=(const iDataType &type); bool Includes(const iDataType &type) const; private: iOrderedArray mArr; }; inline bool iDataType::operator==(const iDataType &type) const { return mId == type.mId; } inline bool iDataType::operator!=(const iDataType &type) const { return mId != type.mId; } inline const iDataInfo operator+(const iDataInfo &info, const iDataType &type) { iDataInfo tmp(info); tmp += type; return tmp; } inline const iDataInfo operator+(const iDataInfo &info1, const iDataInfo &info2) { iDataInfo tmp(info1); tmp += info2; return tmp; } inline const iDataInfo operator-(const iDataInfo &info, const iDataType &type) { iDataInfo tmp(info); tmp -= type; return tmp; } #endif // IDATA_H ifrit-3.4.2/core/idataconsumer.cpp0000755000175700010010000001151412167404427015510 0ustar HomeNone/*========================================================================= Program: Ionization FRont Interactive Tool (IFRIT) Language: C++ Copyright (c) 2002-2012 Nick Gnedin All rights reserved. This file may be distributed and/or modified under the terms of the GNU General Public License version 2 as published by the Free Software Foundation and appearing in the file LICENSE.GPL included in the packaging of this file. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHORS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. =========================================================================*/ #include "idataconsumer.h" #include "idata.h" #include "idatahandler.h" #include "idatareader.h" #include "ierror.h" #include "iviewmodule.h" // // Templates // #include "iarraytemplate.h" using namespace iParameter; int iDataConsumer::mModeGlobal = DataConsumerOptimizationMode::OptimizeForSpeed; // // helper class // iDataSyncRequest::iDataSyncRequest() { mDataInfoPointer = new iDataInfo; IERROR_ASSERT(mDataInfoPointer); mVar = -1; } iDataSyncRequest::~iDataSyncRequest() { delete mDataInfoPointer; } void iDataSyncRequest::Set(int var, const iDataInfo &info) { mVar = var; *mDataInfoPointer = info; } // // Main class // iDataConsumer::iDataConsumer(iViewModule *vm, const iDataType &type) : mViewModule(vm), mPrimaryDataInfo(new iDataInfo(type)) { IERROR_ASSERT(vm); IERROR_ASSERT(mPrimaryDataInfo); mSecondaryDataInfo = new iDataInfo; IERROR_ASSERT(mSecondaryDataInfo); mModeLocal = mModeGlobal; mOverrideGlobal = false; this->GetViewModule()->RegisterDataConsumer(this); } iDataConsumer::~iDataConsumer() { this->GetViewModule()->UnRegisterDataConsumer(this); delete mPrimaryDataInfo; delete mSecondaryDataInfo; // // Check that all DataHandlers have been deleted too. // Fails for VTK 5.0.0 - Garbage collection is more convoluted. // if(mDataHandlers.Size() > 0) { int i; for(i=0; imConsumer = 0; } } void iDataConsumer::AddSecondaryDataType(const iDataType &type) { *mSecondaryDataInfo += type; } bool iDataConsumer::IsUsingData(const iDataInfo &info, bool onlyprimary) const { int i; for(i=0; iIncludes(info.Type(i))) return true; if(!onlyprimary && mSecondaryDataInfo->Includes(info.Type(i))) return true; } return false; } const iDataType& iDataConsumer::GetDataType() const { return mPrimaryDataInfo->Type(0); } bool iDataConsumer::IsThereData() const { return this->GetViewModule()->GetReader()->IsThereData(this->GetDataType()); } vtkDataSet* iDataConsumer::GetData() const { return this->GetViewModule()->GetReader()->GetData(this->GetDataType()); } void iDataConsumer::SetGlobalOptimizationMode(int mode) { if(DataConsumerOptimizationMode::IsValid(mode)) { mModeGlobal = mode; } } void iDataConsumer::SetOptimizationMode(int mode) { // // Reset the global mode; // if(DataConsumerOptimizationMode::IsValid(mode)) { mModeLocal = mode; mOverrideGlobal = true; } else if(mode==DataConsumerOptimizationMode::ResetToGlobal) { mModeLocal = mModeGlobal; mOverrideGlobal = false; } } int iDataConsumer::GetOptimizationMode() const { if(mOverrideGlobal) return mModeLocal; else return mModeGlobal; } // // DataHandler registry functionality // void iDataConsumer::RegisterDataHandler(iDataHandler *c) { mDataHandlers.AddUnique(c); } void iDataConsumer::UnRegisterDataHandler(iDataHandler *c) { mDataHandlers.Remove(c); } void iDataConsumer::SyncWithData(const iDataSyncRequest &r) { int i; this->SyncWithDataBody(r); for(i=0; iSyncWithData(r); } const iDataSyncRequest& iDataConsumer::RequestAll() { mRequest.Set(-1,(*mPrimaryDataInfo)+(*mSecondaryDataInfo)); return mRequest; } const iDataSyncRequest& iDataConsumer::RequestPrimary() { mRequest.Set(-1,*mPrimaryDataInfo); return mRequest; } const iDataSyncRequest& iDataConsumer::Request(int ind) { mRequest.Set(ind,(*mPrimaryDataInfo)+(*mSecondaryDataInfo)); return mRequest; } const iDataSyncRequest& iDataConsumer::Request(const iDataInfo &info, int ind) // for general use { static iDataSyncRequest req; req.Set(ind,info); return req; } ifrit-3.4.2/core/idataconsumer.h0000755000175700010010000000775012167404411015155 0ustar HomeNone/*========================================================================= Program: Ionization FRont Interactive Tool (IFRIT) Language: C++ Copyright (c) 2002-2012 Nick Gnedin All rights reserved. This file may be distributed and/or modified under the terms of the GNU General Public License version 2 as published by the Free Software Foundation and appearing in the file LICENSE.GPL included in the packaging of this file. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHORS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. =========================================================================*/ // // Single-type data consumer // #ifndef IDATACONSUMER_H #define IDATACONSUMER_H #include "iarray.h" #include "istring.h" #include "ipointermacro.h" class iDataHandler; class iDataInfo; class iDataType; class iViewModule; class vtkDataSet; namespace iParameter { namespace DataConsumerOptimizationMode { // // DataConsumer parameters // const int ResetToGlobal = -1; const int OptimizeForSpeed = 0; const int OptimizeForMemory = 1; const int OptimizeForQuality = 2; inline bool IsValid(int m){ return m>=0 && m<=2; } }; }; // // Helper class for providing requests // class iDataSyncRequest { friend class iDataConsumer; public: ~iDataSyncRequest(); int Var() const { return mVar; } const iDataInfo& Data() const { return *mDataInfoPointer; } private: iDataSyncRequest(); void Set(int var, const iDataInfo &info); int mVar; iDataInfo* mDataInfoPointer; }; class iDataConsumer { friend class iDataHandler; friend class iViewModule; IPOINTER_AS_PART(ViewModule); public: static void SetGlobalOptimizationMode(int mode); static int GetGlobalOptimizationMode(){ return mModeGlobal; } void SetOptimizationMode(int mode); int GetOptimizationMode() const; inline bool IsOptimizedForSpeed() const { return this->GetOptimizationMode() == iParameter::DataConsumerOptimizationMode::OptimizeForSpeed; } inline bool IsOptimizedForMemory() const { return this->GetOptimizationMode() == iParameter::DataConsumerOptimizationMode::OptimizeForMemory; } inline bool IsOptimizedForQuality() const { return this->GetOptimizationMode() == iParameter::DataConsumerOptimizationMode::OptimizeForQuality; } virtual const iDataType& GetDataType() const; virtual bool IsThereData() const; bool IsUsingData(const iDataInfo &info, bool onlyprimary) const; void AddSecondaryDataType(const iDataType &type); inline const iDataInfo& GetPrimaryDataInfo() const { return *mPrimaryDataInfo; } inline const iDataInfo& GetSecondaryDataInfo() const { return *mSecondaryDataInfo; } virtual void SyncWithData(const iDataSyncRequest &r); const iDataSyncRequest& RequestAll(); const iDataSyncRequest& RequestPrimary(); const iDataSyncRequest& Request(int var); static const iDataSyncRequest& Request(const iDataInfo &info, int var = -1); protected: iDataConsumer(iViewModule *vm, const iDataType &type); virtual ~iDataConsumer(); virtual vtkDataSet* GetData() const; void RegisterDataHandler(iDataHandler *c); void UnRegisterDataHandler(iDataHandler *c); virtual void SyncWithDataBody(const iDataSyncRequest &r) = 0; iDataInfo *mPrimaryDataInfo, *mSecondaryDataInfo; private: iDataSyncRequest mRequest; iPointerArray mDataHandlers; static int mModeGlobal; int mModeLocal; bool mOverrideGlobal; }; #endif // IDATACONSUMER_H ifrit-3.4.2/core/idataexplorer.cpp0000755000175700010010000001315312167404427015516 0ustar HomeNone/*========================================================================= Program: Ionization FRont Interactive Tool (IFRIT) Language: C++ Copyright (c) 2002-2012 Nick Gnedin All rights reserved. This file may be distributed and/or modified under the terms of the GNU General Public License version 2 as published by the Free Software Foundation and appearing in the file LICENSE.GPL included in the packaging of this file. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHORS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. =========================================================================*/ #include "idataexplorer.h" #include "idata.h" #include "idatalimits.h" #include "idatareader.h" #include "idatasubject.h" #include "ierror.h" #include "iextensionfactory.h" #include "ihistogram.h" #include "ihistogrammaker.h" #include "isurfaceviewsubject.h" #include "iviewmodule.h" #include "iviewobjectfamily.h" #include #include // // Templates (needed for some compilers) // #include "iarraytemplate.h" // // DataExplorer must be an object so that it can be created by the ObjectFactory // IOBJECT_DEFINE_TYPE(iDataExplorer,DataExplorer,-de,iObjectType::_Helper); // helper type iDataExplorer* iDataExplorer::New(iViewModule *vm) { IERROR_ASSERT(vm); return new iDataExplorer(vm); } iDataExplorer::iDataExplorer(iViewModule *vm) : iMultiTypeDataConsumer(vm,iDataInfo::Any()) { mHistogramMaker = 0; mMTime = 0; mComputeRangeOnly = false; mComponent = 0; mStretch = 0; } iDataExplorer::~iDataExplorer() { if(mHistogramMaker != 0) mHistogramMaker->Delete(); } void iDataExplorer::SyncWithDataBody(const iDataSyncRequest &) { if(mComponent >= this->GetViewModule()->GetReader()->GetLimits(this->GetDataType())->GetNumVars()) { mComponent = 0; mMTime = 0; } } void iDataExplorer::UpdateDataType(int prev) { if(prev != mActiveDataTypeIndex) { if(mHistogramMaker != 0) { mHistogramMaker->Delete(); mHistogramMaker = 0; } mComponent = 0; mMTime = 0; } } const iDataExplorer::Info& iDataExplorer::GetInfo(bool rangeonly, float start, float length) { if(mHistogramMaker == 0) { mHistogramMaker = this->GetViewModule()->GetReader()->GetSubject(this->GetDataType())->CreateHistogramMaker(); IERROR_ASSERT(mHistogramMaker); mHistogramMaker->SetFullResolution(true); } if(this->IsThereData()) { mHistogramMaker->SetDataRank(this->GetDataType().GetRank()); mHistogramMaker->SetInput(this->GetData(),mComponent); mHistogramMaker->SetStretch(mStretch); mHistogramMaker->SetProgressRange(start,length); mHistogramMaker->GetInput()->Update(); if(mHistogramMaker->GetInput()->GetMTime() > mMTime) { mComputeRangeOnly = rangeonly; this->Execute(); } } return mInfo; } void iDataExplorer::SetStretch(int v) { if(mStretch != v) { mStretch = v; mMTime = 0; } } void iDataExplorer::SetInputComponent(int c) { if(c>=0 && cGetNumberOfInputComponents() && c!=mComponent) { mComponent = c; mMTime = 0; } } int iDataExplorer::GetNumberOfInputComponents() const { return this->GetViewModule()->GetReader()->GetLimits(this->GetDataType())->GetNumVars(); } void iDataExplorer::Execute() { int j; if(mHistogramMaker == 0) { vtkErrorMacro("iDataExplorer has no input."); return; } if(mComputeRangeOnly) { mHistogramMaker->GetHistogramRange(mInfo.Minimum,mInfo.CellMin,mInfo.PosMin,mInfo.Maximum,mInfo.CellMax,mInfo.PosMax); mInfo.Histogram = 0; mInfo.Median = 0.0; mInfo.Average = 0.0; mInfo.Dispersion = 0.0; return; } const iHistogram *h = mHistogramMaker->GetHistogram(); // dereference for better performance if(h == 0) { vtkErrorMacro("iDataExplorer has null histogram."); #ifdef I_DEBUG h = mHistogramMaker->GetHistogram(); #endif mInfo.Histogram = 0; mInfo.Maximum = iMath::_LargeFloat; mInfo.Minimum = -iMath::_LargeFloat; mInfo.Median = 0.0; mInfo.Average = 0.0; mInfo.Dispersion = 0.0; return; } mMTime = mHistogramMaker->GetInput()->GetMTime(); float max = mHistogramMaker->ApplyStretch(h->GetMaxValue(),true); float min = mHistogramMaker->ApplyStretch(h->GetMinValue(),false); float avg, dis, med; if(max > min) { double sum0 = 0.0, sum1 = 0.0, sum2 = 0.0; for(j=0; jN(); j++) { sum0 += h->Y(j); sum1 += h->Y(j)*h->X(j); sum2 += h->Y(j)*h->X(j)*h->X(j); } if(sum0 > 0.0) { avg = min + sum1/sum0*(max-min); dis = sqrt(sum2/sum0-pow(sum1/sum0,2.0))*(max-min); med = 0.0; sum1 = 0.0; for(j=0; jN(); j++) { if(sum1<0.5*sum0 && (sum1+=h->Y(j))>=0.5*sum0) { med = min + h->X(j)*(max-min); break; } } } else { avg = dis = med = 0.5*(max+min); } } else { avg = med = min = max = 0.5*(max+min); dis = 0.0; } mInfo.Histogram = h; mInfo.Maximum = h->GetMaxValue(); mInfo.Minimum = h->GetMinValue(); mInfo.Median = mHistogramMaker->ResetStretch(med); mInfo.Average = mHistogramMaker->ResetStretch(avg); mInfo.Dispersion = mHistogramMaker->ResetStretch(dis); this->Modified(); } ifrit-3.4.2/core/idataexplorer.h0000755000175700010010000000477412167404411015165 0ustar HomeNone/*========================================================================= Program: Ionization FRont Interactive Tool (IFRIT) Language: C++ Copyright (c) 2002-2012 Nick Gnedin All rights reserved. This file may be distributed and/or modified under the terms of the GNU General Public License version 2 as published by the Free Software Foundation and appearing in the file LICENSE.GPL included in the packaging of this file. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHORS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. =========================================================================*/ #ifndef IDATAEXPLORER_H #define IDATAEXPLORER_H #include #include "imultitypedataconsumer.h" class iDataType; class iHistogram; class iHistogramMaker; class iObjectType; class iPosition; class iDataExplorer : public vtkObject, public iMultiTypeDataConsumer { friend class iExtensionFactory; public: struct Info { float Maximum; float Minimum; float Median; float Average; float Dispersion; const iHistogram* Histogram; vtkIdType CellMin, CellMax; const iPosition *PosMin, *PosMax; }; vtkTypeMacro(iDataExplorer,vtkObject); static iDataExplorer* New(iViewModule *vm = 0); static const iObjectType& Type(); // // using a struct, only one Update is needed to bring everything up to date // const Info& GetInfo(bool rangeonly = false, float start = 0.0, float length = 1.0); void SetStretch(int v); void SetInputComponent(int c); int GetNumberOfInputComponents() const; protected: virtual ~iDataExplorer(); virtual void Execute(); virtual void SyncWithDataBody(const iDataSyncRequest &r); virtual void UpdateDataType(int prev); private: iDataExplorer(iViewModule *vm); bool mComputeRangeOnly; int mComponent, mStretch; Info mInfo; iHistogramMaker *mHistogramMaker; unsigned long mMTime; }; #endif // IDATAEXPLORER_H ifrit-3.4.2/core/idataformatter.cpp0000755000175700010010000001430512167404427015661 0ustar HomeNone/*========================================================================= Program: Ionization FRont Interactive Tool (IFRIT) Language: C++ Copyright (c) 2002-2012 Nick Gnedin All rights reserved. This file may be distributed and/or modified under the terms of the GNU General Public License version 2 as published by the Free Software Foundation and appearing in the file LICENSE.GPL included in the packaging of this file. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHORS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. =========================================================================*/ #include "idataformatter.h" #include "idatalimits.h" #include // // Templates // #include "iarraytemplate.h" iDataFormatter* iDataFormatter::New(iViewModule *vm) { IERROR_ASSERT(vm); return new iDataFormatter(vm); } iDataFormatter::iDataFormatter(iViewModule *vm) : mViewModule(vm) { mFormatHelper = " "; } iDataFormatter::~iDataFormatter() { } void iDataFormatter::AddOneLine(const iString &name, const iString &data, const iString &unit) { mVarNameLines.Add(name); mVarDataLines.Add(data); mVarUnitLines.Add(unit); } void iDataFormatter::GetReport(int i, iString& varName, iString &varData, iString &varUnit) const { if(i>=0 && iGetRank(i)==0) { s2 = iString::FromNumber(v[i],"%.3e"); if(maxLen < s2.Length()) maxLen = s2.Length(); } while(mFormatHelper.Length() < maxLen) mFormatHelper += " "; for(i=0; iGetRank(i)==0) { vlog = float(log10(1.0e-30+fabs(v[i]))); s2 = iString::FromNumber(v[i],"%.3e"); if(s2.Length() < maxLen) s2 += mFormatHelper.Part(0,maxLen-s2.Length()); s1 = s2 + " (" + iString::FromNumber(vlog,"% 5.2f") + " dex)"; this->AddOneLine(lim->GetName(i),s1,lim->GetUnit(i)); } } void iDataFormatter::FormatVectorData(iDataLimits *lim, int ivar, float *v, float *div, float *vort) { int i, maxLen; iString s1, s2, unit; if(lim==0 || v==0) return; if(ivar>=0 && ivarGetNumVars() && !lim->GetUnit(ivar).IsEmpty()) unit = lim->GetUnit(ivar); // // Divergence and vorticity // if(div != 0) { s1 = iString::FromNumber(div[0],"%.3e"); } if(vort != 0) { float vortVal = 0.0; for(i=0; i<3; i++) vortVal += vort[i]*vort[i]; vortVal = float(sqrt(vortVal)); s2 = iString::FromNumber(vortVal,"%.3e"); } maxLen = s1.Length(); if(s2.Length() > maxLen) maxLen = s2.Length(); while(mFormatHelper.Length() < maxLen) mFormatHelper += " "; if(!s1.IsEmpty()) this->AddOneLine("Divergence",s1+mFormatHelper.Part(0,maxLen-s1.Length()),unit); if(!s2.IsEmpty()) this->AddOneLine("Vorticity",s2+mFormatHelper.Part(0,maxLen-s2.Length()),unit); // // Vector components // s1 = "( "; for(i=0; i<3; i++) { s1 += iString::FromNumber(v[i],"%.3e"); if(i < 2) s1 += " , "; } s1 += " )"; this->AddOneLine((ivar<0 || ivar>=lim->GetNumVars())?"Vector components":lim->GetNameForClass(ivar),s1,unit); } void iDataFormatter::FormatTensorData(iDataLimits *lim, int ivar, float *v, bool compressed) { int i, j; iString s1, s2, unit; if(lim==0 || v==0) return; if(ivar>=0 && ivarGetNumVars() && !lim->GetUnit(ivar).IsEmpty()) unit = lim->GetUnit(ivar); // // Compute the eigenvalues // float *mat[3], eig[3], *eiv[3], tmp; float mat0[3], mat1[3], mat2[3]; float eiv0[3], eiv1[3], eiv2[3]; // // Set up working matrices // mat[0] = mat0; mat[1] = mat1; mat[2] = mat2; eiv[0] = eiv0; eiv[1] = eiv1; eiv[2] = eiv2; if(compressed) { mat[0][0] = *(v+0); mat[0][1] = *(v+1); mat[0][2] = *(v+2); mat[1][0] = *(v+1); mat[1][1] = *(v+3); mat[1][2] = *(v+4); mat[2][0] = *(v+2); mat[2][1] = *(v+4); mat[2][2] = *(v+5); } else { mat[0][0] = *(v+0); mat[0][1] = *(v+1); mat[0][2] = *(v+2); mat[1][0] = *(v+3); mat[1][1] = *(v+4); mat[1][2] = *(v+5); mat[2][0] = *(v+6); mat[2][1] = *(v+7); mat[2][2] = *(v+8); } vtkMath::Jacobi(mat,eig,eiv); // // Order eigenvalues // for(i=0; i<2; i++) { for(j=i+1; j<3; j++) { if(eig[i] > eig[j]) { tmp = eig[i]; eig[i] = eig[j]; eig[j] = tmp; } } } int maxLen = 0; for(i=0; i<3; i++) { s2 = iString::FromNumber(eig[i],"%.3e"); if(maxLen < s2.Length()) maxLen = s2.Length(); } while(mFormatHelper.Length() < maxLen) mFormatHelper += " "; for(i=0; i<3; i++) { s2 = iString::FromNumber(eig[i],"%.3e"); this->AddOneLine("Eigenvalue #"+iString::FromNumber(i),s2+mFormatHelper.Part(0,maxLen-s2.Length()),unit); } // // Tensor components // maxLen = 0; for(j=0; j<3; j++) { for(i=0; i<3; i++) { s2 = iString::FromNumber(mat[j][i],"%.3e"); if(maxLen < s2.Length()) maxLen = s2.Length(); } } while(mFormatHelper.Length() < maxLen) mFormatHelper += " "; for(j=0; j<3; j++) { s1 = " "; for(i=0; i<3; i++) { s2 = iString::FromNumber(mat[j][i],"%.3e"); if(s2.Length() < maxLen) s2 += mFormatHelper.Part(0,maxLen-s2.Length()); s1 += s2; s1 += " "; } if(j == 1) { this->AddOneLine((ivar<0 || ivar>=lim->GetNumVars())?"Tensor components":lim->GetName(ivar),s1,unit); } else { this->AddOneLine("",s1,unit); } } } ifrit-3.4.2/core/idataformatter.h0000755000175700010010000000442412167404411015320 0ustar HomeNone/*========================================================================= Program: Ionization FRont Interactive Tool (IFRIT) Language: C++ Copyright (c) 2002-2012 Nick Gnedin All rights reserved. This file may be distributed and/or modified under the terms of the GNU General Public License version 2 as published by the Free Software Foundation and appearing in the file LICENSE.GPL included in the packaging of this file. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHORS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. =========================================================================*/ #ifndef IDATAFORMATTER_H #define IDATAFORMATTER_H #include #include "iarray.h" #include "istring.h" #include "ipointermacro.h" class iDataLimits; class iViewModule; class iDataFormatter : public vtkObjectBase { IPOINTER_AS_PART(ViewModule); public: static iDataFormatter* New(iViewModule *vm = 0); inline int GetNumReportLines() const { return mVarNameLines.Size(); } void GetReport(int i, iString& varName, iString &varData, iString &varUnit) const; void AddOneLine(const iString &name, const iString &data, const iString &unit); void ClearReport(); void FormatScalarData(iDataLimits *lim, int n, float *v, bool useRank = false); void FormatVectorData(iDataLimits *lim, int ivar, float *v, float *div = 0, float *vort = 0); void FormatTensorData(iDataLimits *lim, int ivar, float *v, bool compressed = false); protected: virtual ~iDataFormatter(); private: iDataFormatter(iViewModule *vm); iArray mVarNameLines, mVarDataLines, mVarUnitLines; iString mFormatHelper; }; #endif // IDATAFORMATTER_H ifrit-3.4.2/core/idatahandler.cpp0000755000175700010010000000423312167404427015272 0ustar HomeNone/*========================================================================= Program: Ionization FRont Interactive Tool (IFRIT) Language: C++ Copyright (c) 2002-2012 Nick Gnedin All rights reserved. This file may be distributed and/or modified under the terms of the GNU General Public License version 2 as published by the Free Software Foundation and appearing in the file LICENSE.GPL included in the packaging of this file. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHORS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. =========================================================================*/ #include "idatahandler.h" #include "icontrolmodule.h" #include "idataconsumer.h" #include "ierror.h" #include "ishell.h" #include "iviewmodule.h" iDataHandler::iDataHandler(iDataConsumer *consumer) : mViewModule((consumer==0)?0:consumer->GetViewModule()) { IERROR_ASSERT(consumer); mConsumer = consumer; mConsumer->RegisterDataHandler(this); if(mViewModule != 0) mViewModule->GetControlModule()->GetShell()->OnInitAtom(); } iDataHandler::~iDataHandler() { if(mConsumer != 0) mConsumer->UnRegisterDataHandler(this); } bool iDataHandler::IsOptimizedForSpeed() const { if(mConsumer != 0) return mConsumer->IsOptimizedForSpeed(); else return false; } bool iDataHandler::IsOptimizedForMemory() const { if(mConsumer != 0) return mConsumer->IsOptimizedForMemory(); else return false; } bool iDataHandler::IsOptimizedForQuality() const { if(mConsumer != 0) return mConsumer->IsOptimizedForQuality(); else return false; } ifrit-3.4.2/core/idatahandler.h0000755000175700010010000000344712167404411014736 0ustar HomeNone/*========================================================================= Program: Ionization FRont Interactive Tool (IFRIT) Language: C++ Copyright (c) 2002-2012 Nick Gnedin All rights reserved. This file may be distributed and/or modified under the terms of the GNU General Public License version 2 as published by the Free Software Foundation and appearing in the file LICENSE.GPL included in the packaging of this file. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHORS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. =========================================================================*/ #ifndef IDATAHANDLER_H #define IDATAHANDLER_H #include "ipointermacro.h" class iDataConsumer; class iDataSyncRequest; class iViewModule; class iDataHandler { friend class iDataConsumer; IPOINTER_AS_PART(ViewModule); public: bool IsOptimizedForSpeed() const; bool IsOptimizedForMemory() const; bool IsOptimizedForQuality() const; protected: iDataHandler(iDataConsumer *consumer); virtual ~iDataHandler(); virtual void SyncWithData(const iDataSyncRequest &r) = 0; private: iDataConsumer *mConsumer; }; #endif // IVISUALMODULEDATAHANDLER_H ifrit-3.4.2/core/idatahelper.cpp0000644000175700010010000001007412167404427015131 0ustar HomeNone/*========================================================================= Program: Ionization FRont Interactive Tool (IFRIT) Language: C++ Copyright (c) 2002-2012 Nick Gnedin All rights reserved. This file may be distributed and/or modified under the terms of the GNU General Public License version 2 as published by the Free Software Foundation and appearing in the file LICENSE.GPL included in the packaging of this file. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHORS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. =========================================================================*/ #include "idatahelper.h" #include "ierror.h" #include #include #include namespace iDataHelper_Private { template void CICTemplate(bool periodic[3], int dims[3], double org[3], double spa[3], T pos[3], int ijk1[3], int ijk2[3], double d1[3], double d2[3]); }; using namespace iDataHelper_Private; iDataHelper::iDataHelper(vtkDataSet *ds) { mData = ds; } iDataHelper::~iDataHelper() { } unsigned int iDataHelper::GetDataRank() const { if(this->IsThereTensorData()) return 2U; else if(this->IsThereVectorData()) return 1U; else return 0U; } bool iDataHelper::IsThereData() const { return (mData!=0 && mData->GetNumberOfPoints()>0); } bool iDataHelper::IsThereScalarData() const { return (mData!=0 && mData->GetPointData()!=0 && mData->GetPointData()->GetScalars()!=0 && mData->GetPointData()->GetScalars()->GetSize()>0 && mData->GetPointData()->GetScalars()->GetDataType()==VTK_FLOAT); } bool iDataHelper::IsThereVectorData() const { return (mData!=0 && mData->GetPointData()!=0 && mData->GetPointData()->GetVectors()!=0 && mData->GetPointData()->GetVectors()->GetSize()>0 && mData->GetPointData()->GetVectors()->GetDataType()==VTK_FLOAT && mData->GetPointData()->GetVectors()->GetNumberOfComponents()==3); } bool iDataHelper::IsThereTensorData() const { return (mData!=0 && mData->GetPointData()!=0 && mData->GetPointData()->GetTensors()!=0 && mData->GetPointData()->GetTensors()->GetSize()>0 && mData->GetPointData()->GetTensors()->GetDataType()==VTK_FLOAT && mData->GetPointData()->GetTensors()->GetNumberOfComponents()==9); } // // Two helper functions // void iDataHelper::CIC(bool periodic[3], int dims[3], double org[3], double spa[3], float pos[3], int ijk1[3], int ijk2[3], double d1[3], double d2[3]) { CICTemplate(periodic,dims,org,spa,pos,ijk1,ijk2,d1,d2); } void iDataHelper::CIC(bool periodic[3], int dims[3], double org[3], double spa[3], double pos[3], int ijk1[3], int ijk2[3], double d1[3], double d2[3]) { CICTemplate(periodic,dims,org,spa,pos,ijk1,ijk2,d1,d2); } namespace iDataHelper_Private { template void CICTemplate(bool periodic[3], int dims[3], double org[3], double spa[3], T pos[3], int ijk1[3], int ijk2[3], double d1[3], double d2[3]) { int i; for(i=0; i<3; i++) { d1[i] = (pos[i]-org[i])/spa[i]; ijk1[i] = (int)floor(d1[i]); d2[i] = d1[i] - ijk1[i]; d1[i] = 1.0 - d2[i]; if(periodic[i]) { while(ijk1[i] < 0) ijk1[i] += dims[i]; // in case it is extended while(ijk1[i] >= dims[i]) ijk1[i] -= dims[i]; } else { if(ijk1[i] < 0) ijk1[i] = 0; if(ijk1[i] >= dims[i]) ijk1[i] = dims[i] - 1; } ijk2[i] = ijk1[i] + 1; if(periodic[i]) { while(ijk2[i] >= dims[i]) ijk2[i] -= dims[i]; } else { if(ijk2[i] >= dims[i]) ijk2[i] = dims[i] - 1; } } } }; ifrit-3.4.2/core/idatahelper.h0000644000175700010010000000411712167404411014570 0ustar HomeNone/*========================================================================= Program: Ionization FRont Interactive Tool (IFRIT) Language: C++ Copyright (c) 2002-2012 Nick Gnedin All rights reserved. This file may be distributed and/or modified under the terms of the GNU General Public License version 2 as published by the Free Software Foundation and appearing in the file LICENSE.GPL included in the packaging of this file. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHORS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. =========================================================================*/ #ifndef IDATAHELPER_H #define IDATAHELPER_H class vtkDataSet; // // This is a small helper class, mostly responsible for providing the information about data. // class iDataHelper { public: iDataHelper(vtkDataSet *ds); virtual ~iDataHelper(); inline vtkDataSet* GetData() const { return mData; } unsigned int GetDataRank() const; virtual bool IsThereData() const; virtual bool IsThereScalarData() const; virtual bool IsThereVectorData() const; virtual bool IsThereTensorData() const; static void CIC(bool periodic[3], int dims[3], double org[3], double spa[3], float pos[3], int ijk1[3], int ijk2[3], double d1[3], double d2[3]); static void CIC(bool periodic[3], int dims[3], double org[3], double spa[3], double pos[3], int ijk1[3], int ijk2[3], double d1[3], double d2[3]); private: vtkDataSet *mData; }; #endif // IDATAHELPER_H ifrit-3.4.2/core/idatalimits.cpp0000755000175700010010000001647712167404427015173 0ustar HomeNone/*========================================================================= Program: Ionization FRont Interactive Tool (IFRIT) Language: C++ Copyright (c) 2002-2012 Nick Gnedin All rights reserved. This file may be distributed and/or modified under the terms of the GNU General Public License version 2 as published by the Free Software Foundation and appearing in the file LICENSE.GPL included in the packaging of this file. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHORS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. =========================================================================*/ // // Class containing data limits for a single DataSubject // #include "idatalimits.h" #include "idatastretch.h" #include "idatasubject.h" #include "ifileloader.h" #include "iviewmodule.h" // // templates // #include "iarraytemplate.h" using namespace iParameter; iDataLimits* iDataLimits::New(const iDataSubject *subject, int num, const iString &name) { IERROR_ASSERT(subject); return new iDataLimits(subject,num,name,true,false); } iDataLimits::iDataLimits(const iDataSubject *subject, int num, const iString &name, bool resizable, bool namesfixed) : mSubject(subject), mIsResizable(resizable), mAreNamesFixed(namesfixed), mMinNumListed(num) { IERROR_ASSERT(mSubject); if(num < 1) { IERROR_FATAL("Number of vars must be > 0."); } mNamePrefix = name; mBlockChecking = false; mBlockNotifications = true; // must block here to avoid a loop this->Configure(num); this->AssignVars(); // assign all when there is no data present mBlockNotifications = false; } iDataLimits::~iDataLimits() { } const iDataType& iDataLimits::GetDataType() const { return mSubject->GetDataType(); } void iDataLimits::Resize(int n) { if(mIsResizable) { if(n < mMinNumListed) n = mMinNumListed; this->Configure(n); } } void iDataLimits::BackupVars() { int i; mVarsBackup.Clear(); for(i=0; i 0) { while(mListedVars.Size() > num) { mVars.Remove(&mListedVars.Last()); mListedVars.RemoveLast(); } while(mListedVars.Size() < num) { Var tmp; tmp.Included = true; if(num > 1) { tmp.Name = mNamePrefix + " " + iString::FromNumber(mListedVars.Size()+1); } else { tmp.Name = mNamePrefix; } tmp.Stretch = 0; tmp.Min = 0.1f; tmp.Max = 10.0f; tmp.FixedStretch = false; tmp.Rank = 0; this->Initialize(tmp); mListedVars.Add(tmp); } } } void iDataLimits::ResetVars() { mVars.Clear(); } void iDataLimits::AssignVars(int n) { int i; bool bn = mBlockNotifications; if(!bn) mBlockNotifications = true; // // Try to adjust size // if(n>0 && n!=mListedVars.Size()) this->Resize(n); if(n<0 || n>mListedVars.Size()) n = mListedVars.Size(); this->ResetVars(); for(i=0; iAddVar(i); if(!bn) { mBlockNotifications = false; this->NotifyDependencies(-1); } } void iDataLimits::AddVar(int n) { if(n>=0 && nNotifyDependencies(mVars.MaxIndex()); } else this->Invalid(0); } int iDataLimits::Invalid(int v) const { if(!mBlockChecking) { IERROR_LOW("Invalid access to a DataLimits member."); } return v; } float iDataLimits::Invalid(float v) const { if(!mBlockChecking) { IERROR_LOW("Invalid access to a DataLimits member."); } return v; } const iString& iDataLimits::Invalid(const iString &v) const { if(!mBlockChecking) { IERROR_LOW("Invalid access to a DataLimits member"); } return v; } void iDataLimits::AdjustMinMax(Var &v) { if(!(v.Max > v.Min)) { float q = 0.5f*(v.Min+v.Max); if(q > 0.0f) { v.Min = q*0.99f; v.Max = q*1.01f; } else if(q < 0.0f) { v.Min = q*1.01f; v.Max = q*0.99f; } else { v.Min = -0.01f; v.Max = 0.01f; } } if(v.IsAtMax) v.UpperLimit = v.Max; if(v.IsAtMin) v.LowerLimit = v.Min; if(v.UpperLimit > v.Max) v.UpperLimit = v.Max; if(v.UpperLimit < v.Min) v.UpperLimit = v.Min; if(v.LowerLimit < v.Min) v.LowerLimit = v.Min; if(v.LowerLimit > v.Max) v.LowerLimit = v.Max; } void iDataLimits::SetMax(int n, float v) { if(n>=0 && nMax = v; this->AdjustMinMax(*mVars[n]); this->NotifyDependencies(n); } else this->Invalid(0); } void iDataLimits::SetMinMax(int n, float vMin, float vMax) { if(n>=0 && nMin = vMin; mVars[n]->Max = vMax; this->AdjustMinMax(*mVars[n]); this->NotifyDependencies(n); } else this->Invalid(0); } void iDataLimits::SetMin(int n, float v) { if(n>=0 && nMin = v; this->AdjustMinMax(*mVars[n]); this->NotifyDependencies(n); } else this->Invalid(0); } void iDataLimits::SetName(int n, const iString &v) { if(mAreNamesFixed) return; if(n>=0 && nName = v; this->NotifyDependencies(n); } else this->Invalid(0); } void iDataLimits::SetStretch(int n, int v) { if(n>=0 && n=0 && v<2) { if(!mVars[n]->FixedStretch) { mVars[n]->Stretch = v; this->NotifyDependencies(n); } } else this->Invalid(0); } void iDataLimits::SetUpperLimit(int n, float v) { this->UpdateUpperLimit(v,n,mVars[n]->LowerLimit,mVars[n]->UpperLimit); } void iDataLimits::SetLowerLimit(int n, float v) { this->UpdateLowerLimit(v,n,mVars[n]->LowerLimit,mVars[n]->UpperLimit); } void iDataLimits::UpdateUpperLimit(float v, int n, float &ll, float &ul) { if(n>=0 && nMin) v = mVars[n]->Min; if(v < mVars[n]->Max) { mVars[n]->IsAtMax = false; } else { v = mVars[n]->Max; mVars[n]->IsAtMax = true; } ul = v; if(v < ll) ll = v; this->NotifyDependencies(n); } else this->Invalid(0); } void iDataLimits::UpdateLowerLimit(float v, int n, float &ll, float &ul) { if(n>=0 && n mVars[n]->Max) v = mVars[n]->Max; if(v > mVars[n]->Min) { mVars[n]->IsAtMin = false; } else { v = mVars[n]->Min; mVars[n]->IsAtMin = true; } ll = v; if(v > ul) ul = v; this->NotifyDependencies(n); } else this->Invalid(0); } void iDataLimits::Initialize(Var &v) { v.LowerLimit = v.Min; v.UpperLimit = v.Max; v.IsAtMin = v.IsAtMax = true; } void iDataLimits::GetPeriodicities(bool per[3]) const { int i; for(i=0; i<3; i++) per[i] = mSubject->GetLoader()->IsDirectionPeriodic(i); } bool iDataLimits::IsBoxPeriodic() const { return mSubject->GetLoader()->IsBoxPeriodic(); } void iDataLimits::NotifyDependencies(int var) { if(!mBlockNotifications) { mSubject->GetViewModule()->NotifyDataConsumers(mSubject->Request(var)); } } ifrit-3.4.2/core/idatalimits.h0000755000175700010010000001307312167404411014616 0ustar HomeNone/*========================================================================= Program: Ionization FRont Interactive Tool (IFRIT) Language: C++ Copyright (c) 2002-2012 Nick Gnedin All rights reserved. This file may be distributed and/or modified under the terms of the GNU General Public License version 2 as published by the Free Software Foundation and appearing in the file LICENSE.GPL included in the packaging of this file. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHORS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. =========================================================================*/ #ifndef IDATALIMITS_H #define IDATALIMITS_H #include #include "iarray.h" #include "imath.h" #include "istring.h" #include class iDataSubject; class iDataType; class iDataLimits : public vtkObjectBase { friend class iDataSubject; public: vtkTypeMacro(iDataLimits,vtkObjectBase); static iDataLimits* New(const iDataSubject *subject = 0, int num = 0, const iString &name = ""); int GetNumVars() const; int GetStretch(int n) const; float GetMax(int n) const; float GetMin(int n) const; float GetUpperLimit(int n) const; float GetLowerLimit(int n) const; const iString& GetName(int n) const; const iString& GetUnit(int n) const; bool GetFixedStretch(int n) const; int GetRank(int n) const; const iString& GetNameForClass(int n) const; // GetClassName conflicts with something under VC++ void SetMax(int n, float v); void SetMin(int n, float v); void SetName(int n, const iString &v); void SetStretch(int n, int v); void SetUpperLimit(int n, float v); void SetLowerLimit(int n, float v); void ResetVars(); void AddVar(int n); void AssignVars(int n = -1); // add n first listed Vars void BackupVars(); void RestoreVars(); inline bool AreNamesFixed() const { return mAreNamesFixed; } const iDataType& GetDataType() const; // // Helper functions for using non-limits Lower & Upper Limits // void UpdateLowerLimit(float v, int n, float &ll, float &ul); void UpdateUpperLimit(float v, int n, float &ll, float &ul); // // Boundary conditions are set by the Subject // void GetPeriodicities(bool per[3]) const; bool IsBoxPeriodic() const; void BlockNotifications(bool b); // // Expandability // void Resize(int n); inline int GetSize() const { return mListedVars.Size(); } protected: iDataLimits(const iDataSubject *subject, int num, const iString &name, bool resizable, bool namesfixed); virtual ~iDataLimits(); struct Var { bool Included, FixedStretch; float Min, Max; float LowerLimit, UpperLimit; int Stretch, Rank; iString Name, Unit, ClassName; bool IsAtMin, IsAtMax; }; virtual void NotifyDependencies(int var); void Configure(int num); void Initialize(Var &v); void AdjustMinMax(Var &v); iString mNamePrefix; const iDataSubject *mSubject; iSearchableArray mVars, mVarsBackup; iArray mListedVars; bool mBlockNotifications; const bool mIsResizable, mAreNamesFixed; const int mMinNumListed; private: void SetMinMax(int n, float vMin, float vMax); // // For internal testing // int Invalid(int) const; float Invalid(float) const; const iString& Invalid(const iString &) const; bool mBlockChecking; }; inline int iDataLimits::GetNumVars() const { return mVars.Size(); } inline int iDataLimits::GetStretch(int n) const { if(n>=0 && nStretch; else return this->Invalid(0); } inline float iDataLimits::GetMax(int n) const { if(n>=0 && nMax; else return this->Invalid(iMath::_LargeFloat); } inline float iDataLimits::GetMin(int n) const { if(n>=0 && nMin; else return this->Invalid(-iMath::_LargeFloat); } inline float iDataLimits::GetUpperLimit(int n) const { if(n>=0 && nUpperLimit; else return this->Invalid(iMath::_LargeFloat); } inline float iDataLimits::GetLowerLimit(int n) const { if(n>=0 && nLowerLimit; else return this->Invalid(-iMath::_LargeFloat); } inline const iString& iDataLimits::GetName(int n) const { static const iString null; if(n>=0 && nName; else return this->Invalid(null); } inline const iString& iDataLimits::GetUnit(int n) const { static const iString null; if(n>=0 && nUnit; else return this->Invalid(null); } inline bool iDataLimits::GetFixedStretch(int n) const { if(n>=0 && nFixedStretch; else return (this->Invalid(0) == 0); } inline int iDataLimits::GetRank(int n) const { if(n>=0 && nRank; else return this->Invalid(-1); } inline const iString& iDataLimits::GetNameForClass(int n) const { static const iString null; if(n>=0 && nClassName; else return this->Invalid(null); } inline void iDataLimits::BlockNotifications(bool b) { mBlockNotifications = b; } #endif // IDATALIMITS_H ifrit-3.4.2/core/idatareader.cpp0000755000175700010010000004671212167404427015127 0ustar HomeNone/*========================================================================= Program: Ionization FRont Interactive Tool (IFRIT) Language: C++ Copyright (c) 2002-2012 Nick Gnedin All rights reserved. This file may be distributed and/or modified under the terms of the GNU General Public License version 2 as published by the Free Software Foundation and appearing in the file LICENSE.GPL included in the packaging of this file. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHORS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. =========================================================================*/ #include "iconfigure.h" #include "idatareader.h" #include "ibasicdatasubjects.h" #include "ibasicparticlesfileloader.h" #include "ibuffer.h" #include "icommoneventobservers.h" #include "icontrolmodule.h" #include "idata.h" #include "idatalimits.h" #include "idatasubject.h" #include "idirectory.h" #include "iedition.h" #include "ierror.h" #include "ierrorstatus.h" #include "ifile.h" #include "iobjectfactory.h" #include "iparallelmanager.h" #include "iparallelworker.h" #include "iuniformgriddata.h" #include "iuniformgridfileloader.h" #include "iviewmodule.h" #include // // Templates // #include "iarraytemplate.h" using namespace iParameter; // // Define static members // IOBJECT_DEFINE_TYPE(iDataReader,DataReader,dr,iObjectType::_Helper); IOBJECT_DEFINE_KEY(iDataReader,BoundaryConditions,bc,Int,1); IOBJECT_DEFINE_KEY(iDataReader,EraseData,e,String,1); IOBJECT_DEFINE_KEY(iDataReader,ErrorMessage,em,String,1); IOBJECT_DEFINE_KEY(iDataReader,IsSet,is,Bool,1); IOBJECT_DEFINE_KEY(iDataReader,LoadData,l,String,2); IOBJECT_DEFINE_KEY(iDataReader,ShiftData,s,Double,3); IOBJECT_DEFINE_KEY(iDataReader,ScaledDimension,sd,Int,1); IOBJECT_DEFINE_KEY(iDataReader,VoxelLocation,vl,Int,1); IOBJECT_DEFINE_KEY(iDataReader,RecordLength,-l,Int,1); // hidden key // // Main class // iDataReader* iDataReader::New(iViewModule* vm) { int i, j, k; IERROR_ASSERT(vm); iDataReader *tmp = new iDataReader(vm); IERROR_ASSERT(tmp); iObjectFactory::InstallExtensions(tmp); iFileLoader *s; for(i=0; imExtensions.Size(); i++) { j = 0; while((s = iRequiredCast(INFO,tmp->mExtensions[i])->GetLoader(j++)) != 0) { for(k=0; kNumStreams(); k++) { iEdition::ApplySettings(s->GetStream(k)->Subject,s->GetStream(k)->Subject->GetObjectType()); } tmp->mLoaders.Add(s); } } iEdition::ApplySettings(tmp,iDataReader::Type()); return tmp; } iDataReader::iDataReader(iViewModule *vm) : iExtendableObject("Data Reader"), mViewModule(vm) { mRecordLength = 4; mTwoCopies = mInExtensionUpdate = false; mCellToPointMode = 2; mVoxelLocation = VoxelLocation::Vertex; mBoundaryConditions = BoundaryConditions::Wall; mUniformVectorsLoader = new iUniformVectorsFileLoader(this); IERROR_ASSERT(mUniformVectorsLoader); mUniformScalarsLoader = new iUniformScalarsFileLoader(this,mUniformVectorsLoader); IERROR_ASSERT(mUniformScalarsLoader); mUniformTensorsLoader = new iUniformTensorsFileLoader(this); IERROR_ASSERT(mUniformTensorsLoader); mBasicParticlesLoader = new iBasicParticlesFileLoader(this); IERROR_ASSERT(mBasicParticlesLoader); iUniformScalarsDataSubject *us = new iUniformScalarsDataSubject(mUniformScalarsLoader); IERROR_ASSERT(us); iUniformVectorsDataSubject *uv = new iUniformVectorsDataSubject(mUniformVectorsLoader); IERROR_ASSERT(uv); iUniformTensorsDataSubject *ut = new iUniformTensorsDataSubject(mUniformTensorsLoader); IERROR_ASSERT(ut); iBasicParticlesDataSubject *bp = new iBasicParticlesDataSubject(mBasicParticlesLoader); IERROR_ASSERT(bp); iEdition::ApplySettings(us,us->GetObjectType()); iEdition::ApplySettings(uv,uv->GetObjectType()); iEdition::ApplySettings(ut,ut->GetObjectType()); iEdition::ApplySettings(bp,bp->GetObjectType()); mLoaders.Add(mUniformScalarsLoader); mLoaders.Add(mUniformVectorsLoader); mLoaders.Add(mUniformTensorsLoader); mLoaders.Add(mBasicParticlesLoader); mCurrentRecord = -1; mPeriodicityLeader = 0; mDataShift[0] = mDataShift[1] = mDataShift[2] = 0.0f; mScaledDim = -1; //max dim // mLastFileName = mLastAttemptedFileName = ""; mDirectory = new iDirectory; IERROR_ASSERT(mDirectory); } iDataReader::~iDataReader() { int i; delete mDirectory; for(i=0; iDelete(); } bool iDataReader::IsAborted(const iDataType &type) const { int i; for(i=0; iIsUsingData(type) && mLoaders[i]->IsAborted()) return true; } return false; } void iDataReader::EraseData(const iDataType &type) { int i; for(i=0; iIsUsingData(type) && mLoaders[i]->IsThereData(type)) mLoaders[i]->EraseData(); } this->ClearCache(); } void iDataReader::SetTwoCopies(bool s) { int i; if(mTwoCopies != s) { mTwoCopies = s; for(i=0; iSetTwoCopies(s); } this->ClearCache(); } } void iDataReader::ReloadData(const iDataType &type) { int i; this->GetErrorStatus()->Clear(); for(i=0; this->GetErrorStatus()->NoError() && iIsUsingData(type) && mLoaders[i]->IsThereData(type)) { this->GetErrorStatus()->Monitor(mLoaders[i]->GetErrorStatus()); mLoaders[i]->ReadFile(mLoaders[i]->GetLastFileName()); if(mLoaders[i]->GetObserver()->IsAborted()) this->GetErrorStatus()->SetAbort(); if(this->GetErrorStatus()->NoError()) mLoaders[i]->Finalize(); if(mLoaders[i]->GetObserver()->IsAborted()) this->GetErrorStatus()->SetAbort(); if(this->GetErrorStatus()->NoError()) mLoaders[i]->ShiftData(mDataShift); if(mLoaders[i]->GetObserver()->IsAborted()) this->GetErrorStatus()->SetAbort(); if(this->GetErrorStatus()->IsError()) { mLoaders[i]->EraseData(); this->ClearCache(); } } } } void iDataReader::ResetPipeline() { int i; for(i=0; iReset(); } this->ClearCache(); } bool iDataReader::IsThereData(const iDataInfo &info) const { int i; for(i=0; iIsThereData(info.Type(i))) return true; } return false; } bool iDataReader::IsThereData(const iDataType &type) const { int i; for(i=0; iIsUsingData(type) && mLoaders[i]->IsThereData(type)) return true; } return false; } const iString& iDataReader::GetLastFileName(const iDataType &type) const { static const iString null; int i; for(i=0; iIsUsingData(type)) return mLoaders[i]->GetLastFileName(); } return null; } iDataLimits* iDataReader::GetLimits(const iDataType &type) const { int i; for(i=0; iIsUsingData(type)) return mLoaders[i]->GetSubject(type)->GetLimits(); } return 0; } iDataSubject* iDataReader::GetSubject(const iDataType &type) const { int i; for(i=0; iIsUsingData(type)) return mLoaders[i]->GetSubject(type); } return 0; } bool iDataReader::IsSetLeader(const iFileLoader *loader) const { return (mSetLoaders.Size()>0 && mSetLoaders[0]==loader); } void iDataReader::LoadFile(const iDataType &type, const iString &fname, bool dryrun, bool savename) { int i; this->GetErrorStatus()->Clear(); // // Find a loader that accepts this type. // for(i=0; iIsUsingData(type)) { this->LoadFile(mLoaders[i],fname,dryrun,savename); return; } } this->GetErrorStatus()->Set("There is no loader that supports this data type."); } void iDataReader::LoadFile(iFileLoader *loader, const iString &name, bool dryrun, bool savename) { int i; this->ClearCache(); if(loader == 0) { this->GetErrorStatus()->Set("Trying to load file by a non-existent loader."); return; } iString fname(name); iDirectory::ExpandFileName(fname); mLastAttemptedFileName = fname; if(dryrun) { if(!iFile::IsReadable(fname)) this->GetErrorStatus()->Set("File does not exist."); return; } else { this->GetErrorStatus()->Monitor(loader->GetErrorStatus()); loader->ReadFile(fname); if(this->GetErrorStatus()->IsError()) { if(!mTwoCopies) loader->EraseData(); // mark data as absent if we keep only one copy return; } } iString root, suffix; int newrec = loader->DissectFileName(fname,root,suffix); // // Update the set // if(newrec >= 0) { if(newrec == mCurrentRecord) { // // Adding to the existent set if the subject is not there yet // if(mSetLoaders.Find(loader) < 0) mSetLoaders.Add(loader); } else { if(savename) this->InsertIntoVisitedFilesList(loader,fname); // // Re-establish the set if we are not loading a new one // if(!this->IsSetLeader(loader)) { this->BreakSet(); mSetLoaders.Add(loader); } mCurrentRecord = newrec; } } else { if(this->IsSetLeader(loader)) { this->BreakSet(); } if(savename) this->InsertIntoVisitedFilesList(loader,fname); } if(mPeriodicityLeader==0 || loader->GetPriority()GetPriority()) mPeriodicityLeader = loader; mLastFileName = fname; if(dryrun) return; // we are done in that case // // Do we have a set? If yes, load the rest of it too // if(this->IsSetLeader(loader)) { // //Is the filename consistent? // if(!mSetLoaders[0]->IsSeriesFileName(fname)) { this->BreakSet(); } else { // // Load the data // for(i=1; this->GetErrorStatus()->NoError() && iGetErrorStatus()->Monitor(mSetLoaders[i]->GetErrorStatus()); mSetLoaders[i]->ReadFile(mSetLoaders[i]->GetFileName(newrec)); if(this->GetErrorStatus()->IsError() && !mTwoCopies) mSetLoaders[i]->EraseData(); // mark data as absent if we keep only one copy } } } this->GetViewModule()->GetParallelManager()->StartCounters(); // // Finish updating the data // loader->Finalize(); if(loader->GetObserver()->IsAborted()) { loader->EraseData(); this->GetErrorStatus()->SetAbort(); } if(this->IsSetLeader(loader)) { for(i=1; this->GetErrorStatus()->NoError() && iFinalize(); if(mSetLoaders[i]->GetObserver()->IsAborted()) { mSetLoaders[i]->EraseData(); this->GetErrorStatus()->SetAbort(); } } } // // Shift the data // loader->ShiftData(mDataShift); if(loader->GetObserver()->IsAborted()) { loader->EraseData(); this->GetErrorStatus()->SetAbort(); } if(this->IsSetLeader(loader)) { for(i=1; this->GetErrorStatus()->NoError() && iShiftData(mDataShift); if(mSetLoaders[i]->GetObserver()->IsAborted()) { mSetLoaders[i]->EraseData(); this->GetErrorStatus()->SetAbort(); } } } this->GetViewModule()->GetParallelManager()->StopCounters(); this->GetViewModule()->UpdateAfterFileLoad(); // // If this loader has an extension, ask it do to its share of work, but guard against loops if it calls this function // if(loader->GetReaderExtension() != 0) { if(mInExtensionUpdate) return; mInExtensionUpdate = true; loader->GetReaderExtension()->AfterLoadFile(loader,fname,dryrun); mInExtensionUpdate = false; } } void iDataReader::BreakSet() { mCurrentRecord = -1; mSetLoaders.Clear(); mDirectory->Close(); this->ClearCache(); } void iDataReader::LoadRecord(int rec, int skip, bool dryrun, bool savename) { if(rec < 0) rec = mCurrentRecord; this->GetErrorStatus()->Clear(); this->ClearCache(); if(mSetLoaders.Size() == 0) { this->GetErrorStatus()->Set("File set has not been established."); return; } iString fname = mSetLoaders[0]->GetFileName(rec); if(!iFile::IsReadable(fname)) { this->GetErrorStatus()->Set("File is not accessible."); return; } if(skip != 0) { if(!mDirectory->IsOpened() && !mDirectory->Open(fname)) { this->GetErrorStatus()->Set("Unable to read the directory."); return; } while(skip>0 && !fname.IsEmpty()) { fname = mDirectory->GetFile(fname,1); if(this->IsAnotherSetLeader(fname)) skip--; } // // Is this filename from the same series? // if(!this->IsAnotherSetLeader(fname)) { this->GetErrorStatus()->Set("File does not exist.",10); return; } } if(!fname.IsEmpty()) { this->LoadFile(mSetLoaders[0],fname,dryrun,savename); } else { this->GetErrorStatus()->Set("File does not exist.",10); } } const iDataType& iDataReader::GetFileSetDataType(int member) const { if(member<0 || member>=mSetLoaders.Size()) { return iDataType::Null(); } else { return mSetLoaders[member]->GetDataType(0); } } const iString& iDataReader::GetLastFileSetName() const { static const iString none; if(mSetLoaders.Size() == 0) return none; else return mSetLoaders[0]->GetLastFileName(); } const iString iDataReader::GetFileSetName(int rec) const { static const iString none; if(mSetLoaders.Size()>0 && rec>=0) return mSetLoaders[0]->GetFileName(rec); else return none; } const iString iDataReader::GetFileSetRoot() const { static const iString none; if(mSetLoaders.Size() > 0) return mSetLoaders[0]->GetFileRoot(); else return none; } bool iDataReader::IsCurrentSetMember(const iString &fname) const { int i; for(i=0; iGetLastFileName() == fname) return true; } return false; } bool iDataReader::IsAnotherSetLeader(const iString &fname) const { if(mSetLoaders.Size() > 0) { return mSetLoaders[0]->IsSeriesFileName(fname); } else return false; } void iDataReader::SetDataShift(int d, double dx) { if(d>=0 && d<=2) mDataShift[d] = dx; this->ClearCache(); } void iDataReader::ShiftData(double *dr) { int i; if(dr == 0) dr = mDataShift; this->GetViewModule()->GetParallelManager()->StartCounters(); for(i=0; iIsThereData()) { mLoaders[i]->ShiftData(dr); } this->GetViewModule()->GetParallelManager()->StopCounters(); } float iDataReader::GetMemorySize() const { int i; float s = 0.0; for(i=0; iGetMemorySize(); } return s; } void iDataReader::ExtendableObjectPackStateBody(iString &s) const { this->PackValue(s,KeyScaledDimension(),mScaledDim); this->PackValue(s,KeyVoxelLocation(),mVoxelLocation); this->PackValue(s,KeyBoundaryConditions(),mBoundaryConditions); this->PackValue(s,KeyShiftData(),mDataShift,3); // // Hidden key // this->PackValue(s,KeyRecordLength(),mRecordLength); // // Special "query" keys // this->PackValue(s,KeyErrorMessage(),this->GetErrorStatus()->Message()); this->PackValue(s,KeyIsSet(),this->IsSet()); } void iDataReader::ExtendableObjectUnPackStateBody(const iString &s) { int i; double ds[3]; iString s1; if(this->UnPackValue(s,KeyScaledDimension(),i)) this->SetScaledDimension(i); if(this->UnPackValue(s,KeyVoxelLocation(),i)) this->SetVoxelLocation(i); if(this->UnPackValue(s,KeyBoundaryConditions(),i)) this->SetBoundaryConditions(i); for(i=0; i<3; i++) ds[i] = mDataShift[i]; if(this->UnPackValue(s,KeyShiftData(),ds,3)) { for(i=0; i<3; i++) this->SetDataShift(i,ds[i]); this->ShiftData(); } // // Hidden key // iObject::ReportMissingKeys(false); if(this->UnPackValue(s,KeyRecordLength(),i)) { mRecordLength = i; this->ClearCache(); } iObject::ReportMissingKeys(true); // // Special "action" keys // iObject::ReportMissingKeys(false); //action keys are not part of the states if(this->UnPackValue(s,KeyEraseData(),s1)) { const iDataType &type(iDataType::FindTypeByName(s1)); if(!type.IsNull()) { this->EraseData(type); } } iString ws[2]; if(this->UnPackValue(s,KeyLoadData(),ws,2)) { const iDataType &type(iDataType::FindTypeByName(ws[0])); if(type.IsNull()) { mUnPackedSomething = false; } else { iDirectory::ExpandFileName(ws[1],type.GetEnvironment(this->GetViewModule()->GetControlModule()->GetShell())); this->LoadFile(type,ws[1]); } } iObject::ReportMissingKeys(true); } void iDataReader::PackCompleteState(iString &s) const { int i, k; iString s1; this->PackState(s); // // Pack all subjects for state saving // for(i=0; iNumStreams(); k++) { mLoaders[i]->GetSubject(k)->PackCompleteState(s1); s += iObjectKey::SpecialSeparator() + mLoaders[i]->GetSubject(k)->GetDataType().GetName() + iObjectKey::Delimiter() + s1; } } } void iDataReader::UnPackCompleteState(const iString &s) { int i, j, k, n; iString s1, name; this->UnPackState(s); // // UnPack all subjects for state restoring // n = s.Contains(iObjectKey::SpecialSeparator()); for(j=0; jNumStreams(); k++) if(mLoaders[i]->GetSubject(k)->GetDataType().IsOfType(name)) { mLoaders[i]->GetSubject(k)->UnPackCompleteState(s1); } } } } void iDataReader::InsertIntoVisitedFilesList(const iFileLoader *loader, const iString &name) { VisitedFile v; v.Name = name; v.Loader = loader; mVisitedFilesList.Add(v); } iProgressEventObserver* iDataReader::GetProgressEventObserver(const iDataType &type) { int i; for(i=0; iIsUsingData(type)) return mLoaders[i]->GetObserver(); } return 0; } // // Outputs // vtkDataSet* iDataReader::GetData(const iDataType &type) const { int i; for(i=0; iIsUsingData(type)) { return mLoaders[i]->GetData(type); } } return 0; } // // Decorator functions // void iDataReader::SetBoundaryConditions(int v) { int i; if(BoundaryConditions::IsValid(v)) { mBoundaryConditions = v; for(i=0; iSetBoundaryConditions(v); } this->ClearCache(); } } // void iDataReader::SetScaledDimension(int v) { int i; iUniformGridFileLoader *ds; for(i=0; iSetScaledDimension(v); mScaledDim = ds->GetScaledDimension(); } } this->ClearCache(); } // void iDataReader::SetVoxelLocation(int v) { int i; iUniformGridFileLoader *ds; for(i=0; iSetVoxelLocation(v); mVoxelLocation = ds->GetVoxelLocation(); } } this->ClearCache(); } // // Extension // IOBJECTEXTENSION_DEFINE_ABSTRACT(iDataReader); void iDataReaderExtension::Define() { } void iDataReaderExtension::AfterLoadFile(iFileLoader *loader, const iString &fname, bool dryrun) { if(loader->GetReaderExtension() != this) { IERROR_HIGH("iDataReaderExtension is configured incorrectly."); return; } mLastFileName = fname; this->AfterLoadFileBody(loader,fname,dryrun); } void iDataReaderExtension::AfterLoadFileBody(iFileLoader *, const iString &, bool) { // // By default do nothing // } ifrit-3.4.2/core/idatareader.h0000755000175700010010000001503512167404411014557 0ustar HomeNone/*========================================================================= Program: Ionization FRont Interactive Tool (IFRIT) Language: C++ Copyright (c) 2002-2012 Nick Gnedin All rights reserved. This file may be distributed and/or modified under the terms of the GNU General Public License version 2 as published by the Free Software Foundation and appearing in the file LICENSE.GPL included in the packaging of this file. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHORS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. =========================================================================*/ #ifndef IDATAREADER_H #define IDATAREADER_H #include "iextendableobject.h" #include "iarray.h" class iBasicParticlesFileLoader; class iDataInfo; class iDataLimits; class iDataReaderHelper; class iDataSubject; class iDataType; class iDirectory; class iFile; class iFileLoader; class iProgressEventObserver; class iUniformScalarsFileLoader; class iUniformVectorsFileLoader; class iUniformTensorsFileLoader; class vtkDataSet; class vtkPolyData; class vtkStructuredPoints; class iDataReader : public iExtendableObject { friend class iDataReaderHelper; IPOINTER_AS_PART(ViewModule); public: struct VisitedFile { iString Name; const iFileLoader *Loader; }; vtkTypeMacro(iDataReader,iExtendableObject); static iDataReader* New(iViewModule *vm = 0); static const iObjectType& Type(); // // Non-static members // IOBJECT_DECLARE_GETSET(ScaledDimension,mScaledDim,int); //virtual void SetScaledDimension(int v); //inline int GetScaledDimension() const { return mScaledDim; } IOBJECT_DECLARE_GETSET1(VoxelLocation,int); //virtual void SetVoxelLocation(int s); //inline bool GetVoxelLocation() const { return mVoxelLocation; } IOBJECT_DECLARE_GETSET1(BoundaryConditions,int); //virtual void SetBoundaryConditions(int s); //inline int GetBoundaryConditions() const { return mBoundaryConditions; } void SetDataShift(int d, double f); inline double GetDataShift(int d) const { if(d>=0 && d<3) return mDataShift[d]; else return 0.0; } static const iObjectKey& KeyShiftData(); // // Special "action" keys // static const iObjectKey& KeyEraseData(); static const iObjectKey& KeyLoadData(); // // Special "query" keys // static const iObjectKey& KeyErrorMessage(); inline bool IsSet() const { return mSetLoaders.Size() > 0; } static const iObjectKey& KeyIsSet(); // // Loading of data // void LoadFile(const iDataType &type, const iString &fname, bool dryrun = false, bool savename = true); void LoadRecord(int rec, int skip = 0, bool dryrun = false, bool savename = false); // // Operation on data // bool IsThereData(const iDataType &type) const; bool IsThereData(const iDataInfo &info) const; void EraseData(const iDataType &type); void ReloadData(const iDataType &type); void SetTwoCopies(bool s); void ResetPipeline(); iDataSubject* GetSubject(const iDataType &type) const; iDataLimits* GetLimits(const iDataType &type) const; // // Generic GetData // vtkDataSet* GetData(const iDataType &type) const; inline bool IsFileAnimatable() const { return (mCurrentRecord >= 0); } inline int GetRecordNumber() const { return mCurrentRecord; } virtual void ShiftData(double *dx = 0); virtual float GetMemorySize() const; // // Functions for file manipulation // const iString& GetLastFileSetName() const; bool IsAnotherSetLeader(const iString &fname) const; bool IsCurrentSetMember(const iString &fname) const; const iString GetFileSetName(int rec) const; const iString GetFileSetRoot() const; const iDataType& GetFileSetDataType(int member = 0) const; const iString& GetLastFileName(const iDataType &type) const; inline const iString& GetLastFileName() const { return mLastFileName; } inline const iString& GetLastAttemptedFileName() const { return mLastAttemptedFileName; } inline const iArray& GetVisitedFilesList() const { return mVisitedFilesList; } virtual iProgressEventObserver* GetProgressEventObserver(const iDataType &type); virtual void PackCompleteState(iString &s) const; virtual void UnPackCompleteState(const iString &s); // // Hidden (undocumented) keys // static const iObjectKey& KeyRecordLength(); inline int GetRecordLength() const { return mRecordLength; } protected: virtual ~iDataReader(); virtual void ExtendableObjectPackStateBody(iString &s) const; virtual void ExtendableObjectUnPackStateBody(const iString &s); private: iDataReader(iViewModule *vm); void LoadFile(iFileLoader *loader, const iString &fname, bool dryrun, bool savename); void InsertIntoVisitedFilesList(const iFileLoader *loader, const iString &name); void BreakSet(); bool IsAborted(const iDataType &type) const; bool IsSetLeader(const iFileLoader *loader) const; bool mTwoCopies, mInExtensionUpdate; int mCellToPointMode; double mDataShift[3]; iString mMode; int mScaledDim, mVoxelLocation, mBoundaryConditions; iFileLoader *mPeriodicityLeader; iSearchableArray mSetLoaders; iArray mLoaders; iUniformScalarsFileLoader *mUniformScalarsLoader; iUniformVectorsFileLoader *mUniformVectorsLoader; iUniformTensorsFileLoader *mUniformTensorsLoader; iBasicParticlesFileLoader *mBasicParticlesLoader; int mCurrentRecord, mRecordLength; iString mLastFileName, mLastAttemptedFileName; iArray mVisitedFilesList; iDirectory *mDirectory; }; class iDataReaderExtension : public iObjectExtension { IOBJECTEXTENSION_DECLARE_ABSTRACT(iDataReader); public: inline iDataReader* GetReader() const { return mRealOwner; } virtual iFileLoader* GetLoader(int n) const = 0; // // It is a good idea to keep track of the last file read. // inline const iString& GetLastFileName() const { return mLastFileName; } void AfterLoadFile(iFileLoader *loader, const iString &fname, bool dryrun); protected: virtual void AfterLoadFileBody(iFileLoader *loader, const iString &fname, bool dryrun); iString mLastFileName; }; #endif ifrit-3.4.2/core/idatastretch.cpp0000644000175700010010000000324512167404430015322 0ustar HomeNone/*========================================================================= Program: Ionization FRont Interactive Tool (IFRIT) Language: C++ Copyright (c) 2002-2012 Nick Gnedin All rights reserved. This file may be distributed and/or modified under the terms of the GNU General Public License version 2 as published by the Free Software Foundation and appearing in the file LICENSE.GPL included in the packaging of this file. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHORS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. =========================================================================*/ #include "idatastretch.h" #include "istring.h" namespace iDataStretch { const iString& GetStretchNames() { static const iString tmp("Linear,Logarithmic"); return tmp; } }; iDataStretchUser::iDataStretchUser() { mStretch = iDataStretch::Linear; } iDataStretchUser::~iDataStretchUser() { } void iDataStretchUser::SetStretch(int s) { if(s>=0 && s<2 && s!=mStretch) { mStretch = s; this->OnStretchChanged(); } } ifrit-3.4.2/core/idatastretch.h0000755000175700010010000000604212167404411014767 0ustar HomeNone/*========================================================================= Program: Ionization FRont Interactive Tool (IFRIT) Language: C++ Copyright (c) 2002-2012 Nick Gnedin All rights reserved. This file may be distributed and/or modified under the terms of the GNU General Public License version 2 as published by the Free Software Foundation and appearing in the file LICENSE.GPL included in the packaging of this file. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHORS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. =========================================================================*/ #ifndef IDATASTRETCH_H #define IDATASTRETCH_H #include "imath.h" class iString; namespace iDataStretch { const int Linear = 0; const int Log = 1; template T ApplyStretch(T f, int mode, bool up); template T ResetStretch(T f, int mode); const iString& GetStretchNames(); }; class iDataStretchUser { public: void SetStretch(int s); inline int GetStretch() const { return mStretch; } float ApplyStretch(float f, bool up) const; float ResetStretch(float f) const; double ApplyStretch(double f, bool up) const; double ResetStretch(double f) const; protected: iDataStretchUser(); virtual ~iDataStretchUser(); virtual void OnStretchChanged(){} private: int mStretch; // use Set/GetStretch for access }; inline float iDataStretchUser::ApplyStretch(float f, bool up) const { return iDataStretch::ApplyStretch(f,mStretch,up); } inline float iDataStretchUser::ResetStretch(float f) const { return iDataStretch::ResetStretch(f,mStretch); } inline double iDataStretchUser::ApplyStretch(double f, bool up) const { return iDataStretch::ApplyStretch(f,mStretch,up); } inline double iDataStretchUser::ResetStretch(double f) const { return iDataStretch::ResetStretch(f,mStretch); } // // stretch and restore the data // namespace iDataStretch { template inline T ApplyStretch(T f, int mode, bool up) { const T zero = (T)0.0; const T tiny = (T)1.0e-36; const T invalid = (T)36.0; switch(mode) { case Log: { if(f > zero) { return log10(tiny+f); } else { return (up ? invalid : -invalid); } break; } default: return f; } } template inline T ResetStretch(T f, int mode) { switch(mode) { case Log: { return pow10(f); break; } default: return f; } } }; #endif // IDATASTRETCH_H ifrit-3.4.2/core/idatasubject.cpp0000755000175700010010000002066012167404430015310 0ustar HomeNone/*========================================================================= Program: Ionization FRont Interactive Tool (IFRIT) Language: C++ Copyright (c) 2002-2012 Nick Gnedin All rights reserved. This file may be distributed and/or modified under the terms of the GNU General Public License version 2 as published by the Free Software Foundation and appearing in the file LICENSE.GPL included in the packaging of this file. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHORS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. =========================================================================*/ #include "idatasubject.h" #include "ibuffer.h" #include "idata.h" #include "idataconsumer.h" #include "idatalimits.h" #include "idatareader.h" #include "ifileloader.h" #include "ierror.h" #include "ihistogrammaker.h" #include "iprobefilter.h" // // Templates // #include "iarraytemplate.h" #include "ibuffertemplate.h" IOBJECT_DEFINE_TYPE(iDataSubject,Data,-d,iObjectType::_Data); IOBJECT_DEFINE_KEY(iDataSubject,DataPresent,dp,Bool,1); IOBJECT_DEFINE_KEY(iDataSubject,FixedLimits,fl,Bool,1); IOBJECT_DEFINE_KEY(iDataSubject,FileName,fn,String,1); IOBJECT_DEFINE_KEY(iDataSubject,FixedStretch,fs,Bool,0); IOBJECT_DEFINE_KEY(iDataSubject,LowerLimit,lo,Float,0); IOBJECT_DEFINE_KEY(iDataSubject,Max,max,Float,0); IOBJECT_DEFINE_KEY(iDataSubject,Min,min,Float,0); IOBJECT_DEFINE_KEY(iDataSubject,NumVars,n,Int,1); IOBJECT_DEFINE_KEY(iDataSubject,Name,na,String,0); IOBJECT_DEFINE_KEY(iDataSubject,Stretch,s,Int,0); IOBJECT_DEFINE_KEY(iDataSubject,UpperLimit,up,Float,0); IOBJECT_DEFINE_KEY(iDataSubject,ResizeLimits,-rl,Int,1); // hidden key bool iDataSubject::IsTypeMatch(const iString &prefix) { iString pre = prefix.Section("-",0,0); if(pre == "d") return true; else return iDataSubject::Type().IsMatch(pre); } iString iDataSubject::GetDataSubjectName(const iString &prefix) { static iString none; // // Set the subject name // int i1 = prefix.Find("-"); if(i1 < 0) return none; int i2 = prefix.Find(iObjectKey::PrefixSeparator()); if(i2 < 0) i2 = prefix.Length(); return prefix.Part(i1+1,i2-i1-1); } iDataSubject::iDataSubject(iFileLoader *fl, const iString &name) : iObject(name), mViewModule(fl?fl->GetReader()->GetViewModule():0), mId(fl?fl->NumStreams():-1) { IERROR_ASSERT(fl); mLoader = fl; // // Add self as a new stream // iFileLoader::Stream *s = fl->CreateNewStream(); IERROR_ASSERT(s); s->Subject = this; fl->mStreams.Add(s); mLimits = 0; mFixedLimits = false; mLimitsNum = 1; mLimitsName = "Component"; } iDataSubject::~iDataSubject() { if(mLimits != 0) mLimits->Delete(); } const iObjectType& iDataSubject::GetObjectType() const { return iDataSubject::Type(); } iDataLimits* iDataSubject::CreateLimits() const { return iDataLimits::New(this,mLimitsNum,mLimitsName); } void iDataSubject::ConfigureLimits(int num, const iString &name) { if(num > 0) mLimitsNum = num; mLimitsName = name; } bool iDataSubject::IsThereData() const { return mLoader->IsThereData(mId); } vtkDataSet* iDataSubject::GetData() const { return mLoader->GetData(mId); } iDataLimits* iDataSubject::GetLimits() const { if(mLimits == 0) { mLimits = this->CreateLimits(); } return mLimits; } void iDataSubject::NotifyDependencies() { // // Default implementation, but can be changed in a child // this->GetLimits()->NotifyDependencies(-1); } void iDataSubject::SetFixedLimits(bool s) { mFixedLimits = s; this->ClearCache(); } void iDataSubject::PackCompleteState(iString &s) const { iDataLimits *limits = this->GetLimits(); // // Save the currently loaded Vars // limits->BackupVars(); limits->BlockNotifications(true); limits->AssignVars(); limits->BlockNotifications(false); // // Pack state without caching // s.Clear(); this->PackValue(s,KeyResizeLimits(),limits->GetSize()); this->PackStateBody(s); // // Restore the currently loaded Vars // limits->RestoreVars(); } void iDataSubject::UnPackCompleteState(const iString &s) { iDataLimits *limits = this->GetLimits(); // // Save the currently loaded Vars // if(this->IsThereData()) { limits->BackupVars(); } // // Unpack state and clear the cache // this->UnPackStateBody(s); this->ClearCache(); // // Restore the currently loaded Vars // if(this->IsThereData()) { limits->RestoreVars(); } } void iDataSubject::PackStateBody(iString &s) const { static iBuffer itmp; static iBuffer btmp; static iBuffer ftmp; static iBuffer stmp; int i, n; iDataLimits *limits = this->GetLimits(); this->PackValue(s,KeyFixedLimits(),mFixedLimits); this->PackValue(s,KeyDataPresent(),this->IsThereData()); this->PackValue(s,KeyFileName(),mLoader->GetLastFileName()); n = limits->GetNumVars(); this->PackValue(s,KeyNumVars(),n); if(n > 0) { for(i=0; iGetStretch(i); this->PackValue(s,KeyStretch(),itmp,n); for(i=0; iGetMin(i); this->PackValue(s,KeyMin(),ftmp,n); for(i=0; iGetMax(i); this->PackValue(s,KeyMax(),ftmp,n); for(i=0; iGetLowerLimit(i); this->PackValue(s,KeyLowerLimit(),ftmp,n); for(i=0; iGetUpperLimit(i); this->PackValue(s,KeyUpperLimit(),ftmp,n); for(i=0; iGetFixedStretch(i); this->PackValue(s,KeyFixedStretch(),btmp,n); for(i=0; iGetName(i); this->PackValue(s,KeyName(),stmp,n); } this->DataSubjectPackStateBody(s); } void iDataSubject::UnPackStateBody(const iString &s) { static iBuffer itmp; static iBuffer ftmp, ftmp2; static iBuffer stmp; int i, n; bool b; iDataLimits *limits = this->GetLimits(); limits->BlockNotifications(true); if(this->UnPackValue(s,KeyResizeLimits(),n)) { limits->Resize(n); if(!this->IsThereData()) limits->AssignVars(); this->ClearCache(); } if(this->UnPackValue(s,KeyFixedLimits(),b)) this->SetFixedLimits(b); n = limits->GetNumVars(); if(this->UnPackValue(s,KeyNumVars(),n)) { this->ClearCache(); n = limits->GetNumVars(); } if(n > 0) { for(i=0; iGetStretch(i); if(this->UnPackValue(s,KeyStretch(),itmp,n)) { for(i=0; iSetStretch(i,itmp[i]); this->ClearCache(); } for(i=0; iGetMin(i); if(this->UnPackValue(s,KeyMin(),ftmp,n)) { for(i=0; iGetMax(i); if(this->UnPackValue(s,KeyMax(),ftmp2,n)) { for(i=0; iSetMinMax(i,ftmp[i],ftmp2[i]); this->ClearCache(); } else { for(i=0; iSetMin(i,ftmp[i]); this->ClearCache(); } } else { for(i=0; iGetMax(i); if(this->UnPackValue(s,KeyMax(),ftmp,n)) { for(i=0; iSetMax(i,ftmp[i]); this->ClearCache(); } } for(i=0; iGetLowerLimit(i); if(this->UnPackValue(s,KeyLowerLimit(),ftmp,n)) { for(i=0; iSetLowerLimit(i,ftmp[i]); this->ClearCache(); } for(i=0; iGetUpperLimit(i); if(this->UnPackValue(s,KeyUpperLimit(),ftmp,n)) { for(i=0; iSetUpperLimit(i,ftmp[i]); this->ClearCache(); } for(i=0; iGetName(i); if(this->UnPackValue(s,KeyName(),stmp,n)) { for(i=0; iSetName(i,stmp[i]); this->ClearCache(); } } this->DataSubjectUnPackStateBody(s); limits->BlockNotifications(false); limits->NotifyDependencies(-1); } iProbeFilter* iDataSubject::CreateProbeFilter(iViewSubject *vo) const { return iProbeFilter::New(vo); } iHistogramMaker* iDataSubject::CreateHistogramMaker() const { return iHistogramMaker::New(this->GetViewModule()); } const iDataSyncRequest& iDataSubject::Request(int var) const { return iDataConsumer::Request(this->GetDataType(),var); } ifrit-3.4.2/core/idatasubject.h0000755000175700010010000001527112167404411014756 0ustar HomeNone/*========================================================================= Program: Ionization FRont Interactive Tool (IFRIT) Language: C++ Copyright (c) 2002-2012 Nick Gnedin All rights reserved. This file may be distributed and/or modified under the terms of the GNU General Public License version 2 as published by the Free Software Foundation and appearing in the file LICENSE.GPL included in the packaging of this file. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHORS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. =========================================================================*/ // // A base class for all DataSubjects. One DataSubject provides data for a single unique DataType. // #ifndef IDATASUBJECT_H #define IDATASUBJECT_H #include "iobject.h" class iDataLimits; class iDataSyncRequest; class iDataType; class iFileLoader; class iHistogramMaker; class iProbeFilter; class iViewSubject; class vtkDataSet; // // Useful macro to declare all keys that have to be present in children too // #define IDATASUBJECT_DECLARE_INHERITED_KEYS \ static const iObjectKey& KeyResizeLimits(); \ static const iObjectKey& KeyFixedLimits(); \ static const iObjectKey& KeyDataPresent(); \ static const iObjectKey& KeyFileName(); \ static const iObjectKey& KeyNumVars(); \ static const iObjectKey& KeyStretch(); \ static const iObjectKey& KeyMin(); \ static const iObjectKey& KeyMax(); \ static const iObjectKey& KeyLowerLimit(); \ static const iObjectKey& KeyUpperLimit(); \ static const iObjectKey& KeyFixedStretch(); \ static const iObjectKey& KeyName() class iDataSubject : public iObject { IPOINTER_AS_PART(ViewModule); friend class iFileLoader; public: vtkTypeMacro(iDataSubject,iObject); static const iObjectType& Type(); static bool IsTypeMatch(const iString &prefix); static iString GetDataSubjectName(const iString &prefix); IDATASUBJECT_DECLARE_INHERITED_KEYS; void SetFixedLimits(bool s); inline bool GetFixedLimits() const { return mFixedLimits; } virtual bool IsThereData() const; // // Access to components // inline iFileLoader* GetLoader() const { return mLoader; } iDataLimits* GetLimits() const; vtkDataSet* GetData() const; const iDataSyncRequest& Request(int var = -1) const; virtual const iObjectType& GetObjectType() const; virtual const iDataType& GetDataType() const = 0; virtual void PackCompleteState(iString &s) const; virtual void UnPackCompleteState(const iString &s); // // For picking and data exploring, we need to know what ProbeFilter and HistogramMaker would work with this Subject // virtual iProbeFilter* CreateProbeFilter(iViewSubject *vo) const; virtual iHistogramMaker* CreateHistogramMaker() const; protected: iDataSubject(iFileLoader *fl, const iString &name); virtual ~iDataSubject(); virtual void DataSubjectPackStateBody(iString &) const {} virtual void DataSubjectUnPackStateBody(const iString &){} virtual iDataLimits* CreateLimits() const; virtual void NotifyDependencies(); void ConfigureLimits(int num, const iString &name); // // Components // const int mId; iFileLoader *mLoader; bool mFixedLimits; private: virtual void PackStateBody(iString &s) const; virtual void UnPackStateBody(const iString &s); int mLimitsNum; iString mLimitsName; mutable iDataLimits *mLimits; // must be accessed via GetLimits() only }; // // Useful macros to declare all members that have to be overwritten in children // #define IDATASUBJECT_DECLARE_INHERITED_MEMBERS \ static const iObjectType& Type(); \ static const iDataType& DataType(); \ virtual const iObjectType& GetObjectType() const; \ virtual const iDataType& GetDataType() const #define IDATASUBJECT_DEFINE_TYPE(_object_,_id_,_fname_,_sname_,_rank_,_keywords_,_environment_) \ const iDataType& _object_::DataType() \ { \ static const iDataType tmp(_id_,_fname_,_sname_,_rank_,_keywords_,_environment_); \ return tmp; \ } \ const iObjectType& _object_::Type() \ { \ static const iString fname = "Data-" + _object_::DataType().GetName(); \ static const iString sname = "d-" + _object_::DataType().GetShortName(); \ static const iObjectType *pval = iObjectTypeRegistry::CreateType(iObjectType::_Data,fname.ToCharPointer(),sname.ToCharPointer()); \ return *pval; \ } \ const iObjectType& _object_::GetObjectType() const { return _object_::Type(); } \ const iDataType& _object_::GetDataType() const { return _object_::DataType(); } #define IDATASUBJECT_DEFINE_INHERITED_KEYS(_type_) \ IOBJECT_DEFINE_INHERITED_KEY(iDataSubject,_type_,ResizeLimits,-rl,Int,1); \ IOBJECT_DEFINE_INHERITED_KEY(iDataSubject,_type_,FixedLimits,fl,Bool,1); \ IOBJECT_DEFINE_INHERITED_KEY(iDataSubject,_type_,DataPresent,dp,Bool,1); \ IOBJECT_DEFINE_INHERITED_KEY(iDataSubject,_type_,FileName,fn,String,1); \ IOBJECT_DEFINE_INHERITED_KEY(iDataSubject,_type_,NumVars,n,Int,1); \ IOBJECT_DEFINE_INHERITED_KEY(iDataSubject,_type_,Stretch,s,Int,0); \ IOBJECT_DEFINE_INHERITED_KEY(iDataSubject,_type_,Min,min,Float,0); \ IOBJECT_DEFINE_INHERITED_KEY(iDataSubject,_type_,Max,max,Float,0); \ IOBJECT_DEFINE_INHERITED_KEY(iDataSubject,_type_,LowerLimit,lo,Float,0); \ IOBJECT_DEFINE_INHERITED_KEY(iDataSubject,_type_,UpperLimit,up,Float,0); \ IOBJECT_DEFINE_INHERITED_KEY(iDataSubject,_type_,FixedStretch,fs,Bool,0); \ IOBJECT_DEFINE_INHERITED_KEY(iDataSubject,_type_,Name,na,String,0) #define IDATASUBJECT_DECLARE_CLASS(_prefix_,_name_) \ class _prefix_##_name_##DataSubject : public iDataSubject \ { \ public: \ vtkTypeMacro(_prefix_##_name_##DataSubject,iDataSubject); \ _prefix_##_name_##DataSubject(iFileLoader *fl); \ IDATASUBJECT_DECLARE_INHERITED_KEYS; \ IDATASUBJECT_DECLARE_INHERITED_MEMBERS; \ } #define IDATASUBJECT_DEFINE_CLASS(_prefix_,_name_,_fname_,_sname_,_rank_,_keywords_,_environment_) \ IDATASUBJECT_DEFINE_TYPE(_prefix_##_name_##DataSubject,_prefix_##Extension::SubjectId(),_fname_,_sname_,_rank_,_keywords_,_environment_); \ IDATASUBJECT_DEFINE_INHERITED_KEYS(_prefix_##_name_##DataSubject); \ _prefix_##_name_##DataSubject::_prefix_##_name_##DataSubject(iFileLoader *fl) : iDataSubject(fl,_prefix_##_name_##DataSubject::Type().FullName()){} #endif ifrit-3.4.2/core/idirectory.cpp0000755000175700010010000000647312167404430015031 0ustar HomeNone/*========================================================================= Program: Ionization FRont Interactive Tool (IFRIT) Language: C++ Copyright (c) 2002-2012 Nick Gnedin All rights reserved. This file may be distributed and/or modified under the terms of the GNU General Public License version 2 as published by the Free Software Foundation and appearing in the file LICENSE.GPL included in the packaging of this file. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHORS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. =========================================================================*/ #include "idirectory.h" #include "ierror.h" #include // // templates // #include "iarraytemplate.h" iDirectory::iDirectory() { } bool iDirectory::Open(const iString &fname) { vtkDirectory *d = vtkDirectory::New(); IERROR_ASSERT(d); if(d->Open(fname.ToCharPointer()) == 0) { // // Is the file name attached? // if(d->Open(fname.Section("/",0,-2).ToCharPointer()) == 0) return false; else { mDirectory = fname.Section("/",0,-2) + "/"; } } else { mDirectory = fname; if(fname[-1] != '/') mDirectory += "/"; } mFiles.Clear(); int i, n = d->GetNumberOfFiles(); for(i=0; iGetFile(i)); // assume that all files are different, so AddUnique is not needed. } d->Delete(); return true; } void iDirectory::Close() { mDirectory.Clear(); mFiles.Clear(); } const iString iDirectory::GetFile(int i, bool prefixed) const { static const iString null = ""; if(i>=0 && i= 0) i += skip; return this->GetFile(i,prefixed); } bool iDirectory::Make(const iString &name) { return (vtkDirectory::MakeDirectory(name.ToCharPointer()) != 0); } const iString& iDirectory::Separator() { static const iString sep("/"); return sep; } const iString& iDirectory::Current() { static const iString cur("./"); return cur; } void iDirectory::ExpandFileName(iString& fname, const iString &path) { #ifdef _WIN32 // // Make sure we are Windows compatible // fname.Replace("\\",iDirectory::Separator()); #endif // // Apply standard expansion of the plus sign // if(!path.IsEmpty() && fname[0]=='+') fname.Replace(0,1,path); // // Is this an unprefixed file name? // if(fname.Contains(iDirectory::Separator()) == 0) fname = iDirectory::Current() + fname; } ifrit-3.4.2/core/idirectory.h0000644000175700010010000000430012167404411014455 0ustar HomeNone/*========================================================================= Program: Ionization FRont Interactive Tool (IFRIT) Language: C++ Copyright (c) 2002-2012 Nick Gnedin All rights reserved. This file may be distributed and/or modified under the terms of the GNU General Public License version 2 as published by the Free Software Foundation and appearing in the file LICENSE.GPL included in the packaging of this file. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHORS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. =========================================================================*/ // // A class that accesses file names in a directory. It uses vtkDirectory // class internally, but changes interface to more convenient. // #ifndef IDIRECTORY_H #define IDIRECTORY_H #include "iarray.h" #include "istring.h" class iDirectory { public: iDirectory(); bool Open(const iString &name); void Close(); inline bool IsOpened() const { return !mDirectory.IsEmpty(); } inline const iString& GetDirectoryPrefix() const { return mDirectory; } inline int GetNumberOfFiles() const { return mFiles.Size(); } const iString GetFile(int i, bool prefixed = false) const; const iString GetFile(const iString & file, int skip) const; bool Make(const iString &name); // // Directory naming convention for portability // static const iString& Separator(); static const iString& Current(); static void ExpandFileName(iString& name, const iString &path = ""); private: iString mDirectory; iOrderedArray mFiles; }; #endif // IDIRECTORY_H ifrit-3.4.2/core/ierror.h0000755000175700010010000000536712167404411013623 0ustar HomeNone/*========================================================================= Program: Ionization FRont Interactive Tool (IFRIT) Language: C++ Copyright (c) 2002-2012 Nick Gnedin All rights reserved. This file may be distributed and/or modified under the terms of the GNU General Public License version 2 as published by the Free Software Foundation and appearing in the file LICENSE.GPL included in the packaging of this file. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHORS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. =========================================================================*/ // // Some useful error reporting macros and function(s) // #ifndef IERROR_H #define IERROR_H #include "iconsole.h" #define IERROR_LOW(_m_) { iConsole::Display(iConsole::_LowError,_m_,__FILE__,__LINE__); } #define IERROR_HIGH(_m_) { iConsole::Display(iConsole::_HighError,_m_,__FILE__,__LINE__); } #define IERROR_FATAL(_m_) { iConsole::Display(iConsole::_FatalError,_m_,__FILE__,__LINE__); } #define IERROR_ASSERT(_p_) { if((_p_) == 0) iConsole::Display(iConsole::_FatalError,"Invalid use of a null pointer.",__FILE__,__LINE__); } #if defined(I_CHECK1) || defined(I_CHECK2) #define IERROR_REPORT_BUG { iConsole::Display(iConsole::_HighError,"Bug detected.",__FILE__,__LINE__); } #endif // // error-reporting dynamic_cast - make it a global function to reduce de-referencing // (ideally we would avoid using it all - use iRequiredCast(INFO,vtkObject*) function whenever possible). // template inline O* iDynamicCast(int line, const char *file, I* p) { if(p == 0) return 0; O* tmp = dynamic_cast(p); if(tmp == 0) iConsole::Display(iConsole::_FatalError,"Invalid cast.",file,line); return tmp; } // // RequiredCast for children of vtkObjectBase (which must be all cast-able objects) // class vtkObjectBase; template inline O* iRequiredCast(int line, const char *file, vtkObjectBase *p) { if(p == 0) return 0; O* tmp = O::SafeDownCast(p); if(tmp == 0) iConsole::Display(iConsole::_FatalError,"Invalid cast.",file,line); return tmp; } #define INFO __LINE__,__FILE__ #endif // IERROR_H ifrit-3.4.2/core/ierrorstatus.cpp0000755000175700010010000000644112167404430015415 0ustar HomeNone/*========================================================================= Program: Ionization FRont Interactive Tool (IFRIT) Language: C++ Copyright (c) 2002-2012 Nick Gnedin All rights reserved. This file may be distributed and/or modified under the terms of the GNU General Public License version 2 as published by the Free Software Foundation and appearing in the file LICENSE.GPL included in the packaging of this file. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHORS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. =========================================================================*/ #include "ierrorstatus.h" const iString iErrorStatus::mAbortMessage("Aborted."); iErrorStatus* iErrorStatus::New(const iString &prefix) { return new iErrorStatus(prefix); } iErrorStatus::iErrorStatus(const iString &prefix) : mPrefix(prefix+": ") { mLastSupervisor = mSupervisor = 0; this->Clear(); } iErrorStatus::~iErrorStatus() { } void iErrorStatus::Delete() { delete this; } void iErrorStatus::Monitor(iErrorStatus *object, bool prefixed, const iString &prefix) { // // this->Clear() is configured so that this function needs to be called again before // every execution // if(object != 0) { object->mLastSupervisor = 0; // this way next Clear() will not remove the supervisor. object->mSupervisor = this; if(prefixed) { if(prefix.IsEmpty()) object->mSupervisorPrefix = mPrefix; else object->mSupervisorPrefix = prefix; } else object->mSupervisorPrefix.Clear(); } } void iErrorStatus::Clear() { // // The proper use of this class is to call this function before any activity starts. // This function checks the current and the last supervisor - if they are the same, the // supervisor is removed. This way no action is needed after monitoring is set - at the // next execution, old supervisor will be automatically removed. // mMessage.Clear(); mLevel = iMath::_IntMax; mInUpdate = false; if(mSupervisor!=0 && mSupervisor==mLastSupervisor) { // // Supervision expired // mSupervisor = mLastSupervisor = 0; } mLastSupervisor = mSupervisor; } void iErrorStatus::SetAbort(int lev) { this->Set(mAbortMessage,lev); } void iErrorStatus::Set(const iString &msg, int lev) { if(mInUpdate) return; // avoid recursion mMessage = msg; mLevel = lev; // // If we are monitored, report to supervisor // if(mSupervisor != 0) { // // Reset supervisor's error info if it has no error, or its error is of lower level // if(mSupervisor->NoError() || mSupervisor->mLevelSet(mSupervisorPrefix+msg,lev); mInUpdate = false; } } } ifrit-3.4.2/core/ierrorstatus.h0000755000175700010010000000460012167404411015054 0ustar HomeNone/*========================================================================= Program: Ionization FRont Interactive Tool (IFRIT) Language: C++ Copyright (c) 2002-2012 Nick Gnedin All rights reserved. This file may be distributed and/or modified under the terms of the GNU General Public License version 2 as published by the Free Software Foundation and appearing in the file LICENSE.GPL included in the packaging of this file. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHORS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. =========================================================================*/ // // Class for reporting and monitoring of execution errors // #ifndef IERRORSTATUS_H #define IERRORSTATUS_H #include "istring.h" #include "imath.h" class iErrorStatus { public: // // There functions are needed for AutoPtr signature // static iErrorStatus* New(const iString &prefix); void Delete(); inline const iString& Message() const { return mMessage; } // no Get to fix a VC++7 bug inline int Level() const { return mLevel; } inline bool NoError() const { return mMessage.IsEmpty(); } inline bool IsError() const { return !mMessage.IsEmpty(); } inline bool IsAbort() const { return mMessage == mAbortMessage; } void Clear(); void Set(const iString &msg, int lev = iMath::_IntMax); void SetAbort(int lev = iMath::_IntMax); void Monitor(iErrorStatus *object, bool prefixed = false, const iString &prefix = ""); void SetSupervisorPrefix(const iString &prefix); private: iErrorStatus(const iString &prefix); ~iErrorStatus(); int mLevel; bool mInUpdate; iErrorStatus *mSupervisor, *mLastSupervisor; iString mMessage, mSupervisorPrefix; const iString mPrefix; static const iString mAbortMessage; }; #endif // IERRORSTATUS_H ifrit-3.4.2/core/ieventobserver.cpp0000755000175700010010000000410712167404430015706 0ustar HomeNone/*========================================================================= Program: Ionization FRont Interactive Tool (IFRIT) Language: C++ Copyright (c) 2002-2012 Nick Gnedin All rights reserved. This file may be distributed and/or modified under the terms of the GNU General Public License version 2 as published by the Free Software Foundation and appearing in the file LICENSE.GPL included in the packaging of this file. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHORS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. =========================================================================*/ #include "ieventobserver.h" #include "ierror.h" #include "ivtk.h" #include bool iEventObserver::mAllAreBlocked = false; // // Parent class for all event observers // iEventObserver::iEventObserver(iShell *s) : mShell(s) { mIsBlocked = mLockedExecute = false; #ifndef IVTK_PRE52 this->PassiveObserverOn(); // O-ho-ho, VTK guys - how I wish you messed less with the basic interface... #endif // // Use this mutex to support multi-threaded execution // mMutex = vtkCriticalSection::New(); IERROR_ASSERT(mMutex); } iEventObserver::~iEventObserver() { mMutex->Delete(); } void iEventObserver::Execute(vtkObject *caller, unsigned long event, void *data) { if(mAllAreBlocked || mIsBlocked) return; if(mLockedExecute) mMutex->Lock(); this->ExecuteBody(caller,event,data); if(mLockedExecute) mMutex->Unlock(); } ifrit-3.4.2/core/ieventobserver.h0000755000175700010010000000412312167404412015351 0ustar HomeNone/*========================================================================= Program: Ionization FRont Interactive Tool (IFRIT) Language: C++ Copyright (c) 2002-2012 Nick Gnedin All rights reserved. This file may be distributed and/or modified under the terms of the GNU General Public License version 2 as published by the Free Software Foundation and appearing in the file LICENSE.GPL included in the packaging of this file. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHORS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. =========================================================================*/ // // Base classes for event observers // #ifndef IEVENTOBSERVER_H #define IEVENTOBSERVER_H #include #include "ipointermacro.h" #include class iShell; class vtkCriticalSection; class iEventObserver : public vtkCommand { IPOINTER_AS_PART(Shell); public: vtkTypeMacro(iEventObserver,vtkCommand); static void BlockAllEventObservers(bool s){ mAllAreBlocked = s; } void Block(bool s){ mIsBlocked = s; } virtual void Execute(vtkObject *caller, unsigned long event, void *data); protected: iEventObserver(iShell *s); virtual ~iEventObserver(); void SetLockedExecute(bool s){ mLockedExecute = s; } virtual void ExecuteBody(vtkObject *caller, unsigned long event, void *data) = 0; private: static bool mAllAreBlocked; bool mIsBlocked, mLockedExecute; vtkCriticalSection *mMutex; }; #endif // IEVENTOBSERVER_H ifrit-3.4.2/core/iextendableobject.cpp0000755000175700010010000000651512167404430016324 0ustar HomeNone/*========================================================================= Program: Ionization FRont Interactive Tool (IFRIT) Language: C++ Copyright (c) 2002-2012 Nick Gnedin All rights reserved. This file may be distributed and/or modified under the terms of the GNU General Public License version 2 as published by the Free Software Foundation and appearing in the file LICENSE.GPL included in the packaging of this file. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHORS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. =========================================================================*/ #include "iextendableobject.h" #include "idata.h" #include "iextensionfactory.h" // // Templates // #include "iarraytemplate.h" // // Helper class // iObjectExtension::iObjectExtension(iExtendableObject *owner, const iString &name) : iObject(name), mName(name) { mOwner = owner; IERROR_ASSERT(owner); } void iObjectExtension::ClearCache() { this->iObject::ClearCache(); mOwner->ClearCache(); } void iObjectExtension::PackStateBody(iString &) const { } void iObjectExtension::UnPackStateBody(const iString &) { mUnPackedSomething = true; } // // Main class // iExtendableObject::iExtendableObject(const iString &name) : iObject(name) { } iExtendableObject::~iExtendableObject() { while(mExtensions.Size() > 0) mExtensions.RemoveLast()->Delete(); } iObjectExtension* iExtendableObject::GetExtensionByName(const iString &name) const { int i; for(i=0; iName() == name) return mExtensions[i]; return 0; } iObjectExtension* iExtendableObject::GetExtensionByClassName(const iString &name) const { int i; for(i=0; iIsA(name.ToCharPointer())) return mExtensions[i]; return 0; } void iExtendableObject::InstallExtension(iObjectExtension *object) { IERROR_ASSERT(object); mExtensions.AddUnique(object); } void iExtendableObject::PackCompleteState(iString &s) const { int i; iString s1; this->iObject::PackCompleteState(s); for(i=0; iPackCompleteState(s1); s += s1; } } void iExtendableObject::UnPackCompleteState(const iString &s) { int i; this->iObject::UnPackCompleteState(s); for(i=0; iUnPackCompleteState(s); } void iExtendableObject::PackStateBody(iString &s) const { int i; iString s1; this->ExtendableObjectPackStateBody(s); for(i=0; iPackState(s1); s += s1; } } void iExtendableObject::UnPackStateBody(const iString &s) { int i; this->ExtendableObjectUnPackStateBody(s); for(i=0; iUnPackState(s); } ifrit-3.4.2/core/iextendableobject.h0000755000175700010010000001041412167404412015762 0ustar HomeNone/*========================================================================= Program: Ionization FRont Interactive Tool (IFRIT) Language: C++ Copyright (c) 2002-2012 Nick Gnedin All rights reserved. This file may be distributed and/or modified under the terms of the GNU General Public License version 2 as published by the Free Software Foundation and appearing in the file LICENSE.GPL included in the packaging of this file. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHORS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. =========================================================================*/ // // This a base class for objects that have other objects installed to them as extensions. // #ifndef IEXTENDABLEOBJECT_H #define IEXTENDABLEOBJECT_H #include "iobject.h" #include "iarray.h" class iDataInfo; class iExtendableObject; class iObjectExtension : public iObject { public: vtkTypeMacro(iObjectExtension,iObject); const iString& Name() const { return mName; } virtual void ClearCache(); protected: iObjectExtension(iExtendableObject *owner, const iString &name); iExtendableObject* Owner() const { return mOwner; } virtual void PackStateBody(iString &) const; virtual void UnPackStateBody(const iString &); private: iExtendableObject* mOwner; const iString mName; }; class iExtendableObject : public iObject { friend class iObjectFactory; public: vtkTypeMacro(iExtendableObject,iObject); virtual void PackCompleteState(iString &s) const; virtual void UnPackCompleteState(const iString &s); inline iObjectExtension* GetExtension(int n) const { return mExtensions[n]; } // will return 0 if out of bounds iObjectExtension* GetExtensionByName(const iString &name) const; // will return 0 if none has this name; if more than one has the same name, the first one will be returned iObjectExtension* GetExtensionByClassName(const iString &name) const; // will return 0 if none has this name; if more than one has the same name, the first one will be returned protected: iExtendableObject(const iString &name); virtual ~iExtendableObject(); virtual void ExtendableObjectPackStateBody(iString &s) const = 0; virtual void ExtendableObjectUnPackStateBody(const iString &s) = 0; iSearchableArray mExtensions; private: // // Constructor helpers accessible to iExtensionFactory only // void InstallExtension(iObjectExtension *object); virtual void PackStateBody(iString &s) const; virtual void UnPackStateBody(const iString &s); }; // // Useful macros // #define IOBJECTEXTENSION_DECLARE_COMMON(_owner_,_self_) \ public: \ static _self_* Self(_owner_ *owner) #define IOBJECTEXTENSION_DECLARE_ABSTRACT(_owner_) \ IOBJECTEXTENSION_DECLARE_COMMON(_owner_,_owner_##Extension); \ vtkTypeMacro(_owner_##Extension,iObjectExtension); \ protected: \ _owner_##Extension(_owner_ *owner, const iString &name) : iObjectExtension(owner,name) { mRealOwner = owner; this->Define(); } \ void Define(); \ _owner_ *mRealOwner #define IOBJECTEXTENSION_DECLARE_SPECIFIC(_owner_,_self_) \ IOBJECTEXTENSION_DECLARE_COMMON(_owner_,_self_); \ vtkTypeMacro(_self_,_owner_##Extension); \ protected: \ _self_(_owner_ *owner, const iString &name) : _owner_##Extension(owner,name) { this->Define(); } \ void Define() #define IOBJECTEXTENSION_DEFINE_COMMON(_owner_,_self_) \ _self_* _self_::Self(_owner_ *owner) \ { \ return iRequiredCast<_self_>(INFO,owner->GetExtensionByClassName(#_self_)); \ } #define IOBJECTEXTENSION_DEFINE_ABSTRACT(_owner_) \ IOBJECTEXTENSION_DEFINE_COMMON(_owner_,_owner_##Extension) #define IOBJECTEXTENSION_DEFINE_SPECIFIC(_owner_,_self_) \ IOBJECTEXTENSION_DEFINE_COMMON(_owner_,_self_) #endif ifrit-3.4.2/core/ifamily.h0000755000175700010010000000404312167404412013742 0ustar HomeNone/*========================================================================= Program: Ionization FRont Interactive Tool (IFRIT) Language: C++ Copyright (c) 2002-2012 Nick Gnedin All rights reserved. This file may be distributed and/or modified under the terms of the GNU General Public License version 2 as published by the Free Software Foundation and appearing in the file LICENSE.GPL included in the packaging of this file. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHORS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. =========================================================================*/ #ifndef IFAMILY_H #define IFAMILY_H #include "iarray.h" class iView; template class iFamily { public: static iFamily* New(Parent *p); virtual void Delete(){ delete this; } inline int GetMaxMemberIndex() const { return this->mMemlist.MaxIndex(); } inline int GetCurrentMemberIndex() const { return this->mCur; } Object* GetCurrentMember() const { return this->mMemlist[this->mCur]; } Object* GetMember(int i) const { return this->mMemlist[i]; } void SetCurrentMemberIndex(int i) { if(i>=0 && imMemlist.Size()) this->mCur = i; } virtual int CreateMember(); virtual bool DeleteMember(int i); protected: // iFamily(); iFamily(Parent *p); virtual ~iFamily(); int mCur; Parent *mParent; iArray mMemlist; }; #endif // IFAMILY_H ifrit-3.4.2/core/ifamilytemplate.h0000755000175700010010000000463312167404412015503 0ustar HomeNone/*========================================================================= Program: Ionization FRont Interactive Tool (IFRIT) Language: C++ Copyright (c) 2002-2012 Nick Gnedin All rights reserved. This file may be distributed and/or modified under the terms of the GNU General Public License version 2 as published by the Free Software Foundation and appearing in the file LICENSE.GPL included in the packaging of this file. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHORS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. =========================================================================*/ #include "iarray.h" #include "ifamily.h" template iFamily* iFamily::New(Parent *p) { return new iFamily(p); } template iFamily::iFamily(Parent *p) { this->mParent = p; this->mCur = 0; Object* tmp = Object::New(this->mParent); IERROR_ASSERT(tmp); this->mMemlist.Add(tmp); } template iFamily::~iFamily() { int i; // // Delete members in reverse order in case they create static instances of reference-counted variables // for(i=this->mMemlist.MaxIndex(); i>=0; i--) this->mMemlist[i]->Delete(); } template int iFamily::CreateMember() { Object* tmp = Object::New(this->mParent); if(tmp == 0) return -1; this->mMemlist.Add(tmp); return this->mMemlist.MaxIndex(); } template bool iFamily::DeleteMember(int i) { if(i>=0 && imMemlist.Size() && this->mMemlist.Size()>1) { this->mMemlist[i]->Delete(); this->mMemlist.Remove(i); if(this->mCur>=i && i>0) this->mCur--; return true; } else return false; } ifrit-3.4.2/core/ifielddatasubject.cpp0000755000175700010010000000361312167404430016313 0ustar HomeNone/*========================================================================= Program: Ionization FRont Interactive Tool (IFRIT) Language: C++ Copyright (c) 2002-2012 Nick Gnedin All rights reserved. This file may be distributed and/or modified under the terms of the GNU General Public License version 2 as published by the Free Software Foundation and appearing in the file LICENSE.GPL included in the packaging of this file. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHORS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. =========================================================================*/ #include "ifielddatasubject.h" #include "idata.h" #include "idatalimits.h" #include "ierror.h" #include "ifieldfileloader.h" IOBJECT_DEFINE_TYPE(iFieldDataSubject,FieldData,-df,iObjectType::_Data); iFieldDataSubject::iFieldDataSubject(iFieldFileLoader *fl, const iString &name) : iDataSubject(fl,name), mFieldLoader(fl) { } const iObjectType& iFieldDataSubject::GetObjectType() const { return iFieldDataSubject::Type(); } void iFieldDataSubject::DataSubjectPackStateBody(iString &s) const { this->FieldDataSubjectPackStateBody(s); } void iFieldDataSubject::DataSubjectUnPackStateBody(const iString &s) { this->FieldDataSubjectUnPackStateBody(s); } ifrit-3.4.2/core/ifielddatasubject.h0000755000175700010010000000657412167404412015771 0ustar HomeNone/*========================================================================= Program: Ionization FRont Interactive Tool (IFRIT) Language: C++ Copyright (c) 2002-2012 Nick Gnedin All rights reserved. This file may be distributed and/or modified under the terms of the GNU General Public License version 2 as published by the Free Software Foundation and appearing in the file LICENSE.GPL included in the packaging of this file. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHORS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. =========================================================================*/ // // A base class for all DataSubjects for Field types. // #ifndef IFIELDDATASUBJECT_H #define IFIELDDATASUBJECT_H #include "idatasubject.h" class iFieldFileLoader; class iFieldDataSubject : public iDataSubject { friend class iFieldFileLoader; public: vtkTypeMacro(iFieldDataSubject,iDataSubject); static const iObjectType& Type(); virtual const iObjectType& GetObjectType() const; protected: iFieldDataSubject(iFieldFileLoader *fl, const iString &name); virtual void DataSubjectPackStateBody(iString &s) const; virtual void DataSubjectUnPackStateBody(const iString &s); virtual void FieldDataSubjectPackStateBody(iString &) const {} virtual void FieldDataSubjectUnPackStateBody(const iString &){} private: iFieldFileLoader *mFieldLoader; }; // // Useful macros to declare all members that have to be overwritten in children // #define IFIELDDATASUBJECT_DECLARE_INHERITED_MEMBERS \ IDATASUBJECT_DECLARE_INHERITED_MEMBERS #define IFIELDDATASUBJECT_DECLARE_INHERITED_KEYS \ IDATASUBJECT_DECLARE_INHERITED_KEYS #define IFIELDDATASUBJECT_DEFINE_TYPE(_object_,_id_,_fname_,_sname_,_rank_,_keywords_,_environment_) \ IDATASUBJECT_DEFINE_TYPE(_object_,_id_,_fname_,_sname_,_rank_,_keywords_,_environment_) #define IFIELDDATASUBJECT_DEFINE_INHERITED_KEYS(_type_) \ IDATASUBJECT_DEFINE_INHERITED_KEYS(_type_) #define IFIELDDATASUBJECT_DECLARE_CLASS(_prefix_,_name_) \ class _prefix_##_name_##DataSubject : public iFieldDataSubject \ { \ public: \ vtkTypeMacro(_prefix_##_name_##DataSubject,iFieldDataSubject); \ _prefix_##_name_##DataSubject(iFieldFileLoader *fl); \ IFIELDDATASUBJECT_DECLARE_INHERITED_KEYS; \ IFIELDDATASUBJECT_DECLARE_INHERITED_MEMBERS; \ } #define IFIELDDATASUBJECT_DEFINE_CLASS(_prefix_,_name_,_fname_,_sname_,_rank_,_keywords_,_environment_) \ IFIELDDATASUBJECT_DEFINE_TYPE(_prefix_##_name_##DataSubject,_prefix_##Extension::SubjectId(),_fname_,_sname_,_rank_,_keywords_,_environment_); \ IFIELDDATASUBJECT_DEFINE_INHERITED_KEYS(_prefix_##_name_##DataSubject); \ _prefix_##_name_##DataSubject::_prefix_##_name_##DataSubject(iFieldFileLoader *fl) : iFieldDataSubject(fl,_prefix_##_name_##DataSubject::Type().FullName()){} #endif ifrit-3.4.2/core/ifieldfileloader.cpp0000755000175700010010000000304212167404430016124 0ustar HomeNone/*========================================================================= Program: Ionization FRont Interactive Tool (IFRIT) Language: C++ Copyright (c) 2002-2012 Nick Gnedin All rights reserved. This file may be distributed and/or modified under the terms of the GNU General Public License version 2 as published by the Free Software Foundation and appearing in the file LICENSE.GPL included in the packaging of this file. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHORS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. =========================================================================*/ #include "ifieldfileloader.h" // // Main class // iFieldFileLoader::iFieldFileLoader(iDataReader *r, int priority) : iFileLoader(r,priority) { } iFieldFileLoader::iFieldFileLoader(iDataReaderExtension *ext, int priority) : iFileLoader(ext,priority) { } iFieldFileLoader::~iFieldFileLoader() { } ifrit-3.4.2/core/ifieldfileloader.h0000755000175700010010000000327612167404412015602 0ustar HomeNone/*========================================================================= Program: Ionization FRont Interactive Tool (IFRIT) Language: C++ Copyright (c) 2002-2012 Nick Gnedin All rights reserved. This file may be distributed and/or modified under the terms of the GNU General Public License version 2 as published by the Free Software Foundation and appearing in the file LICENSE.GPL included in the packaging of this file. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHORS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. =========================================================================*/ // // Abstract DataLoader for reading various field files // #ifndef IFIELDFILELOADER_H #define IFIELDFILELOADER_H #include "ifileloader.h" class iFieldFileLoader : public iFileLoader { friend class iUniformGridFileLoader; public: vtkTypeMacro(iFieldFileLoader,iFileLoader); protected: iFieldFileLoader(iDataReaderExtension *ext, int priority); virtual ~iFieldFileLoader(); private: iFieldFileLoader(iDataReader *r, int priority); }; #endif ifrit-3.4.2/core/ifieldviewsubject.cpp0000755000175700010010000001303612167404430016354 0ustar HomeNone/*========================================================================= Program: Ionization FRont Interactive Tool (IFRIT) Language: C++ Copyright (c) 2002-2012 Nick Gnedin All rights reserved. This file may be distributed and/or modified under the terms of the GNU General Public License version 2 as published by the Free Software Foundation and appearing in the file LICENSE.GPL included in the packaging of this file. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHORS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. =========================================================================*/ #include "ifieldviewsubject.h" #include "icolorbars.h" #include "idata.h" #include "idatareader.h" #include "idatalimits.h" #include "imergedatafilter.h" #include "ireplicatedactor.h" #include "iviewmodule.h" //#include // // Templates (needed for some compilers) // #include "iarraytemplate.h" using namespace iParameter; IVIEWSUBJECT_DEFINE_TYPE(iFieldViewSubject,FieldViewSubject,-fvo); IOBJECT_DEFINE_KEY(iFieldViewSubject,ColorBy,cb,OffsetInt,1); IOBJECT_DEFINE_KEY(iFieldViewSubject,GlyphSampleRate,gr,Int,1); IOBJECT_DEFINE_KEY(iFieldViewSubject,ConnectedToScalars,cs,Bool,1); IOBJECT_DEFINE_KEY(iFieldViewSubject,DataOffset,-off,OffsetInt,1); IOBJECT_DEFINE_DISTANCE_KEY(iFieldViewSubject,GlyphSize,gs); // // iFieldViewSubject class // iFieldViewSubject::iFieldViewSubject(iViewModule *vm, const iDataType &type, const iDataType &scalarType, const iString &name, int numActors, unsigned int flags) : iSolidViewSubject(vm,type,name,numActors,flags), mGlyphSize(vm,true), mScalarDataType(scalarType) { mColorBy = -1; mGlyphSize = 0.1; mGlyphSampleRate = 16; mColorByOffset = 0; this->AddSecondaryDataType(mScalarDataType); // // Do VTK stuff // mMergeDataFilter = iMergeDataFilter::New(this); IERROR_ASSERT(mMergeDataFilter); } iFieldViewSubject::~iFieldViewSubject() { mMergeDataFilter->Delete(); } void iFieldViewSubject::SetGlyphSize(const iDistance &v) { if(v < 1.0e5) { mGlyphSize = v; this->UpdateGlyphSize(); this->ClearCache(); } } void iFieldViewSubject::SetColorBy(int v) { if(mColorBy >= 0) this->ShowColorBars(false); mColorBy = v; if(v >= 0) this->ShowColorBars(true); if(this->IsColoredByScalars()) { mActors[0]->SyncWithLimits(this->GetViewModule()->GetReader()->GetLimits(mScalarDataType),mColorBy); mActors[0]->ColorByArrayComponent(0,mColorByOffset+mColorBy); mActors[0]->SetScalarVisibility(true); } else { mActors[0]->SetScalarVisibility(false); this->UpdateColorByExtra(); } this->ClearCache(); } void iFieldViewSubject::SetGlyphSampleRate(int v) { if(v>0 && v<1600) { mGlyphSampleRate = v; this->UpdateGlyphSampleRate(); this->ClearCache(); } } void iFieldViewSubject::ShowColorBarsBody(bool show) { if(this->IsColoredByScalars()) this->GetViewModule()->GetColorBars()->ShowBar(ColorBarsPriority::Field,mColorBy,mScalarDataType,mPalettes[0],show); } // // Two functions used in saving/restoring the state and in creating new instances with // void iFieldViewSubject::SolidViewSubjectPackStateBody(iString &s) const { this->PackValue(s,KeyColorBy(),mColorBy); this->PackValue(s,KeyGlyphSampleRate(),mGlyphSampleRate); this->PackValue(s,KeyConnectedToScalars(),this->IsConnectedToScalars()); this->PackValue(s,KeyDataOffset(),this->GetDataOffset()); this->PackValueDistance(s,KeyGlyphSize(),mGlyphSize); this->FieldViewSubjectPackStateBody(s); } void iFieldViewSubject::SolidViewSubjectUnPackStateBody(const iString &s) { int i; if(this->UnPackValue(s,KeyColorBy(),i)) this->SetColorBy(i); if(this->UnPackValue(s,KeyGlyphSampleRate(),i)) this->SetGlyphSampleRate(i); if(this->UnPackValueDistance(s,KeyGlyphSize(),mGlyphSize)) this->SetGlyphSize(mGlyphSize); this->FieldViewSubjectUnPackStateBody(s); } bool iFieldViewSubject::IsConnectedToScalars() const { return this->IsThereData() && mMergeDataFilter->HasData(0); } bool iFieldViewSubject::IsColoredByScalars() const { return (this->IsConnectedToScalars() && this->GetViewModule()->GetReader()->GetLimits(mScalarDataType)!=0 && mColorBy>=0 && mColorByGetViewModule()->GetReader()->GetLimits(mScalarDataType)->GetNumVars()); } void iFieldViewSubject::ViewSubjectSyncWithData(const iDataSyncRequest &r) { if(this->IsThereData()) { mMergeDataFilter->SetDataInput(0,this->GetViewModule()->GetReader()->GetData(mScalarDataType)); mMergeDataFilter->SetInput(this->GetData()); mMergeDataFilter->Update(); this->ResetPipelineInput(mMergeDataFilter->GetOutput()); } if((r.Var()==-1 || r.Var()==mColorBy) && this->IsColoredByScalars()) { mActors[0]->SyncWithLimits(this->GetViewModule()->GetReader()->GetLimits(mScalarDataType),mColorBy); } if(!this->IsConnectedToScalars() && mColorBy>=0 && mColorByGetViewModule()->GetReader()->GetLimits(mScalarDataType)->GetNumVars()) { this->SetColorBy(mColorByOffset); } this->FieldViewSubjectSyncWithData(r); } ifrit-3.4.2/core/ifieldviewsubject.h0000755000175700010010000001131412167404412016016 0ustar HomeNone/*========================================================================= Program: Ionization FRont Interactive Tool (IFRIT) Language: C++ Copyright (c) 2002-2012 Nick Gnedin All rights reserved. This file may be distributed and/or modified under the terms of the GNU General Public License version 2 as published by the Free Software Foundation and appearing in the file LICENSE.GPL included in the packaging of this file. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHORS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. =========================================================================*/ #ifndef IFIELDVIEWSUBJECT_H #define IFIELDVIEWSUBJECT_H #include "isolidviewsubject.h" class iMergeDataFilter; class iFieldViewSubject : public iSolidViewSubject { public: vtkTypeMacro(iFieldViewSubject,iSolidViewSubject); static const iObjectType& Type(); virtual const iObjectType& RealType(); virtual void SetColorBy(int q); inline int GetColorBy() const { return mColorBy; } virtual void SetGlyphSize(const iDistance &q); inline const iDistance& GetGlyphSize() const { return mGlyphSize; } virtual void SetGlyphSampleRate(int q); inline int GetGlyphSampleRate() const { return mGlyphSampleRate; } virtual int GetDataOffset() const = 0; const iDataType& GetScalarDataType() const { return mScalarDataType; } protected: iFieldViewSubject(iViewModule *vm, const iDataType &type, const iDataType &scalarType, const iString &name, int numActors, unsigned int flags); virtual ~iFieldViewSubject(); virtual void UpdateGlyphSize() = 0; virtual void UpdateGlyphSampleRate() = 0; virtual void ResetPipelineInput(vtkDataSet *input) = 0; virtual void UpdateColorByExtra(){} virtual void FieldViewSubjectPackStateBody(iString &s) const = 0; virtual void FieldViewSubjectUnPackStateBody(const iString &s) = 0; virtual void FieldViewSubjectSyncWithData(const iDataSyncRequest &r) = 0; virtual void SolidViewSubjectPackStateBody(iString &s) const; virtual void SolidViewSubjectUnPackStateBody(const iString &s); virtual void ViewSubjectSyncWithData(const iDataSyncRequest &r); virtual void ShowColorBarsBody(bool); virtual bool IsConnectedToScalars() const; virtual bool IsColoredByScalars() const; iDistance mGlyphSize; int mColorBy, mColorByOffset, mGlyphSampleRate; const iDataType &mScalarDataType; iMergeDataFilter *mMergeDataFilter; private: static const iObjectKey& KeyColorBy(); static const iObjectKey& KeyGlyphSize(bool opengl = false); static const iObjectKey& KeyGlyphSampleRate(); static const iObjectKey& KeyConnectedToScalars(); static const iObjectKey& KeyDataOffset(); }; // // Re-define SolidViewSubject macros // #define IFIELDVIEWSUBJECT_DECLARE_INHERITED_KEYS \ ISOLIDVIEWSUBJECT_DECLARE_INHERITED_KEYS; \ static const iObjectKey& KeyColorBy(); \ static const iObjectKey& KeyGlyphSize(bool opengl = false); \ static const iObjectKey& KeyGlyphSampleRate(); \ static const iObjectKey& KeyConnectedToScalars(); \ static const iObjectKey& KeyDataOffset() #define IFIELDVIEWSUBJECT_DECLARE_INHERITED_MEMBERS \ virtual int GetDataOffset() const; \ virtual bool CanBeShown() const; \ protected: \ virtual void ResetPipelineInput(vtkDataSet *input); \ virtual void ResetPipeline(); \ virtual void FieldViewSubjectPackStateBody(iString &s) const; \ virtual void FieldViewSubjectUnPackStateBody(const iString &s); \ virtual void FieldViewSubjectSyncWithData(const iDataSyncRequest &r); \ virtual void UpdateGlyphSize(); \ virtual void UpdateGlyphSampleRate(); \ virtual void ShowBody(bool s); \ public: \ virtual const iObjectType& RealType() #define IVIEWSUBJECT_DEFINE_INHERITED_KEYS_FIELD(_type_) \ IOBJECT_DEFINE_INHERITED_KEY(iFieldViewSubject,_type_,ColorBy,cb,OffsetInt,1); \ IOBJECT_DEFINE_INHERITED_KEY(iFieldViewSubject,_type_,GlyphSampleRate,gr,Int,1); \ IOBJECT_DEFINE_INHERITED_KEY(iFieldViewSubject,_type_,ConnectedToScalars,cs,Bool,1); \ IOBJECT_DEFINE_INHERITED_KEY(iFieldViewSubject,_type_,DataOffset,-off,OffsetInt,1); \ IOBJECT_DEFINE_INHERITED_DISTANCE_KEY(iFieldViewSubject,_type_,GlyphSize,gs) #endif // IFIELDVIEWSUBJECT_H ifrit-3.4.2/core/ifile.cpp0000755000175700010010000001113512167404430013733 0ustar HomeNone/*========================================================================= Program: Ionization FRont Interactive Tool (IFRIT) Language: C++ Copyright (c) 2002-2012 Nick Gnedin All rights reserved. This file may be distributed and/or modified under the terms of the GNU General Public License version 2 as published by the Free Software Foundation and appearing in the file LICENSE.GPL included in the packaging of this file. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHORS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. =========================================================================*/ #include "ifile.h" #include "ierror.h" #include // // VTK guys do that - so, there must be a good reason // #ifdef read #undef read #endif #ifdef write #undef write #endif #ifdef close #undef close #endif struct iFilePosition { #ifndef VTK_USE_ANSI_STDLIB #ifdef _WIN32 streampos Value; #else istream::pos_type Value; #endif #else istream::pos_type Value; #endif }; iFile::iFile(const iString &n) { mName = n; mStream = new fstream(); IERROR_ASSERT(mStream); mMaxMarker = 0; mNumMarker = 0; mMarker = 0; } iFile::~iFile() { delete mStream; if(mMarker != 0) delete mMarker; } void iFile::SetName(const iString &n) { this->Close(); mName = n; } bool iFile::Open(OpenMode mode, OpenType type) { int om = 0; if(mode & _Read) { om |= ios::in; #ifndef VTK_USE_ANSI_STDLIB om |= ios::nocreate; #endif } if(mode & _Write) { om |= ios::out; #ifndef VTK_USE_ANSI_STDLIB om |= !ios::nocreate; #endif } if(mode & _Append) { om = ios::out | ios::app; // append is exclusive #ifndef VTK_USE_ANSI_STDLIB om |= !ios::nocreate; #endif } if(type == _Binary) { om |= ios::binary; } mStream->clear(); mStream->open(mName.ToCharPointer(),ios::openmode(om)); return (mStream->fail()==0); } void iFile::Close() { mStream->clear(); mStream->close(); } bool iFile::ReadLine(iString &s, int max) { const int nbuf = 256; char buf[nbuf]; int n, r = 0; bool cont; mStream->clear(); s.Clear(); if(max < 1) return true; do { n = nbuf; if(n > max-r+1) n = max - r + 1; mStream->getline(buf,n); if(mStream->gcount() < n-1) { cont = false; } else { if(mStream->fail()!=0) { mStream->clear(); cont = true; } else { cont = false; } } if(mStream->fail()!=0 || mStream->eof()!=0) return false; s += buf; r += n-1; } while(cont && rclear(); mStream->read((char *)p,length); return (mStream->fail()==0 && mStream->eof()==0); } bool iFile::SkipBlock(size_t length) { mStream->clear(); mStream->seekg(length,ios::cur); return (mStream->fail()==0 && mStream->eof()==0); } bool iFile::WriteLine(const iString &s) { mStream->clear(); *mStream << s.ToCharPointer() << endl; bool ret = (mStream->fail()==0 && mStream->eof()==0); mStream->flush(); return ret; } bool iFile::Rewind() { mStream->clear(); mStream->seekg(0); return (mStream->fail()==0 && mStream->eof()==0); } bool iFile::IsReadable(const iString &name) { iFile F(name); if(!F.Open(_Read,_Text)) return false; F.Close(); return true; } bool iFile::IsWritable(const iString &name) { iFile F(name); if(!F.Open(_ReadWrite,_Text)) return false; F.Close(); return true; } int iFile::SetMarker() { if(mNumMarker == mMaxMarker) { mMaxMarker += 100; iFilePosition *tmp = new iFilePosition[mMaxMarker]; IERROR_ASSERT(tmp); if(mMarker != 0) { for(int i=0; itellg(); return mNumMarker++; } bool iFile::ReturnToMarker(int m, bool remove) { if(m<0 || m>=mNumMarker) return false; mStream->clear(); mStream->seekg(mMarker[m].Value); bool ret = (mStream->fail()==0 && mStream->eof()==0); if(remove) { for(int i=m; i struct iFilePosition; // this structure encapsulates file position type class iFile { public: enum OpenMode { _None = 0, _Read = 1, _Write = 2, _ReadWrite = 3, _Append = 4 }; enum OpenType { _Text = 0, _Binary = 1 }; iFile(const iString &name); ~iFile(); // // Open & close // void SetName(const iString &name); bool Open(OpenMode mode, OpenType type); void Close(); // // Reading // bool ReadLine(iString &s, int max = iString::MaxLength); bool ReadBlock(void *p, size_t length); // // Writing // bool WriteLine(const iString &s); // // Skipping // bool SkipBlock(size_t length); // // (Semi-)Random access // bool Rewind(); int SetMarker(); // marks the current location bool ReturnToMarker(int marker, bool remove = false); // returns to a given location int GetNumberOfMarkers() const { return mNumMarker; } // // Properties // static bool IsReadable(const iString &name); static bool IsWritable(const iString &name); inline const iString& GetName() const { return mName; } private: fstream *mStream; iString mName; iFilePosition *mMarker; int mNumMarker, mMaxMarker; }; #endif // IFILE_H ifrit-3.4.2/core/ifileloader.cpp0000755000175700010010000005123012167404430015122 0ustar HomeNone/*========================================================================= Program: Ionization FRont Interactive Tool (IFRIT) Language: C++ Copyright (c) 2002-2012 Nick Gnedin All rights reserved. This file may be distributed and/or modified under the terms of the GNU General Public License version 2 as published by the Free Software Foundation and appearing in the file LICENSE.GPL included in the packaging of this file. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHORS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. =========================================================================*/ #include "ifileloader.h" #include "icommoneventobservers.h" #include "idata.h" #include "idatahelper.h" #include "idatalimits.h" #include "idatareader.h" #include "idatasubject.h" #include "ierror.h" #include "ierrorstatus.h" #include "ifile.h" #include "ishellfactory.h" #include "isystem.h" #include "iviewmodule.h" #include // // Templates // #include "iarraytemplate.h" #define IDATASUBJECT_DEFINE_SWAP_BYTES_FUNCTIONS(_type_) \ void iFileLoader::SwapBytes(_type_ &p) \ { \ iFileLoader_Private::SwapBytes(p); \ } \ void iFileLoader::SwapBytesRange(_type_ *p, vtkIdType count) \ { \ iFileLoader_Private::SwapBytesRange(p,count); \ } #define IDATASUBJECT_DEFINE_READ_BLOCK_FUNCTIONS(_type_) \ bool iFileLoader::ReadBlock(iFile& F, _type_ *p, vtkIdType len, float updateStart, float updateDuration) \ { \ return iFileLoader_Private::ReadBlockToArray(F,p,len,updateStart,updateDuration,mIsBigEndian!=iSystem::IsBigEndianMachine(),mObserver); \ } \ iFileLoader::ReadingBuffer iFileLoader::Buffer(_type_ &d) const \ { \ return ReadingBuffer(&d,1UL,iFileLoader_Private::TypeIndex(&d),sizeof(_type_)); \ } \ iFileLoader::ReadingBuffer iFileLoader::Buffer(_type_ *d, vtkIdType l) const \ { \ return ReadingBuffer(d,l,iFileLoader_Private::TypeIndex(d),sizeof(_type_)); \ } namespace iFileLoader_Private { // // Byte swap helpers // inline void Swap4Bytes(char* data) { char one_byte; one_byte = data[0]; data[0] = data[3]; data[3] = one_byte; one_byte = data[1]; data[1] = data[2]; data[2] = one_byte; } inline void Swap8Bytes(char* data) { char one_byte; one_byte = data[0]; data[0] = data[7]; data[7] = one_byte; one_byte = data[1]; data[1] = data[6]; data[6] = one_byte; one_byte = data[2]; data[2] = data[5]; data[5] = one_byte; one_byte = data[3]; data[3] = data[4]; data[4] = one_byte; } void Swap4BytesRange(char *data, vtkIdType count) { char *pos; vtkIdType i; pos = data; for(i = 0; i inline void SwapBytes(T &p) { switch(sizeof(T)) { case 4: { Swap4Bytes((char *)&p); break; } case 8: { Swap8Bytes((char *)&p); break; } default: { IERROR_FATAL("IFrIT was not ported to that platform."); } } } template inline void SwapBytesRange(T *p, vtkIdType count) { switch(sizeof(T)) { case 4: { Swap4BytesRange((char *)p,count); break; } case 8: { Swap8BytesRange((char *)p,count); break; } default: { IERROR_FATAL("IFrIT was not ported to that platform."); } } } // // Check validity of numbers // bool IsNumberValid(vtkTypeInt32 v){ return true; } bool IsNumberValid(vtkTypeInt64 v){ return true; } bool IsNumberValid(vtkTypeFloat32 v){ return (-iMath::_FloatMax<=v && v<=iMath::_FloatMax); } bool IsNumberValid(vtkTypeFloat64 v){ return (-iMath::_DoubleMax<=v && v<=iMath::_DoubleMax); } // // Type indices // const int _Int32 = 1; const int _Int64 = 2; const int _Float32 = 3; const int _Float64 = 4; int TypeIndex(vtkTypeInt32 *){ return _Int32; } int TypeIndex(vtkTypeInt64 *){ return _Int64; } int TypeIndex(vtkTypeFloat32 *){ return _Float32; } int TypeIndex(vtkTypeFloat64 *){ return _Float64; } // // Read blocks of data from a file // template bool ReadBlockToArray(iFile& F, T *p, vtkIdType len, float updateStart, float updateDuration, bool swapbytes, iProgressEventObserver *observer) { const vtkIdType nline = 16384L; vtkIdType nread, l, nstep = (len+nline-1)/nline; float ustep = updateDuration/nstep; for(l=0; lIsAborted()) return true; if(l < nstep-1) nread = nline; else nread = len - nline*l; if(!F.ReadBlock(p+l*nline,nread*sizeof(T))) return false; observer->SetProgress(updateStart+ustep*l); } if(swapbytes) { iFileLoader_Private::SwapBytesRange(p,len); } bool ok = true; for(l=0; ok && l bool AnalyzeFirstRecordForType(iFile &F, unsigned int len, bool &isBig) { T lrec1, lrec2; int m = F.SetMarker(); if(!F.ReadBlock(&lrec1,sizeof(T)) || !F.SkipBlock(len) || !F.ReadBlock(&lrec2,sizeof(T))) { F.ReturnToMarker(m,true); return false; // unable even to read } F.ReturnToMarker(m,true); // // Is the header/footer length ok? // if(lrec1 == lrec2) // succeeded { // // auto-detect data endiness // if(lrec1 != len) { SwapBytes(lrec1); if(lrec1 != len) return false; else isBig = !iSystem::IsBigEndianMachine(); } else isBig = iSystem::IsBigEndianMachine(); return true; } else return false; } }; using namespace iFileLoader_Private; using namespace iParameter; iFileLoader::iFileLoader(iDataReader *r, int priority) : mViewModule(r?r->GetViewModule():0), mErrorStatus("Data Subject"), mReader(r), mReaderExtension(0), mPriority(priority) { this->Define(); } iFileLoader::iFileLoader(iDataReaderExtension *ext, int priority) : mViewModule(ext?ext->GetReader()->GetViewModule():0), mErrorStatus("Data Subject"), mReader(ext->GetReader()), mReaderExtension(ext), mPriority(priority) { this->Define(); } void iFileLoader::Define() { IERROR_ASSERT(mReader); mFortranHeaderFooterLength = -1; // mFileRoot = mFileSuffix = mLastFileName = ""; mUpdated = true; mIsBigEndian = true; mTwoCopies = false; mRecord = -1; mShift[0] = mShift[1] = mShift[2] = 0.0f; mPeriodic[0] = mPeriodic[1] = mPeriodic[2] = false; mBoundaryConditions = BoundaryConditions::Wall; // // Event observers are driven directly (otherwise we would have to create at least 16 new events, which is // cumbersome), so adding with AddObserver is not necessarily // mObserver = dynamic_cast(iShellFactory::CreateEventObserver("Progress",mReader->GetViewModule())); IERROR_ASSERT(mObserver); } iFileLoader::~iFileLoader() { mObserver->Delete(); while(mStreams.Size() > 0) delete mStreams.RemoveLast(); } bool iFileLoader::IsUsingData(const iDataType &type) const { int i; for(i=0; iSubject->GetDataType() == type) return true; } return false; } const iDataType& iFileLoader::GetDataType(int n) const { if(n>=0 && nSubject->GetDataType(); else return iDataType::Null(); } vtkDataSet* iFileLoader::GetData(int n) const { if(n>=0 && nReleasedData; else return 0; } vtkDataSet* iFileLoader::GetData(const iDataType &type) const { int i; for(i=0; iSubject->GetDataType() == type) return this->GetData(i); } return 0; } iDataSubject* iFileLoader::GetSubject(int n) const { if(n>=0 && nSubject; else return 0; } iDataSubject* iFileLoader::GetSubject(const iDataType &type) const { int i; for(i=0; iSubject->GetDataType() == type) return mStreams[i]->Subject; } return 0; } void iFileLoader::SetBoundaryConditions(int s) { if(BoundaryConditions::IsValid(s)) { mBoundaryConditions = s; } } void iFileLoader::SetDirectionPeriodic(int d, bool s) { if(d>=0 && d<3) { mPeriodic[d] = s; } } void iFileLoader::ReadFile(const iString &fname) { int i; this->GetErrorStatus()->Clear(); mOverflow = false; mFortranHeaderFooterLength = -1; // must be set by a child class iString root, suffix; int record = this->DissectFileName(fname,root,suffix); for(i=0; iSubject->GetLimits()->BlockNotifications(true); if(mStreams[i]->ReleasedData!=0 && !mTwoCopies) { // // The data can be referenced by other objects, so delete will not delete it. Thus, we first erase // the actual data by initializing the data object // mStreams[i]->ReleasedData->Initialize(); mStreams[i]->ReleasedData->Delete(); mStreams[i]->ReleasedData = 0; } } this->ReadFileBody(suffix,fname); for(i=0; iSubject->GetLimits()->BlockNotifications(false); } if(this->GetErrorStatus()->NoError()) { mLastFileName = fname; mFileSuffix = suffix; mFileRoot = root; mUpdated = false; mRecord = record; mShift[0] = mShift[1] = mShift[2] = 0.0f; } } void iFileLoader::Finalize() { int i; for(i=0; iSubject->GetLimits()->BlockNotifications(true); } this->FinalizeBody(); for(i=0; iSubject->GetLimits()->BlockNotifications(false); } if(!mUpdated) { mUpdated = true; if(this->GetErrorStatus()->NoError() && mOverflow) { this->GetErrorStatus()->Set("The data are read correctly, but some values in the file were outside of range ("+iString::FromNumber(-iMath::_LargeFloat)+","+iString::FromNumber(iMath::_LargeFloat)+").\n These values were clamped to be within the required range.",-1); } } this->NotifyDependencies(); } void iFileLoader::NotifyDependencies() { int i; for(i=0; iSubject->NotifyDependencies(); mStreams[i]->Subject->ClearCache(); } } void iFileLoader::AttachDataToStream(int i, vtkDataSet *ds) { if(i>=0 && iReleasedData != 0) { mStreams[i]->ReleasedData->Delete(); } mStreams[i]->ReleasedData = ds->NewInstance(); IERROR_ASSERT(mStreams[i]->ReleasedData); if(mTwoCopies) { mStreams[i]->ReleasedData->DeepCopy(ds); } else { mStreams[i]->ReleasedData->ShallowCopy(ds); } this->Polish(mStreams[i]->ReleasedData); } } } bool iFileLoader::IsAborted() const { return mObserver->IsAborted(); } bool iFileLoader::IsThereData(int n) const { if(n>=0 && nGetData(n)); return h.IsThereData(); } else return false; } bool iFileLoader::IsThereData() const { int i; for(i=0; iIsThereData(i)) return true; } return false; } bool iFileLoader::IsThereData(const iDataType &type) const { int i; for(i=0; iSubject->GetDataType() == type) return this->IsThereData(i); } return false; } void iFileLoader::EraseData() { int i; for(i=0; iReleasedData != 0) { mStreams[i]->ReleasedData->Initialize(); } mRecord = -1; mShift[0] = mShift[1] = mShift[2] = 0.0f; for(i=0; iSubject->GetLimits()->AssignVars(); // if no data, use all vars mStreams[i]->Subject->ClearCache(); } } void iFileLoader::SetTwoCopies(bool s) { if(mTwoCopies != s) { mTwoCopies = s; } } void iFileLoader::Reset() { int i; for(i=0; iReleasedData != 0) { mStreams[i]->ReleasedData->Modified(); this->GetViewModule()->NotifyDataConsumers(mStreams[i]->Subject->Request()); } } void iFileLoader::ShiftData(double dr[3]) { int i; double dx[3]; mObserver->Started(iProgressEventObserver::_Shifting); mObserver->SetProgress(0.0); for(i=0; i<3; i++) dx[i] = dr[i] - mShift[i]; for(i=0; iNumStreams(); i++) if(mStreams[i]->ReleasedData != 0) { this->ShiftDataBody(mStreams[i]->ReleasedData,dx); } for(i=0; i<3; i++) mShift[i] = dr[i]; mObserver->Finished(); } float iFileLoader::GetMemorySize() const { int i; float s = 0.0f; for(i=0; iReleasedData != 0) { s += mStreams[i]->ReleasedData->GetActualMemorySize(); } if(mTwoCopies) s *= 2; return s; } iFileLoader::Stream* iFileLoader::CreateNewStream() const { return new Stream(); } // // Data reading helpers // bool iFileLoader::SkipFortranRecord(iFile& F, vtkIdType len) { vtkIdType lrec1, lrec2; if(!this->ReadFortranHeaderFooter(F,lrec1)) return false; if(!F.SkipBlock(len)) return false; if(!this->ReadFortranHeaderFooter(F,lrec2)) return false; if(lrec1!=lrec2 || lrec1!=len) return false; return true; } bool iFileLoader::ReadFortranRecord(iFile& F, const ReadingBuffer &b, float updateStart, float updateDuration, bool autoswap) { vtkIdType lrec1, lrec2; if(!this->ReadFortranHeaderFooter(F,lrec1)) return false; if(!ReadBlockToBuffer(F,b,updateStart,updateDuration,autoswap && mIsBigEndian!=iSystem::IsBigEndianMachine(),mObserver)) return false; if(mObserver->IsAborted()) return true; if(!this->ReadFortranHeaderFooter(F,lrec2)) return false; if(lrec1!=lrec2 || lrec1!=b.Length*b.Size) return false; return true; } bool iFileLoader::ReadFortranRecord(iFile& F, const ReadingBuffer &b1, const ReadingBuffer &b2, float updateStart, float updateDuration, bool autoswap) { vtkIdType lrec1, lrec2; vtkIdType len = b1.Length*b1.Size + b2.Length*b2.Size; float f1 = float(b1.Length*b1.Size)/len; float f2 = float(b2.Length*b2.Size)/len; if(!this->ReadFortranHeaderFooter(F,lrec1)) return false; if(!ReadBlockToBuffer(F,b1,updateStart,f1*updateDuration,autoswap && mIsBigEndian!=iSystem::IsBigEndianMachine(),mObserver)) return false; if(mObserver->IsAborted()) return true; if(!ReadBlockToBuffer(F,b2,updateStart+f1*updateDuration,f2*updateDuration,autoswap && mIsBigEndian!=iSystem::IsBigEndianMachine(),mObserver)) return false; if(mObserver->IsAborted()) return true; if(!this->ReadFortranHeaderFooter(F,lrec2)) return false; if(lrec1!=lrec2 || lrec1!=len) return false; return true; } bool iFileLoader::ReadFortranRecord(iFile& F, const ReadingBuffer &b1, const ReadingBuffer &b2, const ReadingBuffer &b3, float updateStart, float updateDuration, bool autoswap) { vtkIdType lrec1, lrec2; vtkIdType len = b1.Length*b1.Size + b2.Length*b2.Size + b3.Length*b3.Size; float f1 = float(b1.Length*b1.Size)/len; float f2 = float(b2.Length*b2.Size)/len; float f3 = float(b3.Length*b3.Size)/len; if(!this->ReadFortranHeaderFooter(F,lrec1)) return false; if(!ReadBlockToBuffer(F,b1,updateStart,f1*updateDuration,autoswap && mIsBigEndian!=iSystem::IsBigEndianMachine(),mObserver)) return false; if(mObserver->IsAborted()) return true; if(!ReadBlockToBuffer(F,b2,updateStart+f1*updateDuration,f2*updateDuration,autoswap && mIsBigEndian!=iSystem::IsBigEndianMachine(),mObserver)) return false; if(mObserver->IsAborted()) return true; if(!ReadBlockToBuffer(F,b3,updateStart+(f1+f2)*updateDuration,f3*updateDuration,autoswap && mIsBigEndian!=iSystem::IsBigEndianMachine(),mObserver)) return false; if(mObserver->IsAborted()) return true; if(!this->ReadFortranHeaderFooter(F,lrec2)) return false; if(lrec1!=lrec2 || lrec1!=len) return false; return true; } bool iFileLoader::ReadFortranRecord(iFile& F, int nbufs, const ReadingBuffer *b, float updateStart, float updateDuration, bool autoswap) // read any number of buffers { vtkIdType lrec1, lrec2; if(b==0 || nbufs<=0 || !this->ReadFortranHeaderFooter(F,lrec1)) return false; int i; vtkIdType len = 0L; for(i=0; iIsAborted()) return true; } if(!this->ReadFortranHeaderFooter(F,lrec2)) return false; if(lrec1!=lrec2 || lrec1!=len) return false; return true; } bool iFileLoader::ReadFortranHeaderFooter(iFile& F, vtkIdType &lrec) { bool ret = false; if(mFortranHeaderFooterLength == 8) { vtkTypeInt64 ltmp; ret = F.ReadBlock(<mp,8); if(ret) { if(mIsBigEndian != iSystem::IsBigEndianMachine()) this->SwapBytes(ltmp); if(sizeof(vtkIdType) < 8) { IERROR_LOW("VTK is compiled with 32-bit Ids. The record length of this file is 64-bits, it cannot be read with this VTK installation. To be able to read this file you will have to recompile VTK with the advanced option VTK_USE_64BIT_IDS set to ON and then recompile IFrIT."); return false; } lrec = ltmp; } } else if(mFortranHeaderFooterLength == 4) { vtkTypeInt32 ltmp; ret = F.ReadBlock(<mp,4); if(ret) { if(mIsBigEndian != iSystem::IsBigEndianMachine()) this->SwapBytes(ltmp); lrec = ltmp; } } else { IERROR_LOW("Invalid Fortran header/footer length."); } return ret; } bool iFileLoader::DetectFortranFileStructure(iFile &F, vtkIdType len) { // // Try 4-byte records // if(AnalyzeFirstRecordForType(F,len,mIsBigEndian)) { mFortranHeaderFooterLength = sizeof(vtkTypeInt32); return true; } // // Try 8-byte records // if(AnalyzeFirstRecordForType(F,len,mIsBigEndian)) { mFortranHeaderFooterLength = sizeof(vtkTypeInt64); return true; } // // Failed to figure it out // return false; } iString iFileLoader::GetRecordAsString(int rec) const { const iString format = "%0" + iString::FromNumber(mReader->GetRecordLength()) + "d"; return iString::FromNumber(rec,format.ToCharPointer()); } int iFileLoader::DissectFileName(const iString &fname, iString &root, iString &suffix) const { bool ok; int rec; if(fname.Contains('.') > 0) { suffix = fname.Section(".",-1); root = fname.Part(0,fname.Length()-suffix.Length()-1); } else { suffix.Clear(); root = fname; } iString record = root.Part(-mReader->GetRecordLength()); rec = record.ToInt(ok); if(!ok || record!=this->GetRecordAsString(rec) || rec<0) { return -1; } else { root = root.Part(0,root.Length()-mReader->GetRecordLength()); return rec; } } const iString iFileLoader::GetFileName(int rec) const { if(mFileSuffix.IsEmpty()) { return mFileRoot + this->GetRecordAsString(rec); } else { return mFileRoot + this->GetRecordAsString(rec) + "." + mFileSuffix; } } bool iFileLoader::IsSeriesFileName(const iString &fname) const { iString root, suffix; int rec = this->DissectFileName(fname,root,suffix); return (rec>=0 && root==mFileRoot && suffix==mFileSuffix); } // // Overloads // IDATASUBJECT_DEFINE_SWAP_BYTES_FUNCTIONS(vtkTypeInt32); IDATASUBJECT_DEFINE_SWAP_BYTES_FUNCTIONS(vtkTypeInt64); IDATASUBJECT_DEFINE_SWAP_BYTES_FUNCTIONS(vtkTypeFloat32); IDATASUBJECT_DEFINE_SWAP_BYTES_FUNCTIONS(vtkTypeFloat64); IDATASUBJECT_DEFINE_READ_BLOCK_FUNCTIONS(vtkTypeInt32); IDATASUBJECT_DEFINE_READ_BLOCK_FUNCTIONS(vtkTypeInt64); IDATASUBJECT_DEFINE_READ_BLOCK_FUNCTIONS(vtkTypeFloat32); IDATASUBJECT_DEFINE_READ_BLOCK_FUNCTIONS(vtkTypeFloat64); // // Helper class // iFileLoader::Stream::Stream() { Subject = 0; ReleasedData = 0; } iFileLoader::Stream::~Stream() { if(ReleasedData != 0) ReleasedData->Delete(); if(Subject != 0) Subject->Delete(); } ifrit-3.4.2/core/ifileloader.h0000755000175700010010000001634512167404412014577 0ustar HomeNone/*========================================================================= Program: Ionization FRont Interactive Tool (IFRIT) Language: C++ Copyright (c) 2002-2012 Nick Gnedin All rights reserved. This file may be distributed and/or modified under the terms of the GNU General Public License version 2 as published by the Free Software Foundation and appearing in the file LICENSE.GPL included in the packaging of this file. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHORS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. =========================================================================*/ // // A base class for all classes for reading data files. Each iFileLoader loads a single kind of data, // but may provide data for multiple data types. // #ifndef IFILELOADER_H #define IFILELOADER_H #include #include "iarray.h" #include "ipointermacro.h" #include "istring.h" #include class iDataReader; class iDataReaderExtension; class iDataSubject; class iDataType; class iErrorStatus; class iFile; class iProgressEventObserver; class iViewModule; class vtkDataSet; namespace iParameter { // // Data parameters // namespace BoundaryConditions { const int Periodic = 0; const int Wall = 1; inline bool IsValid(int m){ return m>=0 && m<=1; } }; }; // // Helper macros // #define IDATAFILELOADER_DECLARE_SWAP_BYTES_FUNCTIONS(_type_) \ static void SwapBytes(_type_ &p); \ static void SwapBytesRange(_type_ *data, vtkIdType count) #define IDATAFILELOADER_DECLARE_READ_BLOCK_FUNCTIONS(_type_) \ bool ReadBlock(iFile& F, _type_ *p, vtkIdType len, float updateStart, float updateDuration); \ ReadingBuffer Buffer(_type_ &d) const; \ ReadingBuffer Buffer(_type_ *d, vtkIdType l) const class iFileLoader : public vtkObjectBase { IPOINTER_AS_PART(ViewModule); IPOINTER_AS_USER(ErrorStatus); friend class iDataReader; friend class iDataSubject; friend class iFieldFileLoader; friend class iParticleFileLoader; public: vtkTypeMacro(iFileLoader,vtkObjectBase); IDATAFILELOADER_DECLARE_SWAP_BYTES_FUNCTIONS(vtkTypeInt32); IDATAFILELOADER_DECLARE_SWAP_BYTES_FUNCTIONS(vtkTypeInt64); IDATAFILELOADER_DECLARE_SWAP_BYTES_FUNCTIONS(vtkTypeFloat32); IDATAFILELOADER_DECLARE_SWAP_BYTES_FUNCTIONS(vtkTypeFloat64); // // Operation on data // void ReadFile(const iString &fname); void Finalize(); void EraseData(); void Reset(); void ShiftData(double dr[3]); inline bool IsTwoCopies() const { return mTwoCopies; } void SetTwoCopies(bool s); virtual bool IsAborted() const; inline bool IsAnimatable() const { return (mRecord >= 0); } inline const iString& GetLastFileName() const { return mLastFileName; } inline const iString GetFileRoot() const { return mFileRoot; } virtual const iString GetFileName(int rec) const; iString GetRecordAsString(int rec) const; bool IsSeriesFileName(const iString &fname) const; virtual float GetMemorySize() const; // // Boundary conditions // void SetBoundaryConditions(int s); void SetDirectionPeriodic(int d, bool s); inline int GetBoundaryConditions() const { return mBoundaryConditions; } inline bool IsBoxPeriodic() const { return (mBoundaryConditions == iParameter::BoundaryConditions::Periodic); } inline bool IsDirectionPeriodic(int d) const { if(d>=0 && d<3) return this->IsBoxPeriodic() && mPeriodic[d]; else return false; } // // Access to components // inline iDataReader* GetReader() const { return mReader; } inline iDataReaderExtension* GetReaderExtension() const { return mReaderExtension; } bool IsThereData() const; virtual bool IsThereData(int n) const; virtual iDataSubject* GetSubject(int n) const; virtual vtkDataSet* GetData(int n) const; inline iProgressEventObserver* GetObserver() const { return mObserver; } bool IsUsingData(const iDataType &type) const; const iDataType& GetDataType(int n) const; virtual int DissectFileName(const iString &fname, iString &root, iString &suffix) const; inline int NumStreams() const { return mStreams.Size(); } bool IsThereData(const iDataType &type) const; iDataSubject* GetSubject(const iDataType &type) const; vtkDataSet* GetData(const iDataType &type) const; inline int GetPriority() const { return mPriority; } // // Helper struct // struct ReadingBuffer { void *Data; vtkIdType Length; int Type, Size; ReadingBuffer(void *d, vtkIdType l, int t, int s) { Data = d; Length = l; Type = t; Size = s; } }; protected: iFileLoader(iDataReaderExtension *ext, int priority); virtual ~iFileLoader(); virtual void ReadFileBody(const iString &suffix, const iString &fname) = 0; virtual void FinalizeBody() = 0; virtual void ShiftDataBody(vtkDataSet *data, double dx[3]) = 0; virtual void Polish(vtkDataSet * ){} // optional post-finalize // // File reading helpers // IDATAFILELOADER_DECLARE_READ_BLOCK_FUNCTIONS(vtkTypeInt32); IDATAFILELOADER_DECLARE_READ_BLOCK_FUNCTIONS(vtkTypeInt64); IDATAFILELOADER_DECLARE_READ_BLOCK_FUNCTIONS(vtkTypeFloat32); IDATAFILELOADER_DECLARE_READ_BLOCK_FUNCTIONS(vtkTypeFloat64); bool DetectFortranFileStructure(iFile &F, vtkIdType len); bool ReadFortranHeaderFooter(iFile& F, vtkIdType &lrec); bool SkipFortranRecord(iFile& F, vtkIdType len); bool ReadFortranRecord(iFile& F, const ReadingBuffer &b, float updateStart, float updateDuration, bool autoswap = true); bool ReadFortranRecord(iFile& F, const ReadingBuffer &b1, const ReadingBuffer &b2, float updateStart, float updateDuration, bool autoswap = true); bool ReadFortranRecord(iFile& F, const ReadingBuffer &b1, const ReadingBuffer &b2, const ReadingBuffer &b3, float updateStart, float updateDuration, bool autoswap = true); bool ReadFortranRecord(iFile& F, int nbufs, const ReadingBuffer *b, float updateStart, float updateDuration, bool autoswap = true); // read any number of buffers // // Data management // struct Stream { iDataSubject *Subject; vtkDataSet *ReleasedData; Stream(); virtual ~Stream(); }; virtual Stream* CreateNewStream() const; inline Stream* GetStream(int i) const { return mStreams[i]; } // no bound checking for speed void AttachDataToStream(int i, vtkDataSet *ds); void NotifyDependencies(); // // Components // int mBoundaryConditions; bool mPeriodic[3]; iString mFileRoot, mFileSuffix, mLastFileName; bool mTwoCopies, mIsBigEndian, mOverflow; iProgressEventObserver *mObserver; double mShift[3]; int mRecord, mFortranHeaderFooterLength; iDataReader *mReader; iDataReaderExtension *mReaderExtension; private: iFileLoader(iDataReader *r, int priority); void Define(); iArray mStreams; const int mPriority; bool mUpdated; // should not be used by children }; #endif // IFILELOADER_H ifrit-3.4.2/core/iflipnormalsfilter.cpp0000755000175700010010000000303212167404430016545 0ustar HomeNone/*========================================================================= Program: Ionization FRont Interactive Tool (IFRIT) Language: C++ Copyright (c) 2002-2012 Nick Gnedin All rights reserved. This file may be distributed and/or modified under the terms of the GNU General Public License version 2 as published by the Free Software Foundation and appearing in the file LICENSE.GPL included in the packaging of this file. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHORS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. =========================================================================*/ #include "iflipnormalsfilter.h" // // Templates // #include "igenericfiltertemplate.h" iFlipNormalsFilter::iFlipNormalsFilter(iViewSubject *vo) : iGenericPolyDataToPolyDataFilter(vo,1,true,false) { } void iFlipNormalsFilter::ProduceOutput() { this->ExecuteParent(); } ifrit-3.4.2/core/iflipnormalsfilter.h0000644000175700010010000000312012167404412016205 0ustar HomeNone/*========================================================================= Program: Ionization FRont Interactive Tool (IFRIT) Language: C++ Copyright (c) 2002-2012 Nick Gnedin All rights reserved. This file may be distributed and/or modified under the terms of the GNU General Public License version 2 as published by the Free Software Foundation and appearing in the file LICENSE.GPL included in the packaging of this file. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHORS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. =========================================================================*/ #ifndef IFLIPNORMALSFILTER_H #define IFLIPNORMALSFILTER_H #include "igenericfilter.h" #include class iFlipNormalsFilter : public iGenericPolyDataToPolyDataFilter { IGENERICFILTER_DECLARE(iFlipNormalsFilter,vtkReverseSense); protected: virtual void ProduceOutput(); }; #endif // IFLIPNORMALSFILTER_H ifrit-3.4.2/core/iframedtextactor.cpp0000755000175700010010000001177212167404431016220 0ustar HomeNone/*========================================================================= Program: Ionization FRont Interactive Tool (IFRIT) Language: C++ Copyright (c) 2002-2012 Nick Gnedin All rights reserved. This file may be distributed and/or modified under the terms of the GNU General Public License version 2 as published by the Free Software Foundation and appearing in the file LICENSE.GPL included in the packaging of this file. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHORS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. =========================================================================*/ #include "iframedtextactor.h" #include "ierror.h" #include "ioverlayhelper.h" #include #include #include #include #include #include #include #include // // Templates // #include "iarraytemplate.h" #include "igenericproptemplate.h" iFramedTextActor* iFramedTextActor::New(iRenderTool *rt) { IERROR_ASSERT(rt); return new iFramedTextActor(rt); } iFramedTextActor::iFramedTextActor(iRenderTool *rt) : iTextActor(rt) { this->SetPadding(0.02); vtkPolyData *data; vtkCellArray *cells; vtkPolyDataMapper2D *mapper; vtkCoordinate *coord; mBorderPoints = vtkPoints::New(VTK_FLOAT); IERROR_ASSERT(mBorderPoints); mBorderPoints->SetNumberOfPoints(4); // // Border // data = vtkPolyData::New(); IERROR_ASSERT(data); data->SetPoints(mBorderPoints); cells = vtkCellArray::New(); IERROR_ASSERT(cells); cells->InsertNextCell(5); cells->InsertCellPoint(0); cells->InsertCellPoint(1); cells->InsertCellPoint(2); cells->InsertCellPoint(3); cells->InsertCellPoint(0); data->SetLines(cells); cells->Delete(); mapper = vtkPolyDataMapper2D::New(); IERROR_ASSERT(mapper); mapper->SetInput(data); data->Delete(); coord = vtkCoordinate::New(); IERROR_ASSERT(coord); coord->SetCoordinateSystemToNormalizedViewport(); mapper->SetTransformCoordinate(coord); coord->Delete(); mBorderActor = vtkActor2D::New(); IERROR_ASSERT(mBorderActor); this->PrependComponent(mBorderActor); mBorderActor->SetMapper(mapper); mapper->Delete(); // // Lining // data = vtkPolyData::New(); IERROR_ASSERT(data); data->SetPoints(mBorderPoints); cells = vtkCellArray::New(); IERROR_ASSERT(cells); cells->InsertNextCell(4); cells->InsertCellPoint(0); cells->InsertCellPoint(1); cells->InsertCellPoint(2); cells->InsertCellPoint(3); data->SetPolys(cells); cells->Delete(); mapper = vtkPolyDataMapper2D::New(); IERROR_ASSERT(mapper); mapper->SetInput(data); data->Delete(); coord = vtkCoordinate::New(); IERROR_ASSERT(coord); coord->SetCoordinateSystemToNormalizedViewport(); mapper->SetTransformCoordinate(coord); coord->Delete(); mLiningActor = vtkActor2D::New(); IERROR_ASSERT(mLiningActor); this->PrependComponent(mLiningActor); mLiningActor->SetMapper(mapper); mapper->Delete(); this->SetTransparent(true); } iFramedTextActor::~iFramedTextActor() { mBorderPoints->Delete(); mBorderActor->Delete(); mLiningActor->Delete(); } void iFramedTextActor::SetTransparent(bool s) { if(s != mTransparent) { mTransparent = s; mLiningActor->SetVisibility(mTransparent?0:1); this->Modified(); } } void iFramedTextActor::UpdateGeometry(vtkViewport* vp) { this->iTextActor::UpdateGeometry(vp); if(!this->IsEnabled()) return; int mag = this->GetOverlayHelper()->GetRenderingMagnification(); if(mag == 1) { // // Assign properties // mBorderActor->GetProperty()->SetColor(this->GetOverlayHelper()->GetColor(vp).ToVTK()); mLiningActor->GetProperty()->SetColor(vp->GetBackground()); } // // Scale lines // mBorderActor->GetProperty()->SetLineWidth(2*mag); // // Place border and lining // if(mag == 1) { this->GetBounds(vp,wBounds); int j; for(j=0; j<4; j++) wTrueBounds[j] = wBounds[j]; } else { int winij[2]; this->GetOverlayHelper()->ComputePositionShiftsUnderMagnification(winij); wBounds[0] = mag*wTrueBounds[0] - winij[0]; wBounds[1] = mag*wTrueBounds[1] - winij[0]; wBounds[2] = mag*wTrueBounds[2] - winij[1]; wBounds[3] = mag*wTrueBounds[3] - winij[1]; } // // Define the border // mBorderPoints->SetPoint(0,wBounds[0],wBounds[2],0.0); mBorderPoints->SetPoint(1,wBounds[1],wBounds[2],0.0); mBorderPoints->SetPoint(2,wBounds[1],wBounds[3],0.0); mBorderPoints->SetPoint(3,wBounds[0],wBounds[3],0.0); } ifrit-3.4.2/core/iframedtextactor.h0000644000175700010010000000367112167404412015660 0ustar HomeNone/*========================================================================= Program: Ionization FRont Interactive Tool (IFRIT) Language: C++ Copyright (c) 2002-2012 Nick Gnedin All rights reserved. This file may be distributed and/or modified under the terms of the GNU General Public License version 2 as published by the Free Software Foundation and appearing in the file LICENSE.GPL included in the packaging of this file. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHORS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. =========================================================================*/ #ifndef IFRAMEDTEXTACTOR_H #define IFRAMEDTEXTACTOR_H #include "itextactor.h" class vtkActor2D; class vtkPoints; class iFramedTextActor: public iTextActor { public: vtkTypeMacro(iFramedTextActor,iTextActor); static iFramedTextActor* New(iRenderTool *rt = 0); void SetTransparent(bool s); inline bool IsTransparent() const { return mTransparent; } protected: iFramedTextActor(iRenderTool *rv); virtual ~iFramedTextActor(); virtual void UpdateGeometry(vtkViewport *vp); float wBounds[4]; private: bool mTransparent; float wTrueBounds[4]; vtkPoints *mBorderPoints; vtkActor2D *mBorderActor; vtkActor2D *mLiningActor; }; #endif // IFRAMEDTEXTACTOR_H ifrit-3.4.2/core/ifunctionmapping.cpp0000755000175700010010000000376312167404431016226 0ustar HomeNone/*========================================================================= Program: Ionization FRont Interactive Tool (IFRIT) Language: C++ Copyright (c) 2002-2012 Nick Gnedin All rights reserved. This file may be distributed and/or modified under the terms of the GNU General Public License version 2 as published by the Free Software Foundation and appearing in the file LICENSE.GPL included in the packaging of this file. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHORS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. =========================================================================*/ #include "ifunctionmapping.h" #include "idatalimits.h" #include "ihistogrammaker.h" #include // // Templates // #include "iarraytemplate.h" iFunctionMapping::iFunctionMapping(iPiecewiseFunction *pf, iHistogramMaker *hm, vtkObject *user) { mCurVar = 0; mLimits = 0; mPF = pf; mHM = hm; mUser = user; } const iHistogram* iFunctionMapping::GetHistogram(int nBins) const { if(mLimits!=0 && mCurVar>=0 && mCurVarGetNumVars()) { mHM->SetStretch(mLimits->GetStretch(mCurVar)); return mHM->GetHistogram(nBins,mLimits->GetLowerLimit(mCurVar),mLimits->GetUpperLimit(mCurVar)); } else { return mHM->GetHistogram(nBins); } } void iFunctionMapping::AttachToLimits(iDataLimits *lim, int var) { mLimits = lim; mCurVar = var; } ifrit-3.4.2/core/ifunctionmapping.h0000755000175700010010000000363612167404413015672 0ustar HomeNone/*========================================================================= Program: Ionization FRont Interactive Tool (IFRIT) Language: C++ Copyright (c) 2002-2012 Nick Gnedin All rights reserved. This file may be distributed and/or modified under the terms of the GNU General Public License version 2 as published by the Free Software Foundation and appearing in the file LICENSE.GPL included in the packaging of this file. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHORS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. =========================================================================*/ // // A wrapper to package the piecewise function and its histogram together // #ifndef IFUNCTIONMAPPING_H #define IFUNCTIONMAPPING_H class iDataLimits; class iHistogram; class iHistogramMaker; class iPiecewiseFunction; class vtkObject; class iFunctionMapping { public: iFunctionMapping(iPiecewiseFunction *pf, iHistogramMaker *hm, vtkObject *user); inline iPiecewiseFunction* GetFunction() const { return mPF; } const iHistogram* GetHistogram(int nBins = 0) const; void AttachToLimits(iDataLimits *lim, int var); private: int mCurVar; iDataLimits *mLimits; iHistogramMaker *mHM; iPiecewiseFunction *mPF; vtkObject *mUser; }; #endif // IFUNCTIONMAPPING_H ifrit-3.4.2/core/igenericfilter.h0000755000175700010010000001107712167404413015311 0ustar HomeNone/*========================================================================= Program: Ionization FRont Interactive Tool (IFRIT) Language: C++ Copyright (c) 2002-2012 Nick Gnedin All rights reserved. This file may be distributed and/or modified under the terms of the GNU General Public License version 2 as published by the Free Software Foundation and appearing in the file LICENSE.GPL included in the packaging of this file. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHORS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. =========================================================================*/ // // A front-end for portable inheritance // #ifndef IGENERICFILTER_H #define IGENERICFILTER_H #include "iviewsubjectcomponent.h" #include "ierror.h" #include class vtkDataObject; class vtkDataSetAttributes; class vtkFloatArray; class vtkInformation; class vtkInformationVector; class vtkPolyData; template class iGenericSource : public Source, public iViewSubjectComponent { public: virtual float GetMemorySize(); virtual int GetNumberOfOutputs(); protected: iGenericSource(iViewSubject *vo, bool usesLimits); virtual ~iGenericSource(); virtual int RequestData(vtkInformation *request, vtkInformationVector **inInfo, vtkInformationVector *outInfo); void SaveRequest(vtkInformation *request, vtkInformationVector **inInfo, vtkInformationVector *outInfo); virtual void ExecuteData(vtkDataObject *output); void ExecuteParent(); virtual void SyncWithData(const iDataSyncRequest &r); virtual void ProduceOutput() = 0; // called to recompute the output const bool mUsesLimits; vtkInformation *mSavedRequest; vtkInformationVector **mSavedInputVector; vtkInformationVector *mSavedOutputVector; int mReturnCode; private: int mExecuteMethod; }; template class iGenericFilter : public Filter, public iViewSubjectComponent { public: virtual float GetMemorySize(); virtual int GetNumberOfOutputs(); protected: iGenericFilter(iViewSubject *vo, int numInputs, bool ownsOutput, bool usesLimits); virtual ~iGenericFilter(); virtual int ProcessRequest(vtkInformation *request, vtkInformationVector **inInfo, vtkInformationVector *outInfo); virtual int RequestData(vtkInformation *request, vtkInformationVector **inInfo, vtkInformationVector *outInfo); void SaveRequest(vtkInformation *request, vtkInformationVector **inInfo, vtkInformationVector *outInfo); virtual void ExecuteData(vtkDataObject *output); void ExecuteParent(); virtual void SyncWithData(const iDataSyncRequest &r); virtual void InitExecution(); // called if recomputing is needed virtual void ProduceOutput() = 0; // called to recompute the output virtual void VerifyResults(); // called on every pipeline pass after ProduceOutput // // Helper members for transforming scalars // bool ScalarsInit(vtkDataSetAttributes *data, vtkIdType nSizeOut = 0, int nDimOut = 0); void ScalarsDone(vtkDataSetAttributes *data); const bool mOwnsOutput, mUsesLimits; vtkInformation *mSavedRequest; vtkInformationVector **mSavedInputVector; vtkInformationVector *mSavedOutputVector; int mReturnCode; vtkFloatArray *wScalarArrIn, *wScalarArrOut; float *wScalarPtrIn, *wScalarPtrOut; int wScalarDimIn, wScalarDimOut; private: int mExecuteMethod; }; template class iGenericPolyDataToPolyDataFilter : public iGenericFilter { protected: iGenericPolyDataToPolyDataFilter(iViewSubject *vo, int numInputs, bool ownsOutput, bool usesLimits) : iGenericFilter(vo,numInputs,ownsOutput,usesLimits){} virtual void VerifyResults(); }; // // Useful macro // #define IGENERICFILTER_DECLARE(_name_,_parent_) \ public: \ vtkTypeMacro(_name_,_parent_); \ static _name_* New(iViewSubject *vo = 0) { IERROR_ASSERT(vo); return new _name_(vo); } \ protected: \ _name_(iViewSubject *vo); #endif // IGENERICFILTER_H ifrit-3.4.2/core/igenericfiltertemplate.h0000755000175700010010000002664412167404413017053 0ustar HomeNone/*========================================================================= Program: Ionization FRont Interactive Tool (IFRIT) Language: C++ Copyright (c) 2002-2012 Nick Gnedin All rights reserved. This file may be distributed and/or modified under the terms of the GNU General Public License version 2 as published by the Free Software Foundation and appearing in the file LICENSE.GPL included in the packaging of this file. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHORS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. =========================================================================*/ #include "igenericfilter.h" #include "icommoneventobservers.h" #include "ierror.h" #include "iviewmodule.h" #include "iviewsubject.h" #include #include #include #include #include #include #include // // Generic Source class // template iGenericSource::iGenericSource(iViewSubject *vo, bool usesLimits) : iViewSubjectComponent(vo), mUsesLimits(usesLimits) { mExecuteMethod = 0; if(vo->IsCreatingMainPipeline()) { this->AddObserver(vtkCommand::ProgressEvent,vo->GetViewModule()->GetAbortRenderEventObserver()); } else { this->AddObserver(vtkCommand::ProgressEvent,vo->GetViewModule()->GetSlaveAbortRenderEventObserver()); } } template iGenericSource::~iGenericSource() { } template void iGenericSource::ExecuteData(vtkDataObject * ) { OutputType *output = this->GetOutput(); IERROR_ASSERT(output); mExecuteMethod = 0; this->ProduceOutput(); if(this->IsOptimizedForMemory()) output->Squeeze(); } template void iGenericSource::SaveRequest(vtkInformation *request, vtkInformationVector **inInfo, vtkInformationVector *outInfo) { mSavedRequest = request; mSavedInputVector = inInfo; mSavedOutputVector = outInfo; mReturnCode = 1; } template int iGenericSource::RequestData(vtkInformation* request, vtkInformationVector** inInfo, vtkInformationVector* outInfo) { OutputType *output = this->GetOutput(); IERROR_ASSERT(output); mExecuteMethod = 1; this->SaveRequest(request,inInfo,outInfo); this->ProduceOutput(); if(this->IsOptimizedForMemory()) output->Squeeze(); return mReturnCode; } template void iGenericSource::ExecuteParent() { switch(mExecuteMethod) { case 0: { this->Source::ExecuteData(this->GetOutput()); break; } case 1: { mReturnCode = this->Source::RequestData(mSavedRequest,mSavedInputVector,mSavedOutputVector); break; } default: { IERROR_LOW("Invalid ExecuteMethod."); } } } template void iGenericSource::SyncWithData(const iDataSyncRequest &) { if(mUsesLimits) this->Modified(); } template int iGenericSource::GetNumberOfOutputs() { return this->Source::GetNumberOfOutputPorts(); } template float iGenericSource::GetMemorySize() { int j; float s = 0.0f; for(j=0; jGetNumberOfOutputs(); j++) { s += this->GetOutput(j)->GetActualMemorySize(); } return s; } // // Generic Filter class // template iGenericFilter::iGenericFilter(iViewSubject *vo, int numInputs, bool ownsOutput, bool usesLimits) : iViewSubjectComponent(vo), mOwnsOutput(ownsOutput), mUsesLimits(usesLimits) { mExecuteMethod = 0; if(vo->IsCreatingMainPipeline()) { this->AddObserver(vtkCommand::ProgressEvent,vo->GetViewModule()->GetAbortRenderEventObserver()); } else { this->AddObserver(vtkCommand::ProgressEvent,vo->GetViewModule()->GetSlaveAbortRenderEventObserver()); } if(numInputs > 0) // not all filters default to 1 input, some have 0 inputs { this->SetNumberOfInputConnections(0,numInputs); } } template iGenericFilter::~iGenericFilter() { } template void iGenericFilter::ExecuteData(vtkDataObject * ) { InputType *input = InputType::SafeDownCast(this->GetInput()); OutputType *output = this->GetOutput(); IERROR_ASSERT(output); if(input == 0) { output->Initialize(); return; } mExecuteMethod = 0; #ifdef I_DEBUG iConsole::PrintDebugMessage(iString("Executing filter ")+Filter::GetClassName()+" by method 0."); #endif this->ProduceOutput(); if(this->IsOptimizedForMemory()) output->Squeeze(); this->VerifyResults(); } template void iGenericFilter::SaveRequest(vtkInformation *request, vtkInformationVector **inInfo, vtkInformationVector *outInfo) { mSavedRequest = request; mSavedInputVector = inInfo; mSavedOutputVector = outInfo; mReturnCode = 1; } template int iGenericFilter::ProcessRequest(vtkInformation *request, vtkInformationVector **inInfo, vtkInformationVector *outInfo) { // // This replaces ExecuteInformation call // if(request->Has(vtkDemandDrivenPipeline::REQUEST_INFORMATION())) { InputType *input = InputType::SafeDownCast(this->GetInput()); OutputType *output = this->GetOutput(); IERROR_ASSERT(output); if(input != 0) { this->SaveRequest(request,inInfo,outInfo); this->InitExecution(); } if(this->IsA("vtkSource")) { // // PipelineInformation may contain wrong values of Origin and Spacing. These values get written into the Origin and Spacing fields // of vtkImageData in vtkSource::ProcessRequest. We need to fix this bug by putting correct values into PipelineInformation. // int i; vtkInformation *info; for(i=0; iGetNumberOfInformationObjects(); i++) { info = inInfo[0]->GetInformationObject(i); if(info != 0) { vtkImageData *data = vtkImageData::SafeDownCast(info->Get(vtkDataObject::DATA_OBJECT())); if(data != 0) { double v[3]; vtkInformation *info = data->GetPipelineInformation(); if(info != 0) { if(info->Has(vtkDataObject::ORIGIN())) { data->GetOrigin(v); info->Set(vtkDataObject::ORIGIN(),v,3); } if(info->Has(vtkDataObject::SPACING())) { data->GetSpacing(v); info->Set(vtkDataObject::SPACING(),v,3); } } } } } } } return this->Filter::ProcessRequest(request,inInfo,outInfo); } template int iGenericFilter::RequestData(vtkInformation* request, vtkInformationVector** inInfo, vtkInformationVector* outInfo) { InputType *input = InputType::SafeDownCast(this->GetInput()); OutputType *output = this->GetOutput(); IERROR_ASSERT(output); if(input == 0) { output->Initialize(); return 1; } mExecuteMethod = 1; #ifdef I_DEBUG iConsole::PrintDebugMessage(iString("Executing filter ")+Filter::GetClassName()+" by method 1."); #endif this->SaveRequest(request,inInfo,outInfo); this->ProduceOutput(); if(this->IsOptimizedForMemory()) output->Squeeze(); this->VerifyResults(); return mReturnCode; } template void iGenericFilter::ExecuteParent() { switch(mExecuteMethod) { case 0: { this->Filter::ExecuteData(this->GetOutput()); break; } case 1: { mReturnCode = this->Filter::RequestData(mSavedRequest,mSavedInputVector,mSavedOutputVector); break; } default: { IERROR_LOW("Invalid ExecuteMethod."); } } } template void iGenericFilter::SyncWithData(const iDataSyncRequest &) { if(mUsesLimits) this->Modified(); } template int iGenericFilter::GetNumberOfOutputs() { return this->Filter::GetNumberOfOutputPorts(); } template float iGenericFilter::GetMemorySize() { int j; float s = 0.0f; if(mOwnsOutput) { for(j=0; jGetNumberOfOutputs(); j++) { s += this->GetOutput(j)->GetActualMemorySize(); } } return s; } template void iGenericFilter::InitExecution() { // // Default implementation is to do nothing // } template void iGenericFilter::VerifyResults() { // // Default implementation is to do nothing // } template bool iGenericFilter::ScalarsInit(vtkDataSetAttributes *data, vtkIdType nSizeOut, int nDimOut) { if(data==0 || data->GetScalars()==0) { wScalarArrIn = wScalarArrOut = 0; wScalarPtrIn = wScalarPtrOut = 0; wScalarDimIn = wScalarDimOut = 0; return true; } wScalarArrIn = vtkFloatArray::SafeDownCast(data->GetScalars()); if(wScalarArrIn == 0) { vtkErrorMacro("Input scalars are not float."); return false; } wScalarDimIn = wScalarArrIn->GetNumberOfComponents(); wScalarPtrIn = wScalarArrIn->GetPointer(0); if(nSizeOut < 1) nSizeOut = wScalarArrIn->GetNumberOfTuples(); if(nDimOut < 1) nDimOut = wScalarDimIn; wScalarArrOut = vtkFloatArray::New(); if(wScalarArrOut == 0) { vtkErrorMacro("Not enough memory to create output scalars."); return false; } wScalarArrOut->SetNumberOfComponents(nDimOut); wScalarArrOut->SetNumberOfTuples(nSizeOut); wScalarDimOut = nDimOut; wScalarPtrOut = wScalarArrOut->GetPointer(0); if(wScalarPtrOut == 0) { vtkErrorMacro("Not enough memory to create output scalars."); return false; } return true; } template void iGenericFilter::ScalarsDone(vtkDataSetAttributes *data) { if(data!=0 && wScalarArrOut!=0) { data->SetScalars(wScalarArrOut); wScalarArrOut->Delete(); } } template void iGenericPolyDataToPolyDataFilter::VerifyResults() { vtkPolyData *input = vtkPolyData::SafeDownCast(this->GetInput()); vtkPolyData *output = this->GetOutput(); if(input!=0 && output!=0 && input->GetPoints()!=0 && output->GetPoints()!=0 && (input->GetPoints()->GetDataType()!=output->GetPoints()->GetDataType())) { #ifdef I_DEBUG int it = input->GetPoints()->GetDataType(); int ot = output->GetPoints()->GetDataType(); #endif vtkErrorMacro("Incompatible point types of input and output"); } } ifrit-3.4.2/core/igenericprop.h0000755000175700010010000000524612167404413015005 0ustar HomeNone/*========================================================================= Program: Ionization FRont Interactive Tool (IFRIT) Language: C++ Copyright (c) 2002-2012 Nick Gnedin All rights reserved. This file may be distributed and/or modified under the terms of the GNU General Public License version 2 as published by the Free Software Foundation and appearing in the file LICENSE.GPL included in the packaging of this file. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHORS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. =========================================================================*/ // // A front-end for portable props - in case VTK guys decide to change the vtkProp interface again... // #ifndef IGENERICPROP_H #define IGENERICPROP_H #include "iarray.h" #include "ivtk.h" #include class vtkProp; class vtkViewport; class vtkWindow; template class iGenericProp : public Prop { public: virtual int RenderOverlay(vtkViewport *vp); virtual int RenderOpaqueGeometry(vtkViewport *vp); #ifdef IVTK_PRE52 virtual int RenderTranslucentGeometry(vtkViewport *vp); #else virtual int HasTranslucentPolygonalGeometry(); virtual int RenderTranslucentPolygonalGeometry(vtkViewport *vp); virtual int RenderVolumetricGeometry(vtkViewport *vp); #endif virtual void ReleaseGraphicsResources(vtkWindow *win); protected: iGenericProp(bool self); virtual void UpdateGeometry(vtkViewport *vp) = 0; virtual void UpdateOverlay(vtkViewport *vp); virtual void Reset(); inline bool IsEnabled() const { return mEnabled; } void PrependComponent(vtkProp *p); void AppendComponent(vtkProp *p); void RemoveComponent(vtkProp *p); void RemoveAllComponents(); void ToggleComponent(vtkProp *p); void ShowComponents(int n, vtkProp **p); void Disable(); vtkTimeStamp GetLastRenderMTime() const { return mLastRenderMTime; } private: void MakeUpTodate(vtkViewport *vp); const bool mSelf; bool mDirty, mEnabled; iSearchableArray mProps; vtkTimeStamp mLastRenderMTime; }; #endif // IGENERICPROP_H ifrit-3.4.2/core/igenericproptemplate.h0000755000175700010010000001133012167404413016530 0ustar HomeNone/*========================================================================= Program: Ionization FRont Interactive Tool (IFRIT) Language: C++ Copyright (c) 2002-2012 Nick Gnedin All rights reserved. This file may be distributed and/or modified under the terms of the GNU General Public License version 2 as published by the Free Software Foundation and appearing in the file LICENSE.GPL included in the packaging of this file. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHORS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. =========================================================================*/ #include "igenericprop.h" #include #define IGENERICPROP_RENDER(_fun_) \ if(mEnabled) \ { \ ret = 0; \ for(j=0; jGetVisibility() != 0) \ { \ ret += mProps[j]->_fun_(vp); \ } \ if(mSelf) ret += this->Prop::_fun_(vp); \ } \ else ret = 0 template iGenericProp::iGenericProp(bool self) : mSelf(self) { mDirty = mEnabled = true; } template void iGenericProp::MakeUpTodate(vtkViewport *vp) { if(mDirty) { this->UpdateGeometry(vp); mDirty = false; } } template void iGenericProp::Reset() { } template void iGenericProp::UpdateOverlay(vtkViewport *) { } template int iGenericProp::RenderOverlay(vtkViewport *vp) { int j, ret; this->MakeUpTodate(vp); if(mEnabled) this->UpdateOverlay(vp); IGENERICPROP_RENDER(RenderOverlay); this->Reset(); mDirty = mEnabled = true; mLastRenderMTime.Modified(); return ret; } template int iGenericProp::RenderOpaqueGeometry(vtkViewport *vp) { int j, ret; this->MakeUpTodate(vp); IGENERICPROP_RENDER(RenderOpaqueGeometry); return ret; } #ifdef IVTK_PRE52 template int iGenericProp::RenderTranslucentGeometry(vtkViewport *vp) { int j, ret; this->MakeUpTodate(vp); IGENERICPROP_RENDER(RenderTranslucentGeometry); return ret; } #else template int iGenericProp::HasTranslucentPolygonalGeometry() { int j; if(mEnabled) { for(j=0; jGetVisibility() != 0) { if(mProps[j]->HasTranslucentPolygonalGeometry() != 0) return 1; } if(mSelf && this->Prop::HasTranslucentPolygonalGeometry()!=0) return 1; } return 0; } template int iGenericProp::RenderTranslucentPolygonalGeometry(vtkViewport *vp) { int j, ret; this->MakeUpTodate(vp); IGENERICPROP_RENDER(RenderTranslucentPolygonalGeometry); return ret; } template int iGenericProp::RenderVolumetricGeometry(vtkViewport *vp) { int j, ret; this->MakeUpTodate(vp); IGENERICPROP_RENDER(RenderVolumetricGeometry); return ret; } #endif template void iGenericProp::ReleaseGraphicsResources(vtkWindow *win) { int j; for(j=0; jReleaseGraphicsResources(win); } if(mSelf) this->Prop::ReleaseGraphicsResources(win); } template void iGenericProp::PrependComponent(vtkProp *p) { if(p!=0 && p!=this) { p->SetVisibility(1); mProps.Add(p); // // Reorder // int i; for(i=mProps.MaxIndex(); i>0; i--) { mProps[i] = mProps[i-1]; } mProps[0] = p; } } template void iGenericProp::AppendComponent(vtkProp *p) { if(p!=0 && p!=this) { p->SetVisibility(1); mProps.Add(p); } } template void iGenericProp::RemoveComponent(vtkProp *p) { mProps.Remove(p); } template void iGenericProp::RemoveAllComponents() { mProps.Clear(); } template void iGenericProp::ToggleComponent(vtkProp *p) { int j; for(j=0; jSetVisibility(0); } j = mProps.Find(p); if(j > -1) p->SetVisibility(1); } template void iGenericProp::ShowComponents(int n, vtkProp **p) { int i, j; for(j=0; jSetVisibility(0); } for(i=0; i -1) p[i]->SetVisibility(1); } } template void iGenericProp::Disable() { mEnabled = false; } ifrit-3.4.2/core/ihistogram.cpp0000755000175700010010000000445112167404431015015 0ustar HomeNone/*========================================================================= Program: Ionization FRont Interactive Tool (IFRIT) Language: C++ Copyright (c) 2002-2012 Nick Gnedin All rights reserved. This file may be distributed and/or modified under the terms of the GNU General Public License version 2 as published by the Free Software Foundation and appearing in the file LICENSE.GPL included in the packaging of this file. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHORS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. =========================================================================*/ #include "ihistogram.h" #include "ierror.h" #include "ihistogrammaker.h" // // Templates // #include "iarraytemplate.h" iHistogram* iHistogram::New(iViewModule *vm, iHistogramMaker *parent) { IERROR_ASSERT(vm); // parent can be zero return new iHistogram(vm,parent); } iHistogram::iHistogram(iViewModule *vm, iHistogramMaker *parent) : iPiecewiseFunction(0.0f,1.0f,100), mViewModule(vm), mPosMin(vm), mPosMax(vm) { mParent = parent; mStretch = 0; mValMin = mValMax = 0.0; mCellMin = mCellMax= -1; } iHistogram::~iHistogram() { } void iHistogram::Copy(const iHistogram *h) { iPiecewiseFunction::Copy(h); mStretch = h->mStretch; mValMin = h->mValMin; mValMax = h->mValMax; mCellMin = h->mCellMin; mCellMax = h->mCellMax; mPosMin = h->mPosMin; mPosMax = h->mPosMax; } void iHistogram::SetData(int n, float *values) { int i; mArr.Resize(n+2); mArr[0].X = 0.0f; mArr[0].Y = 0.0f; Point *ptr = const_cast(mArr.Data()) + 1; for(i=0; iMovePoint(n+1,1.0f,0.0f); } ifrit-3.4.2/core/ihistogram.h0000755000175700010010000000454412167404413014465 0ustar HomeNone/*========================================================================= Program: Ionization FRont Interactive Tool (IFRIT) Language: C++ Copyright (c) 2002-2012 Nick Gnedin All rights reserved. This file may be distributed and/or modified under the terms of the GNU General Public License version 2 as published by the Free Software Foundation and appearing in the file LICENSE.GPL included in the packaging of this file. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHORS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. =========================================================================*/ #ifndef IHISTOGRAM_H #define IHISTOGRAM_H #include "ipiecewisefunction.h" #include "iposition.h" class iHistogramMaker; class iHistogram : public iPiecewiseFunction { friend class iHistogramMaker; IPOINTER_AS_PART(ViewModule); public: static iHistogram* New(iViewModule *vm, iHistogramMaker *parent = 0); inline iHistogramMaker* GetMaker() const { return mParent; } int GetStretch() const { return mStretch; } float GetMinValue() const { return mValMin; } float GetMaxValue() const { return mValMax; } vtkIdType GetMinCellIndex() const { return mCellMin; } vtkIdType GetMaxCellIndex() const { return mCellMax; } const iPosition& GetMinCellPosition() const { return mPosMin; } const iPosition& GetMaxCellPosition() const { return mPosMax; } void Copy(const iHistogram *h); protected: virtual ~iHistogram(); private: iHistogram(iViewModule *vm, iHistogramMaker *parent); void SetData(int n, float *values); iHistogramMaker *mParent; float mValMin, mValMax; int mStretch; // // Properties of the Min and Max cells // vtkIdType mCellMin, mCellMax; iPosition mPosMin, mPosMax; }; #endif ifrit-3.4.2/core/ihistogrammaker.cpp0000755000175700010010000003444512167404431016043 0ustar HomeNone/*========================================================================= Program: Ionization FRont Interactive Tool (IFRIT) Language: C++ Copyright (c) 2002-2012 Nick Gnedin All rights reserved. This file may be distributed and/or modified under the terms of the GNU General Public License version 2 as published by the Free Software Foundation and appearing in the file LICENSE.GPL included in the packaging of this file. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHORS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. =========================================================================*/ #include "ihistogrammaker.h" #include "icommoneventobservers.h" #include "idatalimits.h" #include "ierror.h" #include "ihistogram.h" #include "imath.h" #include "iparallel.h" #include "iparallelmanager.h" #include "iviewmodule.h" #include #include #include #include #include #include //------------------------------------------------------------------------------ iHistogramMaker* iHistogramMaker::New(iViewModule *vm) { IERROR_ASSERT(vm); return new iHistogramMaker(vm); } // Construct object to extract all of the input data. iHistogramMaker::iHistogramMaker(iViewModule *vm) : iParallelWorker(vm->GetParallelManager()), mViewModule(vm), mLowResBins(256), mLowResSize(mLowResBins*mLowResBins) { mHisto = iHistogram::New(this->GetViewModule(),this); IERROR_ASSERT(mHisto); mNumProcs = mNumBins = 0; mDataRank = 0; mFullResolution = mSupportsFullResolution = false; mRanges = 0; mValues = 0; mComponent = -1; mProgressStart = 0.0; mProgressLength = 1.0; mAttached = true; this->SetNumberOfInputConnections(0,1); this->AddObserver(vtkCommand::StartEvent,vm->GetProgressEventObserver()); this->AddObserver(vtkCommand::ProgressEvent,vm->GetProgressEventObserver()); this->AddObserver(vtkCommand::EndEvent,vm->GetProgressEventObserver()); } iHistogramMaker::~iHistogramMaker() { if(mAttached) mHisto->Delete(); if(mRanges != 0) { delete [] mRanges; } if(mValues != 0) { for(int i=0; iSetNthInput(0,input); this->SetInputComponent(c); } void iHistogramMaker::SetInputComponent(int c) { if(c != mComponent) { mComponent = c; this->Modified(); } } void iHistogramMaker::OnStretchChanged() { this->Modified(); } vtkDataSet* iHistogramMaker::GetInput() { if(this->Inputs == 0) return 0; else return vtkDataSet::SafeDownCast(this->Inputs[0]); } void iHistogramMaker::SetDataRank(int r) { if(r>=0 && r<=2 && r!=mDataRank) { mDataRank = r; this->Modified(); } } void iHistogramMaker::SetFullResolution(bool s) { if(mFullResolution != s) { mFullResolution = s; this->Modified(); } } int iHistogramMaker::GetEstimatedNumberOfBins() { if(this->GetInput() == 0) { mSupportsFullResolution = false; return 0; } else { int nb = round(1.0+sqrt((float)this->GetNumberOfCells())); if(nb > mLowResBins) { mSupportsFullResolution = true; if(!mFullResolution) nb = mLowResBins; } else mSupportsFullResolution = false; return nb; } } void iHistogramMaker::SetProgressRange(float start, float length) { if(start>=0.0 && start<1.0) mProgressStart = start; if(length > 0.0) mProgressLength = length; if(mProgressStart+mProgressLength > 1.0) mProgressLength = 1.0 - mProgressStart; } void iHistogramMaker::Update() { // // Force to recompute if needed // this->GetHistogram(); } bool iHistogramMaker::ComputeRange() { if(!this->IsDataPresent()) return false; // // Do we need to recompute? // if(this->GetInput()->GetMTime()>mComputeRangeTime || this->GetMTime()>mComputeRangeTime) { // // Recompute the limits // int i; if(mNumProcs != this->GetManager()->GetNumberOfProcessors()) { if(mRanges != 0) delete [] mRanges; mNumProcs = this->GetManager()->GetNumberOfProcessors(); mRanges = new Range[mNumProcs]; if(mRanges == 0) { return false; } } for(i=0; iPrepareForPass() || this->ParallelExecute(1)!=0) { return false; } mHisto->mValMin = mRanges[0].ValMin; mHisto->mValMax = mRanges[0].ValMax; mHisto->mCellMin = mRanges[0].CellMin; mHisto->mCellMax = mRanges[0].CellMax; for(i=1; imValMin > mRanges[i].ValMin) { mHisto->mValMin = mRanges[i].ValMin; mHisto->mCellMin = mRanges[i].CellMin; } if(mHisto->mValMax < mRanges[i].ValMax) { mHisto->mValMax = mRanges[i].ValMax; mHisto->mCellMax = mRanges[i].CellMax; } } this->FindPositionForCell(mHisto->mCellMin,mHisto->mPosMin); this->FindPositionForCell(mHisto->mCellMax,mHisto->mPosMax); // // Spread values a little bit if needed // if(mHisto->mValMax-mHisto->mValMin < 0.01*(fabs(mHisto->mValMax)+fabs(mHisto->mValMin))) { if(mHisto->mValMin < 0) mHisto->mValMin *= 1.001; else mHisto->mValMin *= 0.999; if(mHisto->mValMax < 0) mHisto->mValMax *= 0.999; else mHisto->mValMax *= 1.001; } // // Update the time // mComputeRangeTime.Modified(); } return true; } void iHistogramMaker::GetHistogramRange(float &min, float &max) { if(this->ComputeRange()) { min = mHisto->mValMin; max = mHisto->mValMax; } } void iHistogramMaker::GetHistogramRange(float &valMin, vtkIdType &cellMin, const iPosition* &posMin, float &valMax, vtkIdType &cellMax, const iPosition* &posMax) { if(this->ComputeRange()) { valMin = mHisto->mValMin; posMin = &mHisto->mPosMin; cellMin = mHisto->mCellMin; valMax = mHisto->mValMax; posMax = &mHisto->mPosMax; cellMax = mHisto->mCellMax; } } const iHistogram* iHistogramMaker::GetHistogram(int nBins) { if(this->ComputeRange()) { return this->GetHistogram(nBins,mHisto->mValMin,mHisto->mValMax); } else { return 0; } } const iHistogram* iHistogramMaker::GetHistogram(int nBins, float vMin, float vMax) { int i, j; if(!this->IsDataPresent()) return 0; if(nBins<-1 || nBins>1000000 || vMin>vMax || this->GetInput()==0) return 0; // // No need to recompute // if(nBins == 0) nBins = this->GetEstimatedNumberOfBins(); if(nBins==mNumBins && vMin==mHisto->mValMin && vMax==mHisto->mValMax && this->GetInput()->GetMTime()GetMTime()GetManager()->GetNumberOfProcessors() || nBins!=mNumBins) { int i; if(mValues != 0) { for(i=0; iGetManager()->GetNumberOfProcessors(); mValues = new double*[mNumProcs]; if(mValues == 0) { return 0; } memset(mValues,0,mNumProcs*sizeof(double *)); for(i=0; imValMin = vMin; mHisto->mValMax = vMax; mHisto->mStretch = this->GetStretch(); if(!this->PrepareForPass()) return 0; this->ParallelExecute(2); for(i=0; iSetData(mNumBins,tmp); delete [] tmp; // // Update the time // mComputeTime.Modified(); return mHisto; } int iHistogramMaker::ExecuteStep(int step, iParallel::ProcessorInfo &p) { if(p.NumProcs != mNumProcs) { IERROR_LOW("Error calling iHistogramMaker in parallel."); return -1; } vtkIdType ntup = this->GetNumberOfCells(); vtkIdType l, lbeg, lend, lstp, linc = 1; float v, vmin, vmax; int ret = 999; // // Distribute data // iParallel::SplitRange(p,ntup,lbeg,lend,lstp); if(!mFullResolution) linc = (lend-lbeg+mLowResSize-1)/mLowResSize; if(mFullResolution && this->IsMaster(p)) { this->GetViewModule()->GetProgressEventObserver()->SetMode(iProgressEventObserver::_Computing); this->InvokeEvent(vtkCommand::StartEvent); } // // Recompute the limits // if(step == 1) { vtkIdType lmin, lmax; for(l=lbeg; lIsValidIndex(l)) { vmin = vmax = this->GetValue(l); lmin = lmax = l; break; } l += linc; for(; lIsValidIndex(l)) { if(l%1000 == 0) { if(mFullResolution && this->IsMaster(p)) { double p = mProgressStart + 0.2*mProgressLength*double(l-lbeg)/(lend-lbeg); this->InvokeEvent(vtkCommand::ProgressEvent,&p); } if(this->GetAbortExecute()) break; } v = this->GetValue(l); if(v < vmin) { vmin = v; lmin = l; } if(v > vmax) { vmax = v; lmax = l; } } mRanges[p.ThisProc].ValMin = vmin; mRanges[p.ThisProc].ValMax = vmax; mRanges[p.ThisProc].CellMin = lmin; mRanges[p.ThisProc].CellMax = lmax; ret = 0; } // // Compute the histogram // if(step == 2) { int iv; float vstp; vmin = this->ApplyStretch(mHisto->mValMin,false); vmax = this->ApplyStretch(mHisto->mValMax,true); vstp = 1.0001*(vmax-vmin)/mNumBins; double *d = mValues[p.ThisProc]; memset(d,0,sizeof(double)*mNumBins); for(l=lbeg; lIsValidIndex(l)) { if(l%1000 == 0) { if(mFullResolution && this->IsMaster(p)) { double p = mProgressStart + 0.2*mProgressLength + 0.8*mProgressLength*double(l-lbeg)/(lend-lbeg); this->InvokeEvent(vtkCommand::ProgressEvent,&p); } if(this->GetAbortExecute()) break; } v = this->ApplyStretch(this->GetValue(l),false); iv = round((v-vmin)/vstp-0.4999); if(iv>=0 && ivGetValueWeight(l); } } ret = 0; } if(mFullResolution && this->IsMaster(p)) this->InvokeEvent(vtkCommand::EndEvent); return ret; } vtkIdType iHistogramMaker::GetNumberOfCells() { vtkDataArray *d = 0; switch(mDataRank) { case 0U: { d = this->GetInput()->GetPointData()->GetScalars(); break; } case 1U: { d = this->GetInput()->GetPointData()->GetVectors(); break; } case 2U: { d = this->GetInput()->GetPointData()->GetTensors(); break; } } if(d == 0) return 0; else return d->GetNumberOfTuples(); } void iHistogramMaker::FindPositionForCell(vtkIdType cell, iPosition &pos) { int i; vtkImageData *id = vtkImageData::SafeDownCast(this->GetInput()); if(id != 0) { int dims[3], ijk[3]; double spa[3], org[3]; id->GetDimensions(dims); id->GetSpacing(spa); id->GetOrigin(org); ijk[2] = cell/(dims[0]*dims[1]); ijk[1] = (cell-dims[0]*dims[1]*ijk[2])/dims[0]; ijk[0] = cell % dims[0]; for(i=0; i<3; i++) pos[i] = org[i] + spa[i]*ijk[i]; } else { for(i=0; i<3; i++) pos[i] = 0.0; } } bool iHistogramMaker::IsDataPresent() { vtkDataSet *input = this->GetInput(); if(input == 0) return false; input->Update(); if(input->GetPointData() == 0) return false; switch(mDataRank) { case 0: { if(input->GetPointData()->GetScalars() == 0) return false; break; } case 1: { if(input->GetPointData()->GetVectors() == 0) return false; break; } case 2: { if(input->GetPointData()->GetTensors() == 0) return false; break; } default: { return false; } } return true; } bool iHistogramMaker::PrepareForPass() { vtkDataSet *input = this->GetInput(); if(input==0 || input->GetPointData()==0) return false; wDataPtr = 0; switch(mDataRank) { case 0: { if(input->GetPointData()->GetScalars() == 0) return false; // // Access the data for both vtkPolyData and vtkStructuredPoints // vtkFloatArray *arr = vtkFloatArray::SafeDownCast(input->GetPointData()->GetScalars()); if(arr == 0) return false; wDataPtr = arr->GetPointer(0); wNumCom = input->GetPointData()->GetScalars()->GetNumberOfComponents(); if(mComponent<0 || mComponent>=wNumCom) return false; break; } case 1: { if(input->GetPointData()->GetVectors() == 0) return false; // // Access the data for both vtkPolyData and vtkStructuredPoints // vtkFloatArray *arr = vtkFloatArray::SafeDownCast(input->GetPointData()->GetVectors()); if(arr == 0) return false; wDataPtr = arr->GetPointer(0); wNumCom = input->GetPointData()->GetVectors()->GetNumberOfComponents(); if(mComponent!=0 || wNumCom!=3) return false; break; } case 2: { if(input->GetPointData()->GetTensors() == 0) return false; // // Access the data for both vtkPolyData and vtkStructuredPoints // vtkFloatArray *arr = vtkFloatArray::SafeDownCast(input->GetPointData()->GetTensors()); if(arr == 0) return false; wDataPtr = arr->GetPointer(0); wNumCom = input->GetPointData()->GetTensors()->GetNumberOfComponents(); if(mComponent<0 || mComponent>2 || wNumCom!=9) return false; break; } default: { return false; } } if(wDataPtr == 0) return false; if(mDataRank == 0U) wDataPtr += mComponent; return true; } bool iHistogramMaker::IsValidIndex(vtkIdType) const { return true; // no holes in data } float iHistogramMaker::GetScalarValue(vtkIdType l) const { return wDataPtr[l*wNumCom]; } float iHistogramMaker::GetVectorValue(vtkIdType l) const { float *p = wDataPtr + l*wNumCom; return sqrt(p[0]*p[0]+p[1]*p[1]+p[2]*p[2]); } float iHistogramMaker::GetTensorValue(vtkIdType l) const { int i; float *p = wDataPtr + l*wNumCom; float *m[3], e[3], *v[3], store[9]; for(i=0; i<3; i++) { v[i] = store + 3*i; m[i] = p + 3*i; } vtkMath::Jacobi(m,e,v); return e[mComponent]; } double iHistogramMaker::GetValueWeight(vtkIdType) const { return 1.0; } ifrit-3.4.2/core/ihistogrammaker.h0000755000175700010010000001060012167404413015473 0ustar HomeNone/*========================================================================= Program: Ionization FRont Interactive Tool (IFRIT) Language: C++ Copyright (c) 2002-2012 Nick Gnedin All rights reserved. This file may be distributed and/or modified under the terms of the GNU General Public License version 2 as published by the Free Software Foundation and appearing in the file LICENSE.GPL included in the packaging of this file. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHORS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. =========================================================================*/ #ifndef IHISTOGRAMMAKER_H #define IHISTOGRAMMAKER_H #include #include "idatastretch.h" #include "iparallelworker.h" #include "iposition.h" class iHistogram; class vtkDataSet; class vtkFloatArray; class iHistogramMaker : public vtkProcessObject, public iDataStretchUser, protected iParallelWorker { IPOINTER_AS_PART(ViewModule); public: vtkTypeMacro(iHistogramMaker,vtkProcessObject); static iHistogramMaker* New(iViewModule *vm = 0); inline int GetCurrentNumberOfBins(){ return mNumBins; } inline int GetInputComponent(){ return mComponent; } virtual int GetEstimatedNumberOfBins(); virtual const iHistogram* GetHistogram(int nBins = 0); virtual const iHistogram* GetHistogram(int nBins, float vMin, float vMax); void GetHistogramRange(float &min, float &max); void GetHistogramRange(float &valMin, vtkIdType &cellMin, const iPosition* &posMin, float &valMax, vtkIdType &cellMax, const iPosition* &posMax); void SetFullResolution(bool s); inline bool GetFullResolution() const { return mFullResolution; } inline bool SupportsFullResolution() const { return mSupportsFullResolution; } virtual void SetInput(vtkDataSet *input, int c); virtual void SetInputComponent(int c); virtual vtkDataSet* GetInput(); void SetProgressRange(float start, float length); void AttachHistogram(bool s); void SetDataRank(int r); inline int GetDataRank() const { return mDataRank; } void Update(); protected: iHistogramMaker(iViewModule *vm); virtual ~iHistogramMaker(); virtual int ExecuteStep(int step, iParallel::ProcessorInfo &p); virtual void OnStretchChanged(); bool ComputeRange(); float GetValue(vtkIdType l) const; // // Inherit these functions // virtual bool IsDataPresent(); virtual vtkIdType GetNumberOfCells(); virtual void FindPositionForCell(vtkIdType cell, iPosition &pos); virtual bool PrepareForPass(); virtual bool IsValidIndex(vtkIdType l) const; virtual float GetScalarValue(vtkIdType l) const; virtual float GetVectorValue(vtkIdType l) const; virtual float GetTensorValue(vtkIdType l) const; virtual double GetValueWeight(vtkIdType l) const; protected: int mComponent; private: const int mLowResBins, mLowResSize; bool mAttached, mFullResolution, mSupportsFullResolution; iHistogram *mHisto; int mNumProcs, mNumBins; int mDataRank; float mProgressStart, mProgressLength; // // MTime for the last calculation of the histogram - need to keep track of it // separately so that other changes to this class do not hide the change in the input data. // vtkTimeStamp mComputeTime, mComputeRangeTime; // // Persisting helper variables // struct Range { float ValMax; float ValMin; vtkIdType CellMax; vtkIdType CellMin; } *mRanges; double **mValues; // // Work variables // float *wDataPtr; vtkIdType wNumCom; }; // // Inline to allow a smart compiler to take the switch out of inner loops // inline float iHistogramMaker::GetValue(vtkIdType l) const { switch(mDataRank) { case 0U: { return this->GetScalarValue(l); } case 1U: { return this->GetVectorValue(l); } case 2U: { return this->GetTensorValue(l); } default: { return 0.0f; } } } #endif ifrit-3.4.2/core/iidentityfilter.cpp0000755000175700010010000000307012167404431016053 0ustar HomeNone/*========================================================================= Program: Ionization FRont Interactive Tool (IFRIT) Language: C++ Copyright (c) 2002-2012 Nick Gnedin All rights reserved. This file may be distributed and/or modified under the terms of the GNU General Public License version 2 as published by the Free Software Foundation and appearing in the file LICENSE.GPL included in the packaging of this file. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHORS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. =========================================================================*/ #include "iidentityfilter.h" // // Templates // #include "igenericfiltertemplate.h" iIdentityFilter::iIdentityFilter(iViewSubject *vo) : iGenericFilter(vo,1,false,false) { } void iIdentityFilter::ProduceOutput() { this->GetOutput()->ShallowCopy(this->GetInput()); } ifrit-3.4.2/core/iidentityfilter.h0000644000175700010010000000324412167404413015520 0ustar HomeNone/*========================================================================= Program: Ionization FRont Interactive Tool (IFRIT) Language: C++ Copyright (c) 2002-2012 Nick Gnedin All rights reserved. This file may be distributed and/or modified under the terms of the GNU General Public License version 2 as published by the Free Software Foundation and appearing in the file LICENSE.GPL included in the packaging of this file. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHORS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. =========================================================================*/ // // A filter that ShallowCopy-ies its input into its output // #ifndef IIDENTITYFILTER_H #define IIDENTITYFILTER_H #include "igenericfilter.h" #include class iIdentityFilter : public iGenericFilter { IGENERICFILTER_DECLARE(iIdentityFilter,vtkDataSetToDataSetFilter); protected: virtual void ProduceOutput(); }; #endif // IIDENTITYFILTER_H ifrit-3.4.2/core/iimage.cpp0000755000175700010010000003677012167404431014113 0ustar HomeNone/*========================================================================= Program: Ionization FRont Interactive Tool (IFRIT) Language: C++ Copyright (c) 2002-2012 Nick Gnedin All rights reserved. This file may be distributed and/or modified under the terms of the GNU General Public License version 2 as published by the Free Software Foundation and appearing in the file LICENSE.GPL included in the packaging of this file. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHORS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. =========================================================================*/ #include "iimage.h" #include "icolor.h" #include "ierror.h" #include "imath.h" #include #include #include #include #include #include #include #include #include #include #include iImage::iImage(int depth) { if(depth<1 || depth>4) { IERROR_LOW("Incorrect number of image components"); depth = 3; } mData = 0; mDepth = depth; mWidth = mHeight = 0; } iImage::iImage(const iImage& img) { mData = img.mData; if(mData != 0) { mData->Register(0); mDepth = img.mDepth; mWidth = img.mWidth; mHeight = img.mHeight; } else { mDepth = 3; mWidth = mHeight = 0; } } iImage::~iImage() { if(mData != 0) mData->Delete(); } vtkImageData* iImage::CreateData(int depth) { vtkImageData *tmp; if(depth<1 || depth>4) { IERROR_LOW("Incorrect number of image components"); depth = 3; } tmp = vtkImageData::New(); IERROR_ASSERT(tmp); tmp->SetScalarTypeToUnsignedChar(); tmp->SetNumberOfScalarComponents(depth); tmp->SetOrigin(0.0,0.0,0.0); tmp->SetSpacing(1.0,1.0,1.0); return tmp; } void iImage::Allocate(vtkImageData *d, int w, int h) { if(d != 0) { d->SetDimensions(w,h,1); d->AllocateScalars(); } } unsigned char* iImage::DataPointer() const { if(mData != 0) return (unsigned char *)mData->GetScalarPointer(); else return 0; } void iImage::SetDataPointer(unsigned char* array, int w, int h, int d) { if(w>0 && h>0) { if(mData != 0) mData->Delete(); mData = CreateData(d); mData->SetDimensions(w,h,1); mDepth = mData->GetNumberOfScalarComponents(); vtkUnsignedCharArray *a; if(mData->GetPointData()->GetScalars()==0 || (a = vtkUnsignedCharArray::SafeDownCast(mData->GetPointData()->GetScalars()))==0) { a = vtkUnsignedCharArray::New(); IERROR_ASSERT(a); mData->GetPointData()->SetScalars(a); a->Delete(); } a->SetNumberOfComponents(mDepth); a->SetArray(array,mDepth*w*h,1); mWidth = w; mHeight = h; } } void iImage::Clear() { mDepth = 3; mWidth = mHeight = 0; if(mData != 0) { mData->Delete(); mData = 0; } } bool iImage::LoadFromFile(const iString &filename) { return LoadFromFile(filename,*this); } bool iImage::LoadFromFile(const iString &filename, iImage &image) { iString suf = filename.Section(".",-1).Lower(); vtkImageReader2 *ir = 0; if(suf=="jpg" || suf=="jpeg") { ir = vtkJPEGReader::New(); IERROR_ASSERT(ir); } if(suf == "pnm") { ir = vtkPNMReader::New(); IERROR_ASSERT(ir); } if(suf == "bmp") { ir = vtkBMPReader::New(); IERROR_ASSERT(ir); } if(suf=="tif" || suf=="tiff") { ir = vtkTIFFReader::New(); IERROR_ASSERT(ir); } if(suf == "png") { ir = vtkPNGReader::New(); IERROR_ASSERT(ir); } if(ir!=0 && ir->CanReadFile(filename.ToCharPointer())==3) { ir->SetFileName(filename.ToCharPointer()); ir->SetDataScalarTypeToUnsignedChar(); ir->Update(); if(image.mData != 0) image.mData->Delete(); image.mData = ir->GetOutput(); image.mData->Register(0); image.mDepth = image.mData->GetNumberOfScalarComponents(); int dims[3]; image.mData->GetDimensions(dims); image.mWidth = dims[0]; image.mHeight = dims[1]; ir->Delete(); return true; } else return false; } void iImage::Blend(const iImage& im, float op) { vtkImageBlend* iblend; if(mData==0 || im.mData==0) return; if(op < 0.0) op = 0.0; if(op > 1.0) op = 1.0; iblend = vtkImageBlend::New(); if(iblend == 0) return; iblend->SetInput(0,im.mData); iblend->SetInput(1,mData); iblend->SetOpacity(1,(double)op); iblend->Update(); mData->Delete(); mData = iblend->GetOutput(); mData->Register(0); iblend->Delete(); } void iImage::ReplaceData(vtkImageData *newdata) { if(newdata == 0) { this->Clear(); return; } int dims[3]; newdata->GetDimensions(dims); mDepth = newdata->GetNumberOfScalarComponents(); mWidth = dims[0]; mHeight = dims[1]; // // We need to actually copy the data, not just link it here, since if the data object // changes, we would have no way of knowing it. // if(mData == 0) mData = CreateData(newdata->GetNumberOfScalarComponents()); mData->DeepCopy(newdata); } void iImage::Overlay(int x, int y, const iImage& ovr, float opacity, bool masking) { if(mData==0 || ovr.mData==0 || x<=-ovr.mWidth || x>=mWidth || y<=-ovr.mHeight || y>=mHeight || mDepth!=ovr.Depth()) return; if(opacity < 0.0) opacity = 0.0; if(opacity > 1.0) opacity = 1.0; if(mData->GetReferenceCount() > 1) { vtkImageData *tmp; tmp = vtkImageData::New(); if(tmp == 0) return; tmp->DeepCopy(mData); mData->Delete(); mData = tmp; } // // tmp is now the proper image // int k, j, i, joff, ioff; unsigned long lImage, lOvlay; unsigned char *iPtr = (unsigned char *)mData->GetScalarPointer(); unsigned char *oPtr = (unsigned char *)ovr.mData->GetScalarPointer(); // // totally transparent colors // unsigned char tc[4]; for(k=0; k=0 && joff0.9999) { k = ovr.mWidth; if(x+k > mWidth) k = mWidth - x; lImage = mDepth*(x+(unsigned long)mWidth*joff); lOvlay = mDepth*(0+(unsigned long)ovr.mWidth*j); memcpy(iPtr+lImage,oPtr+lOvlay,mDepth*(unsigned long)k); } else { for(i=0; i=0 && ioffDelete(); mData = img.mData; if(mData != 0) { mData->Register(0); mDepth = img.mDepth; mWidth = img.mWidth; mHeight = img.mHeight; } else { mDepth = 3; mWidth = mHeight = 0; } return *this; } bool operator==(const iImage &s1, const iImage &s2) { if(s1.mDepth != s2.mDepth) return false; if(s1.mWidth != s2.mWidth) return false; if(s1.mHeight != s2.mHeight) return false; if(s1.mData == s2.mData) return true; if(s1.mData==0 || s2.mData==0) return false; unsigned long i, n = s1.mDepth*s1.mWidth*s1.mHeight; unsigned char *p1 = (unsigned char *)s1.mData->GetScalarPointer(); unsigned char *p2 = (unsigned char *)s2.mData->GetScalarPointer(); if(p1 == p2) return true; if(p1==0 || p2==0) return false; for(i=0; iClear(); return; } if(this->IsEmpty()) { mWidth = w; mHeight = h; mData = CreateData(mDepth); Allocate(mData,w,h); memset(mData->GetScalarPointer(),0,mDepth*w*h); return; } switch(m) { case _Fit: { fx = (float)w/mWidth; fy = (float)h/mHeight; if(fx < fy) fy = fx; w = round(fy*mWidth); h = round(fy*mHeight); break; } case _Include: { fx = (float)w/mWidth; fy = (float)h/mHeight; if(fx < fy) fx = fy; w = round(fx*mWidth); h = round(fx*mHeight); break; } case _FitMin: { fx = (float)w/mWidth; fy = (float)h/mHeight; if(fx < fy) fy = fx; if(fy > 1.0) fy = 1.0; w = round(fy*mWidth); h = round(fy*mHeight); break; } case _Both: { break; } } // // w and h are now proper size. Scale linearly first. // vtkImageData *tmp = CreateData(mDepth); Allocate(tmp,w,h); unsigned char *sPtr = (unsigned char *)mData->GetScalarPointer(); unsigned char *dPtr = (unsigned char *)tmp->GetScalarPointer(); fx = (float)mWidth/w; fy = (float)mHeight/h; int *i0l = new int[w]; IERROR_ASSERT(i0l); int *i0s = new int[w]; IERROR_ASSERT(i0s); float *x0l = new float[w]; IERROR_ASSERT(x0l); float *x0s = new float[w]; IERROR_ASSERT(x0s); int *j0l = new int[h]; IERROR_ASSERT(j0l); int *j0s = new int[h]; IERROR_ASSERT(j0s); float *y0l = new float[h]; IERROR_ASSERT(y0l); float *y0s = new float[h]; IERROR_ASSERT(y0s); int i, j, k; float v, x0, y0, x1, y1, dx, dy; for(j=0; j=mHeight) { IERROR_LOW("Corrupted image."); return; } dy = y0 - 0.5 - j0l[j]; if(dy > 0.0) { j0s[j] = j0l[j] + 1; if(j0s[j] >= mHeight) j0s[j] = j0l[j]; y0l[j] = 1.0 - dy; y0s[j] = dy; } else { j0s[j] = j0l[j] - 1; if(j0s[j] < 0) j0s[j] = j0l[j]; y0l[j] = 1.0 + dy; y0s[j] = -dy; } } for(i=0; i=mWidth) { IERROR_LOW("Corrupted image."); return; } dx = x0 - 0.5 - i0l[i]; if(dx > 0.0) { i0s[i] = i0l[i] + 1; if(i0s[i] >= mWidth) i0s[i] = i0l[i]; x0l[i] = 1.0 - dx; x0s[i] = dx; } else { i0s[i] = i0l[i] - 1; if(i0s[i] < 0) i0s[i] = i0l[i]; x0l[i] = 1.0 + dx; x0s[i] = -dx; } } for(j=0; j 255.0) v = 255.0; dPtr[k+mDepth*(i+w*j)] = (unsigned char)round(v); } } } delete [] i0l; delete [] i0s; delete [] x0l; delete [] x0s; delete [] j0l; delete [] j0s; delete [] y0l; delete [] y0s; mWidth = w; mHeight = h; mData->Delete(); mData = tmp; if(f == _None) return; this->Smooth(1.0,1.0); } void iImage::Smooth(float dx, float dy) { vtkImageGaussianSmooth *filter = vtkImageGaussianSmooth::New(); filter->SetDimensionality(3); filter->SetStandardDeviations(dx,dy,0.0); filter->SetRadiusFactors(1.0*dx,1.0*dy,1.0); // exp(-0.5*3.3^2) = 1/255 filter->SetInput(mData); filter->Update(); if(mData != 0) mData->Delete(); mData = filter->GetOutput(); mData->Register(0); filter->Delete(); } bool iImage::CombineInPseudoColor(const iImage &imRed, const iImage &imGreen, const iImage &imBlue) { bool rIn(!imRed.IsEmpty()), gIn(!imGreen.IsEmpty()), bIn(!imBlue.IsEmpty()); int d = 0, w = 0, h = 0; if(rIn) { d = imRed.Depth(); w = imRed.Width(); h = imRed.Height(); } if(gIn) { if(d == 0) { d = imGreen.Depth(); w = imGreen.Width(); h = imGreen.Height(); } else { if(d != imGreen.Depth()) return false; if(w != imGreen.Width()) return false; if(h != imGreen.Height()) return false; } } if(bIn) { if(d == 0) { d = imBlue.Depth(); w = imBlue.Width(); h = imBlue.Height(); } else { if(d != imBlue.Depth()) return false; if(w != imBlue.Width()) return false; if(h != imBlue.Height()) return false; } } if((d!=3 && d!=4) || w==0 || h==0) return false; // no non-empty image is specified // // Reset the data // this->Clear(); mWidth = w; mHeight = h; mDepth = d; mData = CreateData(d); Allocate(mData,w,h); unsigned char *dPtr1, *dPtr2, *dPtr = this->DataPointer(); unsigned char *rPtr1, *rPtr2, *rPtr = imRed.DataPointer(); unsigned char *gPtr1, *gPtr2, *gPtr = imGreen.DataPointer(); unsigned char *bPtr1, *bPtr2, *bPtr = imBlue.DataPointer(); // // Fill in the data // int i, j, a[3], aMax; for(j=0; j 3) { a[0] = rIn ? rPtr2[3] : 0; a[1] = gIn ? gPtr2[3] : 0; a[2] = bIn ? bPtr2[3] : 0; aMax = (a[0] > a[1]) ? a[0] : a[1]; aMax = (a[2] > aMax) ? a[2] : aMax; } else { aMax = a[0] = a[1] = a[2] = 255; } // // Combine // dPtr2[0] = rIn ? (a[0]*(int(rPtr2[0])+int(rPtr2[1])+int(rPtr2[2])))/(3*aMax) : 0; dPtr2[1] = gIn ? (a[1]*(int(gPtr2[0])+int(gPtr2[1])+int(gPtr2[2])))/(3*aMax) : 0; dPtr2[2] = bIn ? (a[2]*(int(bPtr2[0])+int(bPtr2[1])+int(bPtr2[2])))/(3*aMax) : 0; if(d > 3) dPtr2[3] = aMax; } } return true; } void iImage::Crop(int x, int y, int w, int h) { if(x < 0) x = 0; if(y < 0) y = 0; if(x+w > mWidth) w = mWidth - x; if(y+h > mHeight) h = mHeight - y; // // Do nothing is we don't actually crop anything // if(x==0 && y==0 && w==mWidth && h==mHeight) return; vtkImageData *tmp = this->CreateData(mDepth); tmp->SetDimensions(w,h,1); tmp->AllocateScalars(); int j; vtkIdType line = mDepth*w; for(j=0; jGetScalarPointer(0,j,0),mData->GetScalarPointer(x,y+j,0),line); } mWidth = w; mHeight = h; mData->Delete(); mData = tmp; } void iImage::DrawFrame(int width, const iColor &color) { if(this->IsEmpty()) return; int i, j, k; unsigned char *ptr, *ptr0 = (unsigned char *)mData->GetScalarPointer(); unsigned char c[4]; if(width > (mWidth+1)/2) width = (mWidth+1)/2; if(width > (mHeight+1)/2) width = (mHeight+1)/2; c[0] = (unsigned char)color.Red(); c[1] = (unsigned char)color.Green(); c[2] = (unsigned char)color.Blue(); c[3] = (unsigned char)color.Alpha(); for(j=0; j tmp; for(j=0; jUpdateSize(); this->ClearCache(); } void iImageComposer::AddForegroundWindow(iViewModule *v) { if(v == 0) return; mForegroundWindows.Add(iImageComposerForegroundWindow::New(v,this)); this->ClearCache(); } void iImageComposer::RemoveForegroundWindow(int n) { if(n<0 || n>=mForegroundWindows.Size()) return; delete mForegroundWindows[n]; mForegroundWindows.Remove(n); this->ClearCache(); } void iImageComposer::MoveToBack(int n) { if(n<0 || n>=mForegroundWindows.MaxIndex()) return; int i; iImageComposerForegroundWindow *tmp = mForegroundWindows[n]; for(i=n; iClearCache(); } void iImageComposer::SetScaleBackground(bool s) { if(s != mScaleBackground) { mScaleBackground = s; this->UpdateSize(); this->ClearCache(); } } void iImageComposer::SetInnerBorder(bool s) { if(s != mInnerBorder) { mInnerBorder = s; this->UpdateSize(); this->ClearCache(); } } void iImageComposer::SetBorderWidth(int s) { if(s >= 0) { mBorderWidth = s; this->UpdateSize(); this->ClearCache(); } } void iImageComposer::SetBorderColor(const iColor &c) { if(c != mBorderColor) { mBorderColor = c; this->ClearCache(); } } void iImageComposer::Update() { this->UpdateWindowList(); this->UpdateSize(); } void iImageComposer::UpdateSize() { if(mBlockUpdate) return; int i; // // Compute real size // mTileWidth = mTileHeight = 0; for(i=0; iGetWindowWidth()) mTileWidth = mBackgroundWindows[i]->GetWindowWidth(); if(mTileHeight < mBackgroundWindows[i]->GetWindowHeight()) mTileHeight = mBackgroundWindows[i]->GetWindowHeight(); } if(mTileWidth==0 || mTileHeight==0) { for(i=0; iGetControlModule()->GetNumberOfViewModules(); i++) { if(mTileWidth < this->GetControlModule()->GetViewModule(i)->GetThisImageWidth()) mTileWidth = this->GetControlModule()->GetViewModule(i)->GetThisImageWidth(); if(mTileHeight < this->GetControlModule()->GetViewModule(i)->GetThisImageHeight()) mTileHeight = this->GetControlModule()->GetViewModule(i)->GetThisImageHeight(); } } mFullWidth = mNumTilesX*mTileWidth + 2*mBorderWidth; mFullHeight = mNumTilesY*mTileHeight + 2*mBorderWidth; if(mInnerBorder) { mFullWidth += (mNumTilesX-1)*mBorderWidth; mFullHeight += (mNumTilesY-1)*mBorderWidth; } // // Make sure no foreground window moves out of image area // for(i=0; iCorrectPosition(); } } void iImageComposer::UpdateWindowList() { int i; for(i=0; iUpdateWindow(); for(i=0; iUpdateWindow(); if(mForegroundWindows[i]->GetViewModule() == 0) this->RemoveForegroundWindow(i); } } iImageComposerBackgroundWindow* iImageComposer::GetBackgroundWindow(int i) const { if(i>=0 && i=0 && iPackValue(s,KeyScaleBackground(),mScaleBackground); this->PackValue(s,KeyInnerBorder(),mInnerBorder); this->PackValue(s,KeyBorderColor(),mBorderColor); this->PackValue(s,KeyBorderWidth(),mBorderWidth); this->PackValue(s,KeyImageWidth(),mFullWidth); this->PackValue(s,KeyImageHeight(),mFullHeight); iv[0] = mNumTilesX; iv[1] = mNumTilesY; this->PackValue(s,KeyNumTiles(),iv,2); this->PackValue(s,KeyNumForegroundWindows(),mForegroundWindows.Size()); int *itmp = new int[mBackgroundWindows.Size()]; IERROR_ASSERT(itmp); for(i=0; iGetWindowNumber(0); this->PackValue(s,KeyBackgroundWindowViewModule(),itmp,mBackgroundWindows.Size()); for(i=0; iGetWindowNumber(1); this->PackValue(s,KeyBackgroundWindowViewModule2(),itmp,mBackgroundWindows.Size()); for(i=0; iGetWindowNumber(2); this->PackValue(s,KeyBackgroundWindowViewModule3(),itmp,mBackgroundWindows.Size()); iString *stmp = new iString[mBackgroundWindows.Size()]; IERROR_ASSERT(stmp); for(i=0; iGetWallpaperFile(); this->PackValue(s,KeyBackgroundWindowWallpaperFile(),stmp,mBackgroundWindows.Size()); delete [] stmp; // // We need the keys to be present even if there are no windows, so that QueryValue functions // do not fail // int n = mForegroundWindows.Size(); if(n == 0) n++; if(n > mBackgroundWindows.Size()) { delete [] itmp; itmp = new int[n]; IERROR_ASSERT(itmp); } float *ftmp = new float[n]; IERROR_ASSERT(ftmp); bool *btmp = new bool[n]; IERROR_ASSERT(btmp); if(mForegroundWindows.Size() == 0) { itmp[0] = 0; ftmp[0] = 1.0; btmp[0] = true; } for(i=0; iGetWindowNumber(0); this->PackValue(s,KeyForegroundWindowViewModule(),itmp,n); for(i=0; iGetWindowNumber(1); this->PackValue(s,KeyForegroundWindowViewModule2(),itmp,n); for(i=0; iGetWindowNumber(2); this->PackValue(s,KeyForegroundWindowViewModule3(),itmp,n); for(i=0; iGetPositionX(); this->PackValue(s,KeyForegroundWindowPositionX(),itmp,n); for(i=0; iGetPositionY(); this->PackValue(s,KeyForegroundWindowPositionY(),itmp,n); for(i=0; iGetBorderWidth(); this->PackValue(s,KeyForegroundWindowBorderWidth(),itmp,n); iColor *ctmp = new iColor[n]; IERROR_ASSERT(ctmp); for(i=0; iGetBorderColor(); this->PackValue(s,KeyForegroundWindowBorderColor(),ctmp,n); delete [] ctmp; for(i=0; iGetScale(); this->PackValue(s,KeyForegroundWindowScale(),ftmp,n); for(i=0; iGetZoomSource() == 0) { itmp[i] = 0; } else { itmp[i] = mForegroundWindows[i]->GetZoomSource()->GetId(); } } this->PackValue(s,KeyForegroundWindowZoomSource(),itmp,n); for(i=0; iGetZoomFlag() == iImageComposerForegroundWindow::_4Lines); this->PackValue(s,KeyForegroundWindowZoom4Line(),btmp,n); for(i=0; iGetZoomX(); this->PackValue(s,KeyForegroundWindowZoomX(),ftmp,n); for(i=0; iGetZoomY(); this->PackValue(s,KeyForegroundWindowZoomY(),ftmp,n); for(i=0; iGetZoomFactor(); this->PackValue(s,KeyForegroundWindowZoomFactor(),ftmp,n); delete [] btmp; delete [] ftmp; delete [] itmp; } void iImageComposer::UnPackStateBody(const iString &s) { int i, iv[2]; bool b; iColor c; mBlockUpdate = true; if(this->UnPackValue(s,KeyScaleBackground(),b)) this->SetScaleBackground(b); if(this->UnPackValue(s,KeyInnerBorder(),b)) this->SetInnerBorder(b); if(this->UnPackValue(s,KeyBorderColor(),c)) this->SetBorderColor(c); if(this->UnPackValue(s,KeyBorderWidth(),i)) this->SetBorderWidth(i); iv[0] = mNumTilesX; iv[1] = mNumTilesY; if(this->UnPackValue(s,KeyNumTiles(),iv,2)) this->SetNumTiles(iv[0],iv[1]); if(this->UnPackValue(s,KeyNumForegroundWindows(),i)) { while(i < mForegroundWindows.Size()) this->RemoveForegroundWindow(i); while(i > mForegroundWindows.Size()) this->AddForegroundWindow(this->GetControlModule()->GetViewModule()); } int *itmp = new int[mBackgroundWindows.Size()]; IERROR_ASSERT(itmp); this->UnPackingHelper(mBackgroundWindows.Size(),0,(iImageComposerWindow**)mBackgroundWindows.Data(),itmp,KeyBackgroundWindowViewModule(),s); this->UnPackingHelper(mBackgroundWindows.Size(),1,(iImageComposerWindow**)mBackgroundWindows.Data(),itmp,KeyBackgroundWindowViewModule2(),s); this->UnPackingHelper(mBackgroundWindows.Size(),2,(iImageComposerWindow**)mBackgroundWindows.Data(),itmp,KeyBackgroundWindowViewModule3(),s); iString *stmp = new iString[mBackgroundWindows.Size()]; IERROR_ASSERT(stmp); for(i=0; iGetWallpaperFile(); if(this->UnPackValue(s,KeyBackgroundWindowWallpaperFile(),stmp,mBackgroundWindows.Size())) { for(i=0; iLoadWallpaperImage(stmp[i]); } delete [] stmp; // // All background windows are loaded. We can update now so that // position setting works. // mBlockUpdate = false; this->Update(); if(mForegroundWindows.Size() > 0) { if(mForegroundWindows.Size() > mBackgroundWindows.Size()) { delete [] itmp; itmp = new int[mForegroundWindows.Size()]; IERROR_ASSERT(itmp); } float *ftmp = new float[mForegroundWindows.Size()]; IERROR_ASSERT(ftmp); bool *btmp = new bool[mForegroundWindows.Size()]; IERROR_ASSERT(btmp); this->UnPackingHelper(mForegroundWindows.Size(),0,(iImageComposerWindow**)mForegroundWindows.Data(),itmp,KeyForegroundWindowViewModule(),s); this->UnPackingHelper(mForegroundWindows.Size(),1,(iImageComposerWindow**)mForegroundWindows.Data(),itmp,KeyForegroundWindowViewModule2(),s); this->UnPackingHelper(mForegroundWindows.Size(),2,(iImageComposerWindow**)mForegroundWindows.Data(),itmp,KeyForegroundWindowViewModule3(),s); for(i=0; iGetBorderWidth(); if(this->UnPackValue(s,KeyForegroundWindowBorderWidth(),itmp,mForegroundWindows.Size())) { for(i=0; iSetBorderWidth(itmp[i]); } iColor *ctmp = new iColor[mForegroundWindows.Size()]; IERROR_ASSERT(ctmp); for(i=0; iGetBorderColor(); if(this->UnPackValue(s,KeyForegroundWindowBorderColor(),ctmp,mForegroundWindows.Size())) { for(i=0; iSetBorderColor(ctmp[i]); } delete [] ctmp; for(i=0; iGetScale(); if(this->UnPackValue(s,KeyForegroundWindowScale(),ftmp,mForegroundWindows.Size())) { for(i=0; iSetScale(ftmp[i]); } for(i=0; iGetPositionX(); if(this->UnPackValue(s,KeyForegroundWindowPositionX(),itmp,mForegroundWindows.Size())) { for(i=0; iSetPositionX(itmp[i]); } for(i=0; iGetPositionY(); if(this->UnPackValue(s,KeyForegroundWindowPositionY(),itmp,mForegroundWindows.Size())) { for(i=0; iSetPositionY(itmp[i]); } // // As an optimization, load positions first, then the source, and then the height - loading the height // will adjust the position, but only once. // for(i=0; iGetZoomFlag() == iImageComposerForegroundWindow::_4Lines); if(this->UnPackValue(s,KeyForegroundWindowZoom4Line(),btmp,mForegroundWindows.Size())) { for(i=0; iSetZoomFlag(btmp[i]?iImageComposerForegroundWindow::_4Lines:1); } for(i=0; iGetZoomX(); if(this->UnPackValue(s,KeyForegroundWindowZoomX(),ftmp,mForegroundWindows.Size())) { for(i=0; iSetZoomPosition(ftmp[i],mForegroundWindows[i]->GetZoomY()); } for(i=0; iGetZoomY(); if(this->UnPackValue(s,KeyForegroundWindowZoomY(),ftmp,mForegroundWindows.Size())) { for(i=0; iSetZoomPosition(mForegroundWindows[i]->GetZoomX(),ftmp[i]); } for(i=0; iGetZoomSource() == 0) { itmp[i] = 0; } else { itmp[i] = mForegroundWindows[i]->GetZoomSource()->GetId(); } } if(this->UnPackValue(s,KeyForegroundWindowZoomSource(),itmp,mForegroundWindows.Size())) { for(i=0; iSetZoomSource(this->GetBackgroundWindow(-itmp[i]-1)); } else if(itmp[i] > 0) { mForegroundWindows[i]->SetZoomSource(this->GetForegroundWindow(itmp[i]-1)); } else { mForegroundWindows[i]->SetZoomSource(0); } } } for(i=0; iGetZoomFactor(); if(this->UnPackValue(s,KeyForegroundWindowZoomFactor(),ftmp,mForegroundWindows.Size())) { for(i=0; iSetZoomFactor(ftmp[i]); } delete [] ftmp; delete [] btmp; } delete [] itmp; } void iImageComposer::UnPackingHelper(int n, int j, iImageComposerWindow **win, int *itmp, const iObjectKey &key, const iString &s) { int i, k; for(i=0; iGetWindowNumber(j); if(this->UnPackValue(s,key,itmp,n)) { for(i=0; i=0 && itmp[i]!=win[i]->GetWindowNumber(j)) { for(k=0; kGetControlModule()->GetNumberOfViewModules() && itmp[i]!=this->GetControlModule()->GetViewModule(k)->GetWindowNumber(); k++); if(k < this->GetControlModule()->GetNumberOfViewModules()) win[i]->SetViewModule(this->GetControlModule()->GetViewModule(k),j); } } } bool iImageComposer::IsActive() { int i; // // Is there an active background window? // for(i=0; iIsEmpty()) return true; } // // Is there an active foreground window? // if(mForegroundWindows.Size() > 0) return true; // // At the very least, is there a border? // return mBorderWidth > 0; } void iImageComposer::Compose(iViewModule *vm, iStereoImageArray &images) { this->GetErrorStatus()->Clear(); if(vm == 0) { this->GetErrorStatus()->Set("No ViewModule is specified"); return; } mInComposing = true; // // We received a request to compose the images and put the data into images. // First, make sure that Composer is up to date // this->UpdateWindowList(); iStereoImage outIm; char rgb[3]; int i, j, k, xoff; unsigned char *dPtr, *dPtr1; outIm.Scale(mFullWidth,mFullHeight); dPtr = outIm.LeftEye().DataPointer(); int d = outIm.Depth(); bool work = false; if(mBorderWidth > 0) { work = true; // // Create the border // mBorderColor.GetRGB(rgb); // // Vertical lines // for(j=0; jIsEmpty()) { work = true; mBackgroundWindows[i]->Draw(outIm); } } // // Foreground windows // for(i=0; iIsEmpty()) { work = true; mForegroundWindows[i]->Draw(outIm); } } if(work) { images.Clear(); images.Add(outIm); } else { this->GetErrorStatus()->Monitor(vm->GetErrorStatus()); vm->RenderImages(images); } mInComposing = false; } ifrit-3.4.2/core/iimagecomposer.h0000755000175700010010000001137512167404413015322 0ustar HomeNone/*========================================================================= Program: Ionization FRont Interactive Tool (IFRIT) Language: C++ Copyright (c) 2002-2012 Nick Gnedin All rights reserved. This file may be distributed and/or modified under the terms of the GNU General Public License version 2 as published by the Free Software Foundation and appearing in the file LICENSE.GPL included in the packaging of this file. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHORS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. =========================================================================*/ #ifndef IIMAGECOMPOSER_H #define IIMAGECOMPOSER_H #include "iobject.h" #include "iarray.h" class iControlModule; class iImageComposerWindow; class iImageComposerBackgroundWindow; class iImageComposerForegroundWindow; class iStereoImageArray; class iViewModule; class iImageComposer : public iObject { IPOINTER_AS_PART(ControlModule); public: vtkTypeMacro(iImageComposer,iObject); static iImageComposer* New(iControlModule *cm = 0); static const iObjectType& Type(); IOBJECT_DECLARE_GETSET1(ScaleBackground,bool); IOBJECT_DECLARE_GETSET1(InnerBorder,bool); IOBJECT_DECLARE_GETSET1(BorderColor,const iColor&); IOBJECT_DECLARE_GETSET1(BorderWidth,int); IOBJECT_DECLARE_GET(ImageWidth,mFullWidth,int); IOBJECT_DECLARE_GET(ImageHeight,mFullHeight,int); int GetTileWidth() const { return mTileWidth; } int GetTileHeight() const { return mTileHeight; } void SetNumTiles(int nx, int ny); int GetNumTilesX() const { return mNumTilesX; } int GetNumTilesY() const { return mNumTilesY; } static const iObjectKey& KeyNumTiles(); int GetNumberOfBackgroundWindows() const { return mBackgroundWindows.Size(); } int GetNumberOfForegroundWindows() const { return mForegroundWindows.Size(); } static const iObjectKey& KeyNumForegroundWindows(); inline iImageComposerBackgroundWindow* GetBackgroundWindow(int i, int j) const { return this->GetBackgroundWindow(i+mNumTilesX*j); } iImageComposerBackgroundWindow* GetBackgroundWindow(int i) const; iImageComposerForegroundWindow* GetForegroundWindow(int i) const; void AddForegroundWindow(iViewModule *v); void RemoveForegroundWindow(int n); void MoveToBack(int n); // // Useful keys for command-line interface // static const iObjectKey& KeyBackgroundWindowViewModule(); static const iObjectKey& KeyBackgroundWindowViewModule2(); static const iObjectKey& KeyBackgroundWindowViewModule3(); static const iObjectKey& KeyBackgroundWindowWallpaperFile(); static const iObjectKey& KeyForegroundWindowViewModule(); static const iObjectKey& KeyForegroundWindowViewModule2(); static const iObjectKey& KeyForegroundWindowViewModule3(); static const iObjectKey& KeyForegroundWindowPositionX(); static const iObjectKey& KeyForegroundWindowPositionY(); static const iObjectKey& KeyForegroundWindowScale(); static const iObjectKey& KeyForegroundWindowBorderWidth(); static const iObjectKey& KeyForegroundWindowBorderColor(); static const iObjectKey& KeyForegroundWindowZoomSource(); static const iObjectKey& KeyForegroundWindowZoom4Line(); static const iObjectKey& KeyForegroundWindowZoomFactor(); static const iObjectKey& KeyForegroundWindowZoomX(); static const iObjectKey& KeyForegroundWindowZoomY(); // // Other functions // inline bool InComposing() const { return mInComposing; } void Compose(iViewModule *vm, iStereoImageArray &images); bool IsActive(); void Update(); // update all void UpdateWindowList(); void UpdateSize(); protected: virtual ~iImageComposer(); private: iImageComposer(iControlModule *cm); virtual void PackStateBody(iString &s) const; virtual void UnPackStateBody(const iString &s); void UnPackingHelper(int n, int j, iImageComposerWindow **win, int *itmp, const iObjectKey &key, const iString &s); bool mBlockUpdate, mInComposing; bool mInnerBorder, mScaleBackground; iColor mBorderColor; int mBorderWidth; int mFullWidth, mFullHeight; int mTileWidth, mTileHeight; int mNumTilesX, mNumTilesY; iArray mBackgroundWindows; iArray mForegroundWindows; }; #endif // IIMAGECOMPOSER_H ifrit-3.4.2/core/iimagecomposerwindows.cpp0000755000175700010010000006657212167404431017301 0ustar HomeNone/*========================================================================= Program: Ionization FRont Interactive Tool (IFRIT) Language: C++ Copyright (c) 2002-2012 Nick Gnedin All rights reserved. This file may be distributed and/or modified under the terms of the GNU General Public License version 2 as published by the Free Software Foundation and appearing in the file LICENSE.GPL included in the packaging of this file. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHORS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. =========================================================================*/ #include "iimagecomposerwindows.h" #include "icontrolmodule.h" #include "ierror.h" #include "ierrorstatus.h" #include "iimagecomposer.h" #include "imath.h" #include "ishellfactory.h" #include "istereoimagearray.h" #include "iviewmodule.h" #include #include // // Templates // #include "iarraytemplate.h" iColor iImageComposerBackgroundWindow::mEmptyBackground = iColor::White(); int iImageComposerForegroundWindow::mPosQuantum = 10; namespace iImageComposerWindow_Private { void DrawPixel(int x, int y, float f, const iStereoImage &image, const iColor &color, bool swap = false) { if(x<0 || y<0) return; if(swap) { int tmp = x; x = y; y = tmp; } if(x>=image.Width() || y>=image.Height()) return; unsigned char rgb[4], *ptr; color.GetRGB(rgb); rgb[3] = 255; int eye, numEyes = 1; if(image.IsStereo()) numEyes = 2; int k, d = image.Depth(), w = image.Width(); for(eye=0; eye abs(x2-x1)); if(swap) { tmp = x1; x1 = y1; y1 = tmp; tmp = x2; x2 = y2; y2 = tmp; } if(x2 < x1) { tmp = x1; x1 = x2; x2 = tmp; tmp = y1; y1 = y2; y2 = tmp; } float dx = x2 - x1; float dy = y2 - y1; float gradient = dy/dx; // dx cannot be zero // // main loop // int x; float f, y = y1 + 1.0e-3; // first y-intersection for the main loop for(x=x1; x<=x2; x++) { f = fpart(y); DrawPixel(x,int(y),f0*(1.0f-f),image,color,swap); DrawPixel(x,int(y)+1,f0*f,image,color,swap); y += gradient; } } void DrawWideLine(int x1, int y1, int x2, int y2, int w, const iStereoImage &image, const iColor &color, int corner = -1) { int i, j; if(w < 1) { return; } if(x1==x2 && y1==y2) { for(j=0; j abs(x2-x1)); if(swap) { tmp = x1; x1 = y1; y1 = tmp; tmp = x2; x2 = y2; y2 = tmp; if(corner != -1) corner = 2*(corner & 1) + (corner & 2)/2; } if(x2 < x1) { tmp = x1; x1 = x2; x2 = tmp; tmp = y1; y1 = y2; y2 = tmp; if(corner != -1) corner = (corner & 2) + 1 - (corner & 1); } float dx = x2 - x1; float dy = y2 - y1; float gradient = dy/dx; // dx cannot be zero float normal[2]; normal[1] = 1.0/sqrt(1.0+gradient*gradient); normal[0] = -gradient*normal[1]; int ymin, ymax; if(y1 < y2) { ymin = y1; ymax = y2 + w - 1; } else if(y1 > y2) { ymin = y2; ymax = y1 + w - 1; } else { ymin = y1; ymax = y1 + w - 1; } // // main loop // const int subsample = 4; const float scale = 1.0f/subsample, offset = 0.5f*(subsample-1), w2 = 0.5*w; float r1, r2; switch(w) { case 1: { r1 = r2 = w2; break; } case 2: { r1 = w2 - 0.75; r2 = w2 + 0.75; break; } default: { r1 = w2 - 0.75; r2 = w2 + 0.75; break; } } int x0, y0, k, kmax = w + 2; float p[2], f, r; float x = x1 + 0.5*(w-1), y = y1 + 0.5*(w-1), xmax = x2 + 0.5*(w-1) + 1.0e-2; while(x < xmax) { x0 = round(x); y0 = round(y); for(k=-kmax; k<=kmax; k++) { f = 0.0f; for(j=0; j0.0 && y0+k>=ymin && y0+k<=ymax) { DrawPixel(x0,y0+k,f,image,color,swap); } } x += 1.0f; y += gradient; } } }; using namespace iImageComposerWindow_Private; // // Helper classes // iImageComposerWindow::iImageComposerWindow(iViewModule *vm, iImageComposer *ic) { mType = UNDEFINED; mComposer = ic; mViewModules[0] = vm; mViewModules[1] = mViewModules[2] = 0; } iImageComposerWindow::~iImageComposerWindow() { while(mZoomTargets.Size() > 0) { mZoomTargets.Last()->SetZoomSource(0); } } void iImageComposerWindow::SetViewModule(iViewModule *vm, int win) { if(win>0 && win<3) { mViewModules[win] = vm; } else { mViewModules[0] = vm; if(vm == 0) mViewModules[1] = mViewModules[2] = 0; } mComposer->ClearCache(); } void iImageComposerWindow::UpdateWindow() { int j, k; bool present; iControlModule *cm = this->GetImageComposer()->GetControlModule(); for(j=0; j<3; j++) if(mViewModules[j] != 0) { present = false; for(k=0; !present && kGetNumberOfViewModules(); k++) { if(mViewModules[j] == cm->GetViewModule(k)) present = true; } if(!present) this->SetViewModule(0,j); } } int iImageComposerWindow::GetWindowNumber(int win) const { if(win<0 && win>2) win = 2; if(mViewModules[win] == 0) return -1; else return mViewModules[win]->GetWindowNumber(); } void iImageComposerWindow::RenderStereoImage(iStereoImage &im) const { if(mViewModules[0] == 0) { mComposer->GetErrorStatus()->Set("Unable to render image: ViewModule is not set."); return; } if(mViewModules[1]!=0 || mViewModules[2]!=0) { iStereoImage imRed, imGreen, imBlue; mComposer->GetErrorStatus()->Monitor(mViewModules[0]->GetErrorStatus(),true); mViewModules[0]->RenderStereoImage(imRed); if(mComposer->GetErrorStatus()->IsError()) return; im.SetStereo(imRed.IsStereo()); if(mViewModules[1] != 0) { mComposer->GetErrorStatus()->Monitor(mViewModules[1]->GetErrorStatus(),true); mViewModules[1]->RenderStereoImage(imGreen); if(mComposer->GetErrorStatus()->IsError()) return; if(imRed.Width()!=imGreen.Width() || imRed.Height()!=imGreen.Height()) { imGreen.SetStereo(imRed.IsStereo()); imGreen.Scale(imRed.Width(),imRed.Height()); } } if(mViewModules[2] != 0) { mComposer->GetErrorStatus()->Monitor(mViewModules[2]->GetErrorStatus(),true); mViewModules[2]->RenderStereoImage(imBlue); if(mComposer->GetErrorStatus()->IsError()) return; if(imRed.Width()!=imBlue.Width() || imRed.Height()!=imBlue.Height()) { imBlue.SetStereo(imRed.IsStereo()); imBlue.Scale(imRed.Width(),imRed.Height()); } } if(!im.CombineInPseudoColor(imRed,imGreen,imBlue)) { mComposer->GetErrorStatus()->Set("Unable to render image: error in pseudo-color composting."); } } else { mComposer->GetErrorStatus()->Monitor(mViewModules[0]->GetErrorStatus()); mViewModules[0]->RenderStereoImage(im); } } void iImageComposerWindow::OverlayImage(iStereoImage &outIm, const iStereoImage &inIm, const iColor &bg) const { // // Check that dimensions are ok. // iStereoImage winIm(inIm); winIm.Scale(this->GetContentsWidth(),this->GetContentsHeight()); unsigned char *outPtr[2], *outPtr1, *winPtr, *winPtr1; // // Prepare the left eye // outPtr[0] = outIm.LeftEye().DataPointer(); // // Begin creating a non-stereo image // int eye, numEyes = 1; outPtr[1] = 0; // for debugging - will crash if tries to write into the right eye image // // Check whether we need to switch to a stereo mode // if(winIm.IsStereo()) { numEyes = 2; if(!outIm.IsStereo()) { // // Prepare the right eye // outIm.CopyLeftEyeToRightEye(); outPtr[1] = outIm.RightEye().DataPointer(); } } int outWidth = outIm.Width(); int outHeight = outIm.Height(); int winWidth = winIm.Width(); int winHeight = winIm.Height(); int winDepth = winIm.Depth(); int outDepth = outIm.Depth(); int d = (winDepth < outDepth) ? winDepth : outDepth; // // Fill in the background color; this may be needed since winIm may have smaller size/depth // int i, j, k, xoff, yoff, w1, h1; char rgb[4]; bg.GetRGB(rgb); rgb[3] = 255; if(inIm.IsEmpty() || this->GetContentsWidth()GetImageWidth() || this->GetContentsHeight()GetImageHeight() || winDepthGetImageX(); yoff = this->GetImageY(); w1 = this->GetImageWidth(); h1 = this->GetImageHeight(); for(eye=0; eyeGetContentsX(); yoff = this->GetContentsY(); w1 = winWidth; h1 = winHeight; if(xoff+w1 > outWidth) w1 = outWidth - xoff; if(yoff+h1 > outHeight) h1 = outHeight - yoff; for(eye=0; eyeGetBackgroundWindow(j))!=0 && w!=this) j++; if(w == this) { return -(1+j); } else { IERROR_LOW("Invalid id for a background window."); return 0; } } int iImageComposerBackgroundWindow::GetImageX() const { int x = mComposer->GetBorderWidth() + mTileX*mComposer->GetTileWidth(); if(mComposer->GetInnerBorder()) x += mTileX*mComposer->GetBorderWidth(); return x; } int iImageComposerBackgroundWindow::GetImageY() const { int y = mComposer->GetBorderWidth() + mTileY*mComposer->GetTileHeight(); if(mComposer->GetInnerBorder()) y += mTileY*mComposer->GetBorderWidth(); return y; } int iImageComposerBackgroundWindow::GetImageWidth() const { return mComposer->GetTileWidth(); } int iImageComposerBackgroundWindow::GetImageHeight() const { return mComposer->GetTileHeight(); } int iImageComposerBackgroundWindow::GetContentsX() const { int x = this->GetImageX(); if(!mComposer->GetScaleBackground()) x += (mComposer->GetTileWidth()-this->GetWindowWidth())/2; return x; } int iImageComposerBackgroundWindow::GetContentsY() const { int y = this->GetImageY(); if(!mComposer->GetScaleBackground()) y += (mComposer->GetTileHeight()-this->GetWindowHeight())/2; return y; } int iImageComposerBackgroundWindow::GetContentsWidth() const { if(mComposer->GetScaleBackground()) return mComposer->GetTileWidth(); else return this->GetWindowWidth(); } int iImageComposerBackgroundWindow::GetContentsHeight() const { if(mComposer->GetScaleBackground()) return mComposer->GetTileHeight(); else return this->GetWindowHeight(); } int iImageComposerBackgroundWindow::GetWindowWidth() const { if(this->GetViewModule() != 0) return this->GetViewModule()->GetThisImageWidth(); else return mWallpaperImage.Width(); } int iImageComposerBackgroundWindow::GetWindowHeight() const { if(this->GetViewModule() != 0) return this->GetViewModule()->GetThisImageHeight(); else return mWallpaperImage.Height(); } bool iImageComposerBackgroundWindow::IsEmpty() const { return (this->GetViewModule()==0 && mWallpaperImage.IsEmpty()); } void iImageComposerBackgroundWindow::Draw(iStereoImage &outIm) const { iStereoImage winIm; if(this->GetViewModule() != 0) { // // Render the image // this->RenderStereoImage(winIm); if(mComposer->GetErrorStatus()->IsError()) return; this->OverlayImage(outIm,winIm,mEmptyBackground); } else { winIm = mWallpaperImage; this->OverlayImage(outIm,winIm,mEmptyBackground); } } bool iImageComposerBackgroundWindow::LoadWallpaperImage(const iString &s) { if(s != mWallpaperFile) { if(s.IsEmpty()) { mWallpaperImage.Clear(); mWallpaperFile.Clear(); mComposer->UpdateSize(); mComposer->ClearCache(); return true; } else { bool ret = mWallpaperImage.LoadFromFile(s); if(ret) { mWallpaperFile = s; mComposer->UpdateSize(); mComposer->ClearCache(); } return ret; } } else return true; } // // Foreground windows // iImageComposerForegroundWindow* iImageComposerForegroundWindow::New(iViewModule *vm, iImageComposer *ic) { return new iImageComposerForegroundWindow(vm,ic); } iImageComposerForegroundWindow::iImageComposerForegroundWindow(iViewModule *vm, iImageComposer *ic) : iImageComposerWindow(vm,ic) { mType = FOREGROUND; mBorderWidth = 1; mScale = 0.5; mPosX = mPosY = 0; mZoomX = mZoomY = 0.5f; mZoomFactor = 0.2f; mZoomSource = 0; mZoomFlag = _4Lines; mZoomAuto = false; } iImageComposerForegroundWindow::~iImageComposerForegroundWindow() { if(mZoomSource != 0) mZoomSource->UnRegisterZoomTarget(this); } int iImageComposerForegroundWindow::GetId() const { iImageComposerForegroundWindow *w; int j = 0; while((w = mComposer->GetForegroundWindow(j))!=0 && w!=this) j++; if(w == this) { return (1+j); } else { IERROR_LOW("Invalid id for a foreground window."); return 0; } } int iImageComposerForegroundWindow::GetImageX() const { return mPosX; } int iImageComposerForegroundWindow::GetImageY() const { return mPosY; } int iImageComposerForegroundWindow::GetImageWidth() const { return 2*mBorderWidth + this->GetContentsWidth(); } int iImageComposerForegroundWindow::GetImageHeight() const { return 2*mBorderWidth + this->GetContentsHeight(); } int iImageComposerForegroundWindow::GetContentsX() const { return mPosX + mBorderWidth; } int iImageComposerForegroundWindow::GetContentsY() const { return mPosY + mBorderWidth; } int iImageComposerForegroundWindow::GetContentsWidth() const { return round(mScale*this->GetWindowWidth()); } int iImageComposerForegroundWindow::GetContentsHeight() const { return round(mScale*this->GetWindowHeight()); } int iImageComposerForegroundWindow::GetWindowWidth() const { if(this->GetViewModule() != 0) return this->GetViewModule()->GetThisImageWidth(); else return 0; } int iImageComposerForegroundWindow::GetWindowHeight() const { if(this->GetViewModule() != 0) return this->GetViewModule()->GetThisImageHeight(); else return 0; } void iImageComposerForegroundWindow::UpdateWindow() { this->iImageComposerWindow::UpdateWindow(); mZoomAuto = this->SyncZoom(); } bool iImageComposerForegroundWindow::IsEmpty() const { return (this->GetViewModule() == 0); } void iImageComposerForegroundWindow::Draw(iStereoImage &outIm) const { if(this->GetViewModule() != 0) { iStereoImage winIm; this->RenderStereoImage(winIm); if(mComposer->GetErrorStatus()->IsError()) return; // // Draw zoom first // if(mZoomSource != 0) { int bw = this->GetBorderWidth(); iColor bc(this->GetBorderColor()); int zx1 = round(mZoomSource->GetContentsX()+(mZoomX*mZoomSource->GetContentsWidth()-0.5*this->GetZoomWidth())); int zy1 = round(mZoomSource->GetContentsY()+(mZoomY*mZoomSource->GetContentsHeight()-0.5*this->GetZoomHeight())); int zx2 = round(mZoomSource->GetContentsX()+(mZoomX*mZoomSource->GetContentsWidth()+0.5*this->GetZoomWidth())); int zy2 = round(mZoomSource->GetContentsY()+(mZoomY*mZoomSource->GetContentsHeight()+0.5*this->GetZoomHeight())); int i; for(i=0; iGetCoordinatesForZoomLine(0,x,y,mPosX,mPosY,this->GetImageWidth()-bw+1,this->GetImageHeight()-bw+1)) DrawWideLine(zx1,zy1,x,y,bw,outIm,bc,0); if(this->GetCoordinatesForZoomLine(1,x,y,mPosX,mPosY,this->GetImageWidth()-bw+1,this->GetImageHeight()-bw+1)) DrawWideLine(zx2,zy1,x,y,bw,outIm,bc,1); if(this->GetCoordinatesForZoomLine(2,x,y,mPosX,mPosY,this->GetImageWidth()-bw+1,this->GetImageHeight()-bw+1)) DrawWideLine(zx1,zy2,x,y,bw,outIm,bc,2); if(this->GetCoordinatesForZoomLine(3,x,y,mPosX,mPosY,this->GetImageWidth()-bw+1,this->GetImageHeight()-bw+1)) DrawWideLine(zx2,zy2,x,y,bw,outIm,bc,3); } // // Draw the window // this->OverlayImage(outIm,winIm,mBorderColor); } } void iImageComposerForegroundWindow::SetScale(float s) { if(s>0.0 && s<=1.0 && fabs(s-mScale)>1.0e-5) { mScale = s; this->CorrectPosition(); mComposer->ClearCache(); } } void iImageComposerForegroundWindow::SetPosition(int x, int y) { if(x!=mPosX || y!=mPosY) { // // Quantize the position but not if we are against the outer wall // if(x+this->GetImageWidth() < mComposer->GetImageWidth()) mPosX = mPosQuantum*(x/mPosQuantum); else mPosX = x; if(y+this->GetImageHeight() < mComposer->GetImageHeight()) mPosY = mPosQuantum*(y/mPosQuantum); else mPosY = y; this->CorrectPosition(); mComposer->ClearCache(); } } void iImageComposerForegroundWindow::SetBorderWidth(int w) { if(w>=0 && w!=mBorderWidth) { mBorderWidth = w; this->CorrectPosition(); mComposer->ClearCache(); } } void iImageComposerForegroundWindow::SetBorderColor(const iColor& c) { if(c != mBorderColor) { mBorderColor = c; mComposer->ClearCache(); } } void iImageComposerForegroundWindow::CorrectPosition() { if(mPosX < 0) mPosX = 0; if(mPosY < 0) mPosY = 0; if(mBorderWidth > this->GetWindowWidth()/4) mBorderWidth = this->GetWindowWidth()/4; if(mBorderWidth > this->GetWindowHeight()/4) mBorderWidth = this->GetWindowHeight()/4; // // Is scale small enough? // if(this->GetImageWidth() > mComposer->GetImageWidth()) { mPosX = 0; mScale = (float)(mComposer->GetImageWidth()-2*mBorderWidth)/this->GetWindowWidth(); } if(this->GetImageHeight() > mComposer->GetImageHeight()) { mPosY = 0; mScale = (float)(mComposer->GetImageHeight()-2*mBorderWidth)/this->GetWindowHeight(); } // // Now we are guaranteed to fit into the image. But are we fully inside? // if(mPosX+this->GetImageWidth() > mComposer->GetImageWidth()) mPosX = mComposer->GetImageWidth() - this->GetImageWidth(); if(mPosY+this->GetImageHeight() > mComposer->GetImageHeight()) mPosY = mComposer->GetImageHeight() - this->GetImageHeight(); this->UpdateZoomFlag(); } void iImageComposerForegroundWindow::SetZoomSource(iImageComposerWindow *source) { if(source != this) { if(mZoomSource != 0) mZoomSource->UnRegisterZoomTarget(this); mZoomSource = source; if(source != 0) source->RegisterZoomTarget(this); this->UpdateZoomPosition(); this->UpdateZoomFlag(); mComposer->ClearCache(); } } void iImageComposerForegroundWindow::SetZoomPosition(float x, float y) { if(x>0.0f && x<1.0f && y>0.0f && y<1.0f && (fabs(x-mZoomX)>1.0e-5 || fabs(y-mZoomY)>1.0e-5)) { mZoomX = x; mZoomY = y; mComposer->ClearCache(); if(mZoomSource != 0) this->UpdateZoomPosition(); } } void iImageComposerForegroundWindow::SetZoomFactor(float factor) { if(factor>0.0f && factor<1.0f && fabs(factor-mZoomFactor)>1.0e-5) { mZoomFactor = factor; mComposer->ClearCache(); if(mZoomSource != 0) this->UpdateZoomPosition(); } } void iImageComposerForegroundWindow::SetZoomFlag(int f) { if(f > 0) { mZoomFlag = f; this->UpdateZoomFlag(); } } bool iImageComposerForegroundWindow::GetCoordinatesForZoomLine(int n, int &x, int &y, int wx, int wy, int ww, int wh) const { if(n<0 || n>3 || (mZoomFlag & (1<GetContentsX()+(mZoomX*mZoomSource->GetContentsWidth()-0.5*this->GetZoomWidth())); pz[1][0] = pz[3][0] = round(mZoomSource->GetContentsX()+(mZoomX*mZoomSource->GetContentsWidth()+0.5*this->GetZoomWidth())); pz[0][1] = pz[1][1] = round(mZoomSource->GetContentsY()+(mZoomY*mZoomSource->GetContentsHeight()-0.5*this->GetZoomHeight())); pz[2][1] = pz[3][1] = round(mZoomSource->GetContentsY()+(mZoomY*mZoomSource->GetContentsHeight()+0.5*this->GetZoomHeight())); pw[0][0] = pw[2][0] = mPosX; pw[1][0] = pw[3][0] = mPosX + this->GetImageWidth() - 1; pw[0][1] = pw[1][1] = mPosY; pw[2][1] = pw[3][1] = mPosY + this->GetImageHeight() - 1; for(j=0; j<4; j++) { n[0] = pw[j][1] - pz[j][1]; n[1] = pz[j][0] - pw[j][0]; ok = true; s = 0; for(i=0; ok && i<4; i++) if(i != j) { d = n[0]*(pz[i][0]-pz[j][0]) + n[1]*(pz[i][1]-pz[j][1]); if(s==0 && d!=0) { s = d/abs(d); } if(d*s < 0) ok = false; } for(i=0; ok && i<4; i++) if(i != j) { d = n[0]*(pw[i][0]-pz[j][0]) + n[1]*(pw[i][1]-pz[j][1]); if(d*s < 0) ok = false; } if(ok) { mZoomFlag = mZoomFlag | (1 << j); } } // // Activate a switch if needed // if(mZoomFlag == (_Line11 | _Line12)) { mZoomFlag = _Line21 | _Line22 | _ShiftX; } if(mZoomFlag == (_Line21 | _Line22)) { mZoomFlag = _Line11 | _Line12 | _ShiftX; } if(mZoomFlag == (_Line11 | _Line21)) { mZoomFlag = _Line12 | _Line22 | _ShiftY; } if(mZoomFlag == (_Line12 | _Line22)) { mZoomFlag = _Line11 | _Line21 | _ShiftY; } } void iImageComposerForegroundWindow::UpdateZoomPosition() { if(mZoomSource==0 || this->GetViewModule()==0 || (mZoomAuto=this->SyncZoom())) return; if(this->GetWindowWidth()*mZoomFactor > mZoomSource->GetContentsWidth()) { mZoomFactor = float(mZoomSource->GetContentsWidth())/this->GetWindowWidth(); } if(this->GetWindowHeight()*mZoomFactor > mZoomSource->GetContentsHeight()) { mZoomFactor = float(mZoomSource->GetContentsHeight())/this->GetWindowHeight(); } float w = 0.5*this->GetWindowWidth()*mZoomFactor/mZoomSource->GetContentsWidth(); float h = 0.5*this->GetWindowHeight()*mZoomFactor/mZoomSource->GetContentsHeight(); if(mZoomX < w) mZoomX = w; if(mZoomY < h) mZoomY = h; if(mZoomX > 1.0f-w) mZoomX = 1.0f - w; if(mZoomY > 1.0f-h) mZoomY = 1.0f - h; this->UpdateZoomFlag(); } bool iImageComposerForegroundWindow::SyncZoom() { if(mZoomSource==0 || mZoomSource->GetViewModule()==0 || this->GetViewModule()==0) return false; iViewModule *source = mZoomSource->GetViewModule(); iViewModule *target = this->GetViewModule(); // // Do we have the same projections? // if(source->GetRenderer()->GetActiveCamera()->GetParallelProjection() != target->GetRenderer()->GetActiveCamera()->GetParallelProjection()) return false; // // ViewUp vectors must coincide // int i; double sPos[3], tPos[3]; source->GetRenderer()->GetActiveCamera()->GetViewUp(sPos); target->GetRenderer()->GetActiveCamera()->GetViewUp(tPos); for(i=0; i<3; i++) if(fabs(sPos[i]-tPos[i]) > iMath::_DoubleTolerance) { return false; } // // In perspective projection camera focal points, view angles, and directions must coincide // if(source->GetRenderer()->GetActiveCamera()->GetParallelProjection() == 0) { source->GetRenderer()->GetActiveCamera()->GetFocalPoint(sPos); target->GetRenderer()->GetActiveCamera()->GetFocalPoint(tPos); for(i=0; i<3; i++) if(fabs(sPos[i]-tPos[i]) > iMath::_DoubleTolerance) { return false; } source->GetRenderer()->GetActiveCamera()->GetDirectionOfProjection(sPos); target->GetRenderer()->GetActiveCamera()->GetDirectionOfProjection(tPos); for(i=0; i<3; i++) if(fabs(sPos[i]-tPos[i]) > iMath::_DoubleTolerance) { return false; } if(fabs(source->GetRenderer()->GetActiveCamera()->GetViewAngle()-target->GetRenderer()->GetActiveCamera()->GetViewAngle()) > iMath::_DoubleTolerance) { return false; } } // // Get target frustrum planes // double aspect[2], planes[24]; target->GetRenderer()->GetAspect(aspect); target->GetRenderer()->GetActiveCamera()->GetFrustumPlanes(aspect[0]/aspect[1],planes); // // Find the source focal plane // double fp[3], fplane[4]; source->GetRenderer()->GetActiveCamera()->GetFocalPoint(fp); source->GetRenderer()->GetActiveCamera()->GetViewPlaneNormal(fplane); fplane[3] = -(fplane[0]*fp[0]+fplane[1]*fp[1]+fplane[2]*fp[2]); // // Find the rectangle that we see at the camera focal point in the target window // double r[4][3]; if(!iMath::Intersect3Planes(fplane,planes+4*0,planes+4*2,r[0])) return false; // -X & -Y planes if(!iMath::Intersect3Planes(fplane,planes+4*1,planes+4*2,r[1])) return false; // +X & -Y planes if(!iMath::Intersect3Planes(fplane,planes+4*0,planes+4*3,r[2])) return false; // -X & +Y planes if(!iMath::Intersect3Planes(fplane,planes+4*1,planes+4*3,r[3])) return false; // +X & +Y planes // // Find the projections of this rectangle onto the source view plane // for(i=0; i<4; i++) { source->GetRenderer()->WorldToView(r[i][0],r[i][1],r[i][2]); source->GetRenderer()->ViewToNormalizedViewport(r[i][0],r[i][1],r[i][2]); } // // Is it a rectangle? // if(fabs(r[0][0]-r[2][0])>iMath::_DoubleTolerance || fabs(r[1][0]-r[3][0])>iMath::_DoubleTolerance || fabs(r[0][1]-r[1][1])>iMath::_DoubleTolerance || fabs(r[2][1]-r[3][1])>iMath::_DoubleTolerance) return false; // // Does it fits? // if(r[0][0]<0.0 || r[0][0]>1.0 || r[0][1]<0.0 || r[0][1]>1.0 || r[3][0]<0.0 || r[3][0]>1.0 || r[3][1]<0.0 || r[3][1]>1.0) return false; mZoomFactor = (r[3][1]-r[0][1])*mZoomSource->GetContentsHeight()/this->GetWindowHeight(); mZoomX = 0.5*(r[0][0]+r[3][0]); mZoomY = 0.5*(r[0][1]+r[3][1]); this->UpdateZoomFlag(); return true; } ifrit-3.4.2/core/iimagecomposerwindows.h0000755000175700010010000001536112167404413016734 0ustar HomeNone/*========================================================================= Program: Ionization FRont Interactive Tool (IFRIT) Language: C++ Copyright (c) 2002-2012 Nick Gnedin All rights reserved. This file may be distributed and/or modified under the terms of the GNU General Public License version 2 as published by the Free Software Foundation and appearing in the file LICENSE.GPL included in the packaging of this file. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHORS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. =========================================================================*/ #ifndef IIMAGECOMPOSERWINDOWS_H #define IIMAGECOMPOSERWINDOWS_H #include "iarray.h" #include "icolor.h" #include "iimage.h" #include "istring.h" class iImageComposer; class iImageComposerForegroundWindow; class iStereoImage; class iViewModule; class iImageComposerWindow { public: enum iImageComposerWindowType { UNDEFINED = 0, BACKGROUND = 1, FOREGROUND = 2 }; virtual ~iImageComposerWindow(); inline iViewModule* GetViewModule(int win = 0) const { return mViewModules[(win>0 && win<3)?win:0]; } void SetViewModule(iViewModule *vm, int win = 0); inline iImageComposerWindowType GetType() const { return mType; } inline const iImageComposer* GetImageComposer() const { return mComposer; } int GetWindowNumber(int win = 0) const; virtual void UpdateWindow(); virtual int GetId() const = 0; virtual int GetImageX() const = 0; virtual int GetImageY() const = 0; virtual int GetImageWidth() const = 0; virtual int GetImageHeight() const = 0; virtual int GetContentsX() const = 0; virtual int GetContentsY() const = 0; virtual int GetContentsWidth() const = 0; virtual int GetContentsHeight() const = 0; virtual int GetWindowWidth() const = 0; virtual int GetWindowHeight() const = 0; virtual bool IsEmpty() const = 0; virtual void Draw(iStereoImage &outIm) const = 0; void RegisterZoomTarget(iImageComposerForegroundWindow *win); void UnRegisterZoomTarget(iImageComposerForegroundWindow *win); protected: iImageComposerWindow(iViewModule *vm, iImageComposer *ic); // // Helper functions // void RenderStereoImage(iStereoImage &winIm) const; void OverlayImage(iStereoImage &outIm, const iStereoImage &winIm, const iColor &bg) const; iViewModule *mViewModules[3]; iImageComposer *mComposer; iImageComposerWindowType mType; iSearchableArray mZoomTargets; }; class iImageComposerBackgroundWindow : public iImageComposerWindow { public: static iImageComposerBackgroundWindow* New(int tx, int ty, iImageComposer *ic); virtual int GetId() const; virtual int GetImageX() const; virtual int GetImageY() const; virtual int GetImageWidth() const; virtual int GetImageHeight() const; virtual int GetContentsX() const; virtual int GetContentsY() const; virtual int GetContentsWidth() const; virtual int GetContentsHeight() const; virtual int GetWindowWidth() const; virtual int GetWindowHeight() const; virtual bool IsEmpty() const; virtual void Draw(iStereoImage &outIm) const; int GetTileX() const { return mTileX; } int GetTileY() const { return mTileY; } const iString& GetWallpaperFile() const { return mWallpaperFile; } const iImage& GetWallpaperImage() const { return mWallpaperImage; } bool LoadWallpaperImage(const iString &s); protected: iImageComposerBackgroundWindow(int tx, int ty, iImageComposer *ic); private: int mTileX, mTileY; iImage mWallpaperImage; iString mWallpaperFile; static iColor mEmptyBackground; }; class iImageComposerForegroundWindow : public iImageComposerWindow { public: enum Flags { _Line11 = 1, _Line21 = 2, _Line12 = 4, _Line22 = 8, _4Lines = 15, _ShiftX = 16, _ShiftY = 32 }; static iImageComposerForegroundWindow* New(iViewModule *vm, iImageComposer *ic); virtual ~iImageComposerForegroundWindow(); virtual int GetId() const; virtual int GetImageX() const; virtual int GetImageY() const; virtual int GetImageWidth() const; virtual int GetImageHeight() const; virtual int GetContentsX() const; virtual int GetContentsY() const; virtual int GetContentsWidth() const; virtual int GetContentsHeight() const; virtual int GetWindowWidth() const; virtual int GetWindowHeight() const; virtual void UpdateWindow(); virtual bool IsEmpty() const; virtual void Draw(iStereoImage &outIm) const; inline float GetScale() const { return mScale; } inline int GetPositionX() const { return mPosX; } inline int GetPositionY() const { return mPosY; } inline int GetBorderWidth() const { return mBorderWidth; } inline iColor GetBorderColor() const { return mBorderColor; } void SetScale(float s); void SetPosition(int x, int y); void SetPositionX(int x); void SetPositionY(int y); void SetBorderWidth(int w); void SetBorderColor(const iColor& c); void CorrectPosition(); inline float GetZoomX() const { return mZoomX; } inline float GetZoomY() const { return mZoomY; } inline float GetZoomFactor() const { return mZoomFactor; } inline iImageComposerWindow* GetZoomSource() const { return mZoomSource; } inline int GetZoomFlag() const { return mZoomFlag; } void SetZoomSource(iImageComposerWindow *source); void SetZoomPosition(float x, float y); void SetZoomFactor(float factor); void SetZoomFlag(int f); inline bool IsAutoZoom() const { return mZoomAuto; } bool GetCoordinatesForZoomLine(int n, int &x, int &y, int wx, int wy, int ww, int wh) const; inline float GetZoomWidth() const { return mZoomFactor*this->GetWindowWidth(); } inline float GetZoomHeight() const { return mZoomFactor*this->GetWindowHeight(); } protected: iImageComposerForegroundWindow(iViewModule *vm, iImageComposer *ic); void UpdateZoomPosition(); void UpdateZoomFlag(); bool SyncZoom(); private: float mScale; iColor mBorderColor; int mBorderWidth, mPosX, mPosY; int mZoomFlag; bool mZoomAuto; float mZoomX, mZoomY, mZoomFactor; iImageComposerWindow *mZoomSource; static int mPosQuantum; }; inline void iImageComposerForegroundWindow::SetPositionX(int x) { this->SetPosition(x,mPosY); } inline void iImageComposerForegroundWindow::SetPositionY(int y) { this->SetPosition(mPosX,y); } #endif // IIMAGECOMPOSERWINDOWS_H ifrit-3.4.2/core/ikeyboardinteractorstyle.cpp0000644000175700010010000000572112167404431017772 0ustar HomeNone/*========================================================================= Program: Ionization FRont Interactive Tool (IFRIT) Language: C++ Copyright (c) 2002-2012 Nick Gnedin All rights reserved. This file may be distributed and/or modified under the terms of the GNU General Public License version 2 as published by the Free Software Foundation and appearing in the file LICENSE.GPL included in the packaging of this file. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHORS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. =========================================================================*/ #include "ikeyboardinteractorstyle.h" #include iKeyboardInteractorStyle* iKeyboardInteractorStyle::New() { return new iKeyboardInteractorStyle; } iKeyboardInteractorStyle::iKeyboardInteractorStyle() { } iKeyboardInteractorStyle::~iKeyboardInteractorStyle() { } void iKeyboardInteractorStyle::OnChar() { // // Are these universal??? // const char _Left = 18; const char _Down = 21; const char _Up = 19; const char _Right = 20; // catch keycodes switch (Interactor->GetKeyCode()) { case 'a': case 'A': { MotionFactor *= 0.5; break; } case 'z': case 'Z': { MotionFactor *= 2.0; break; } case '+': { this->DoZoom(0,1); break; } case '-': { this->DoZoom(0,-1); break; } case 'h': case 'H': case _Left: { this->DoMove(-1,0); break; } case 'j': case 'J': case _Down: { this->DoMove(0,-1); break; } case 'k': case 'K': case _Up: { this->DoMove(0,1); break; } case 'l': case 'L': case _Right: { this->DoMove(1,0); break; } default: { vtkInteractorStyleTrackballCamera::OnChar(); } } Interactor->Render(); } void iKeyboardInteractorStyle::FakeEvent(int dx, int dy) { int x, y; Interactor->GetMousePosition(&x,&y); Interactor->SetEventPosition(x-dx,y-dy); Interactor->SetEventPosition(x,y); this->FindPokedRenderer(x,y); } void iKeyboardInteractorStyle::DoZoom(int dx, int dy) { this->FakeEvent(dx,dy); this->Dolly(); } void iKeyboardInteractorStyle::DoMove(int dx, int dy) { this->FakeEvent(dx,dy); if(Interactor->GetShiftKey()) { this->Pan(); } else if(Interactor->GetControlKey()) { this->Spin(); } else { this->Rotate(); } } ifrit-3.4.2/core/ikeyboardinteractorstyle.h0000644000175700010010000000411312167404413017431 0ustar HomeNone/*========================================================================= Program: Ionization FRont Interactive Tool (IFRIT) Language: C++ Copyright (c) 2002-2012 Nick Gnedin All rights reserved. This file may be distributed and/or modified under the terms of the GNU General Public License version 2 as published by the Free Software Foundation and appearing in the file LICENSE.GPL included in the packaging of this file. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHORS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. =========================================================================*/ #ifndef IKEYBOARDINTERACTORSTYLE_H #define IKEYBOARDINTERACTORSTYLE_H #include class iKeyboardInteractorStyle: public vtkInteractorStyleTrackballCamera { public: vtkTypeMacro(iKeyboardInteractorStyle,vtkInteractorStyleTrackballCamera); static iKeyboardInteractorStyle* New(); // // Disable mouse interaction // virtual void OnMouseMove(){} virtual void OnLeftButtonDown(){} virtual void OnLeftButtonUp(){} virtual void OnMiddleButtonDown(){} virtual void OnMiddleButtonUp(){} virtual void OnRightButtonDown(){} virtual void OnRightButtonUp(){} virtual void OnChar(); protected: virtual ~iKeyboardInteractorStyle(); private: iKeyboardInteractorStyle(); void FakeEvent(int dx, int dy); void DoZoom(int dx, int dy); void DoMove(int dx, int dy); }; #endif // IKEYBOARDINTERACTORSTYLE_H ifrit-3.4.2/core/ilegend.cpp0000755000175700010010000001025612167404431014256 0ustar HomeNone/*========================================================================= Program: Ionization FRont Interactive Tool (IFRIT) Language: C++ Copyright (c) 2002-2012 Nick Gnedin All rights reserved. This file may be distributed and/or modified under the terms of the GNU General Public License version 2 as published by the Free Software Foundation and appearing in the file LICENSE.GPL included in the packaging of this file. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHORS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. =========================================================================*/ #include "ilegend.h" #include "ierror.h" #include "ioverlayhelper.h" #include #include #include #include #include #include // // Templates // #include "iarraytemplate.h" #include "igenericproptemplate.h" iLegend* iLegend::New(iRenderTool *rv) { IERROR_ASSERT(rv); return new iLegend(rv); } iLegend::iLegend(iRenderTool *rv) : iGenericProp(true), mOverlayHelper(rv) { this->BorderOn(); this->GetPositionCoordinate()->SetCoordinateSystemToNormalizedViewport(); this->GetPosition2Coordinate()->SetCoordinateSystemToNormalizedViewport(); this->GetPosition2Coordinate()->SetReferenceCoordinate(this->GetPositionCoordinate()); this->SetPosition2(0.25,0.08); this->BorderOn(); this->LockBorderOn(); this->GetProperty()->SetColor(0.0,0.0,0.0); this->GetProperty()->SetLineWidth(2.0); this->GetEntryTextProperty()->SetJustificationToLeft(); this->GetEntryTextProperty()->SetVerticalJustificationToCentered(); this->GetEntryTextProperty()->SetBold(1); this->PickableOff(); } iLegend::~iLegend() { } void iLegend::UpdateGeometry(vtkViewport *viewport) { // // Maintain the font size // int mag = mOverlayHelper->GetRenderingMagnification(); if(mag == 1) { double *x1 = this->GetPosition(); double *x2 = this->GetPosition2(); int *size = viewport->GetSize(); float s = (mOverlayHelper->GetFontSize(viewport)*NumberOfEntries+(NumberOfEntries+1)*Padding)/fabs(size[1]*x2[1]); mOverlayHelper->UpdateTextProperty(viewport,this->EntryTextProperty); this->EntryTextProperty->Modified(); mUnmagx1[0] = x1[0]; mUnmagx1[1] = x1[1]; mUnmagx2[0] = s*x2[0]; mUnmagx2[1] = s*x2[1]; // // Corrections // if(mUnmagx2[0] > 0.25) mUnmagx2[0] = 0.25; if(mUnmagx2[1] > 0.16) mUnmagx2[1] = 0.16; if(mUnmagx1[0] > 0.5) { mUnmagx1[0] = 0.98 - mUnmagx2[0]; this->SetPosition(mUnmagx1[0],mUnmagx1[1]); } } else { int winij[2]; mOverlayHelper->ComputePositionShiftsUnderMagnification(winij); this->SetPosition(mag*mUnmagx1[0]-winij[0],mag*mUnmagx1[1]-winij[1]); this->Padding *= mag; } this->SetPosition2(mUnmagx2[0]*mag,mUnmagx2[1]*mag); // // Scale lines // this->GetProperty()->SetLineWidth(2*mag); this->GetProperty()->SetColor(this->GetOverlayHelper()->GetColor(viewport).ToVTK()); } void iLegend::UpdateOverlay(vtkViewport *viewport) { int i; // // Redo text colors and rerender them // for(i=0; iNumberOfEntries; i++) { //this->TextMapper[i]->GetTextProperty()->ShallowCopy(this->GetEntryTextProperty()); this->TextMapper[i]->GetTextProperty()->SetColor(this->GetOverlayHelper()->GetColor(viewport).ToVTK()); } } void iLegend::Reset() { int mag = mOverlayHelper->GetRenderingMagnification(); // // Reset to the unmagnified state // if(mag > 1) { this->SetPosition(mUnmagx1[0],mUnmagx1[1]); this->SetPosition2(mUnmagx2[0],mUnmagx2[1]); this->Padding /= mag; } } ifrit-3.4.2/core/ilegend.h0000644000175700010010000000352012167404413013714 0ustar HomeNone/*========================================================================= Program: Ionization FRont Interactive Tool (IFRIT) Language: C++ Copyright (c) 2002-2012 Nick Gnedin All rights reserved. This file may be distributed and/or modified under the terms of the GNU General Public License version 2 as published by the Free Software Foundation and appearing in the file LICENSE.GPL included in the packaging of this file. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHORS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. =========================================================================*/ #ifndef ILEGEND_H #define ILEGEND_H #include "igenericprop.h" #include #include "ipointermacro.h" class iOverlayHelper; class iRenderTool; class iLegend: public iGenericProp { IPOINTER_AS_USER(OverlayHelper); public: vtkTypeMacro(iLegend,vtkLegendBoxActor); static iLegend* New(iRenderTool *rv = 0); protected: virtual ~iLegend(); virtual void UpdateGeometry(vtkViewport *vp); virtual void UpdateOverlay(vtkViewport *vp); virtual void Reset(); private: iLegend(iRenderTool *rv); float mUnmagx1[2], mUnmagx2[2]; }; #endif // ILEGEND_H ifrit-3.4.2/core/ilightkit.cpp0000755000175700010010000001102512167404431014632 0ustar HomeNone/*========================================================================= Program: Ionization FRont Interactive Tool (IFRIT) Language: C++ Copyright (c) 2002-2012 Nick Gnedin All rights reserved. This file may be distributed and/or modified under the terms of the GNU General Public License version 2 as published by the Free Software Foundation and appearing in the file LICENSE.GPL included in the packaging of this file. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHORS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. =========================================================================*/ #include "ilightkit.h" #include "ivtk.h" #include #include #include namespace iLightKit_Private { void UpdateLight(vtkLight *l, double elevation, double azimuth, double ex[3], double ey[3], double ez[3]) { int i; double org[3], pos[3]; #ifdef IVTK_PRE54 elevation *= vtkMath::DegreesToRadians(); azimuth *= vtkMath::DegreesToRadians(); #else elevation = vtkMath::RadiansFromDegrees(elevation); azimuth = vtkMath::RadiansFromDegrees(azimuth); #endif org[0] = cos(elevation)*sin(azimuth); org[1] = sin(elevation); org[2] = cos(elevation)*cos(azimuth); for(i=0; i<3; i++) { pos[i] = org[0]*ex[i] + org[1]*ey[i] + org[2]*ez[i]; } l->SetPosition(pos); } }; using namespace iLightKit_Private; // // Main class // iLightKit* iLightKit::New() { return new iLightKit; } iLightKit::iLightKit() { this->vtkLightKit::SetKeyLightAngle(45.0,0.0); this->vtkLightKit::SetFillLightAngle(-75.0,0.0); this->vtkLightKit::SetBackLightAngle(0.0,110.0); this->vtkLightKit::SetKeyLightIntensity(1.0); this->vtkLightKit::SetKeyToFillRatio(3.0); this->vtkLightKit::SetKeyToHeadRatio(6.0); this->vtkLightKit::SetKeyToBackRatio(3.0); mAngles[0] = mAngles[1] = 0.0; this->UpdateAngles(); } iLightKit::~iLightKit() { } // // This is to fix a bug with off-screen rednering: the key light must be first. // void iLightKit::AddLightsToRenderer(vtkRenderer *renderer) { if(renderer != 0) { renderer->AddLight(this->KeyLight); renderer->AddLight(this->FillLight); renderer->AddLight(this->HeadLight); renderer->AddLight(this->BackLight0); renderer->AddLight(this->BackLight1); } } void iLightKit::SetAngles(float e, float a) { if(fabs(e-mAngles[0])>1.0e-5 || fabs(a-mAngles[1])>1.0e-5) { mAngles[0] = e; mAngles[1] = a; this->UpdateAngles(); } } void iLightKit::SetIntensities(float k, float f, float h) { if(k > 1.0e-10) { this->SetKeyLightIntensity(k); if(f > 1.0e-10) this->SetKeyToFillRatio(k/f); if(h > 1.0e-10) this->SetKeyToHeadRatio(k/h); } } void iLightKit::GetIntensities(float i[3]) const { i[0] = this->KeyLightIntensity; i[1] = this->KeyLightIntensity/this->KeyToFillRatio; i[2] = this->KeyLightIntensity/this->KeyToHeadRatio; } void iLightKit::UpdateAngles() { double ex[3], ey[3], ez[3]; #ifdef IVTK_PRE54 double ce = cos(mAngles[0]*vtkMath::DegreesToRadians()); double se = sin(mAngles[0]*vtkMath::DegreesToRadians()); double ca = cos(mAngles[1]*vtkMath::DegreesToRadians()); double sa = sin(mAngles[1]*vtkMath::DegreesToRadians()); #else double ce = cos(vtkMath::RadiansFromDegrees(mAngles[0])); double se = sin(vtkMath::RadiansFromDegrees(mAngles[0])); double ca = cos(vtkMath::RadiansFromDegrees(mAngles[1])); double sa = sin(vtkMath::RadiansFromDegrees(mAngles[1])); #endif ex[0] = ce*ca; ex[1] = 0.0; ex[2] = -ce*sa; ey[0] = -se*sa; ey[1] = ce; ey[2] = -se*ca; ez[0] = ce*sa; ez[1] = se; ez[2] = ce*ca; UpdateLight(this->KeyLight,this->KeyLightAngle[0],this->KeyLightAngle[1],ex,ey,ez); UpdateLight(this->FillLight,this->FillLightAngle[0],this->FillLightAngle[1],ex,ey,ez); // UpdateLight(this->Headlight,0.0,0.0,ex,ey,ez); UpdateLight(this->BackLight0,this->BackLightAngle[0],this->BackLightAngle[1],ex,ey,ez); UpdateLight(this->BackLight1,this->BackLightAngle[0],this->BackLightAngle[1],ex,ey,ez); } ifrit-3.4.2/core/ilightkit.h0000755000175700010010000000457412167404414014313 0ustar HomeNone/*========================================================================= Program: Ionization FRont Interactive Tool (IFRIT) Language: C++ Copyright (c) 2002-2012 Nick Gnedin All rights reserved. This file may be distributed and/or modified under the terms of the GNU General Public License version 2 as published by the Free Software Foundation and appearing in the file LICENSE.GPL included in the packaging of this file. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHORS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. =========================================================================*/ #ifndef ILIGHTKIT_H #define ILIGHTKIT_H #include class vtkRenderer; class iLightKit : public vtkLightKit { public: static iLightKit* New(); void AddLightsToRenderer(vtkRenderer *renderer); void SetAngles(float e, float a); inline void GetAngles(float a[2]) const { a[0] = mAngles[0]; a[1] = mAngles[1]; } void SetIntensities(float k, float f, float h); void GetIntensities(float i[3]) const; protected: virtual ~iLightKit(); private: iLightKit(); void UpdateAngles(); // // Hide setting directions for individual lights // void SetKeyLightAngle(double elevation, double azimuth){} void SetKeyLightAngle(double angle[2]){} void SetKeyLightElevation(double x){} void SetKeyLightAzimuth(double x){} void SetFillLightAngle(double elevation, double azimuth){} void SetFillLightAngle(double angle[2]){} void SetFillLightElevation(double x){} void SetFillLightAzimuth(double x){} void SetBackLightAngle(double elevation, double azimuth){} void SetBackLightAngle(double angle[2]){} void SetBackLightElevation(double x){} void SetBackLightAzimuth(double x){} double mAngles[2]; }; #endif // ILIGHTKIT_H ifrit-3.4.2/core/ilinetobandfilter.cpp0000755000175700010010000000303412167404431016341 0ustar HomeNone/*========================================================================= Program: Ionization FRont Interactive Tool (IFRIT) Language: C++ Copyright (c) 2002-2012 Nick Gnedin All rights reserved. This file may be distributed and/or modified under the terms of the GNU General Public License version 2 as published by the Free Software Foundation and appearing in the file LICENSE.GPL included in the packaging of this file. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHORS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. =========================================================================*/ #include "ilinetobandfilter.h" // // Templates // #include "igenericfiltertemplate.h" iLineToBandFilter::iLineToBandFilter(iViewSubject *vo) : iGenericPolyDataToPolyDataFilter(vo,1,true,false) { } void iLineToBandFilter::ProduceOutput() { this->ExecuteParent(); } ifrit-3.4.2/core/ilinetobandfilter.h0000644000175700010010000000313512167404414016006 0ustar HomeNone/*========================================================================= Program: Ionization FRont Interactive Tool (IFRIT) Language: C++ Copyright (c) 2002-2012 Nick Gnedin All rights reserved. This file may be distributed and/or modified under the terms of the GNU General Public License version 2 as published by the Free Software Foundation and appearing in the file LICENSE.GPL included in the packaging of this file. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHORS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. =========================================================================*/ #ifndef ILINETOBANDFILTER_H #define ILINETOBANDFILTER_H #include "igenericfilter.h" #include class iLineToBandFilter : public iGenericPolyDataToPolyDataFilter { IGENERICFILTER_DECLARE(iLineToBandFilter,vtkRuledSurfaceFilter); protected: virtual void ProduceOutput(); }; #endif // ILINETOBANDFILTER_H ifrit-3.4.2/core/ilinetotubefilter.cpp0000755000175700010010000002016412167404431016377 0ustar HomeNone/*========================================================================= Program: Ionization FRont Interactive Tool (IFRIT) Language: C++ Copyright (c) 2002-2012 Nick Gnedin All rights reserved. This file may be distributed and/or modified under the terms of the GNU General Public License version 2 as published by the Free Software Foundation and appearing in the file LICENSE.GPL included in the packaging of this file. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHORS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. =========================================================================*/ #include "ilinetotubefilter.h" #include #include #include #include #include #include // // Templates // #include "igenericfiltertemplate.h" iLineToTubeFilter::iLineToTubeFilter(iViewSubject *vo) : iGenericPolyDataToPolyDataFilter(vo,1,true,false) { } void iLineToTubeFilter::ProduceOutput() { vtkPolyData *input = vtkPolyData::SafeDownCast(this->GetInput()); vtkPolyData *output = this->GetOutput(); // // The code between === lines is copied from vtkTubeFilter.cxx file with minor modifications, as marked behind /// comments // Below is the original copyright notice. // // Copyright (c) Ken Martin, Will Schroeder, Bill Lorensen // All rights reserved. // See Copyright.txt or http://www.kitware.com/Copyright.htm for details. // // ========================================================================= // vtkPointData *pd=input->GetPointData(); vtkPointData *outPD=output->GetPointData(); vtkCellData *cd=input->GetCellData(); vtkCellData *outCD=output->GetCellData(); vtkCellArray *inLines = NULL; vtkDataArray *inNormals; vtkDataArray *inScalars=pd->GetScalars(); vtkDataArray *inVectors=pd->GetVectors(); vtkPoints *inPts; vtkIdType numPts = 0; vtkIdType numLines; vtkIdType numNewPts, numNewCells; vtkPoints *newPts; int deleteNormals=0; vtkFloatArray *newNormals; vtkIdType i; double range[2], maxSpeed=0; vtkCellArray *newStrips; vtkIdType npts=0, *pts=NULL; vtkIdType offset=0; vtkFloatArray *newTCoords=NULL; int abort=0; vtkIdType inCellId; double oldRadius=1.0; // Check input and initialize // vtkDebugMacro(<<"Creating tube"); if ( !(inPts=input->GetPoints()) || (numPts = inPts->GetNumberOfPoints()) < 1 || !(inLines = input->GetLines()) || (numLines = inLines->GetNumberOfCells()) < 1 ) { return; } // Create the geometry and topology numNewPts = numPts * this->NumberOfSides; /// ------ Removed ------------------------------------------ /// newPts = vtkPoints::New(); /// --------------------------------------------------------- /// ++++++ Added ++++++++++++++++++++++++++++++++++++++++++++ newPts = vtkPoints::New(inPts->GetDataType()); /// +++++++++++++++++++++++++++++++++++++++++++++++++++++++++ newPts->Allocate(numNewPts); newNormals = vtkFloatArray::New(); newNormals->SetName("TubeNormals"); newNormals->SetNumberOfComponents(3); newNormals->Allocate(3*numNewPts); newStrips = vtkCellArray::New(); newStrips->Allocate(newStrips->EstimateSize(1,numNewPts)); vtkCellArray *singlePolyline = vtkCellArray::New(); // Point data: copy scalars, vectors, tcoords. Normals may be computed here. outPD->CopyNormalsOff(); if ( (this->GenerateTCoords == VTK_TCOORDS_FROM_SCALARS && inScalars) || this->GenerateTCoords == VTK_TCOORDS_FROM_LENGTH || this->GenerateTCoords == VTK_TCOORDS_FROM_NORMALIZED_LENGTH ) { newTCoords = vtkFloatArray::New(); newTCoords->SetNumberOfComponents(2); newTCoords->Allocate(numNewPts); outPD->CopyTCoordsOff(); } outPD->CopyAllocate(pd,numNewPts); int generateNormals = 0; if ( !(inNormals=pd->GetNormals()) || this->UseDefaultNormal ) { deleteNormals = 1; inNormals = vtkFloatArray::New(); inNormals->SetNumberOfComponents(3); inNormals->SetNumberOfTuples(numPts); if ( this->UseDefaultNormal ) { for ( i=0; i < numPts; i++) { inNormals->SetTuple(i,this->DefaultNormal); } } else { // Normal generation has been moved to lower in the function. // This allows each different polylines to share vertices, but have // their normals (and hence their tubes) calculated independently generateNormals = 1; } } // If varying width, get appropriate info. // if ( inScalars ) { inScalars->GetRange(range,0); if ((range[1] - range[0]) == 0.0) { if (this->VaryRadius == VTK_VARY_RADIUS_BY_SCALAR ) { vtkWarningMacro(<< "Scalar range is zero!"); } range[1] = range[0] + 1.0; } if (this->VaryRadius == VTK_VARY_RADIUS_BY_ABSOLUTE_SCALAR) { // temporarily set the radius to 1.0 so that radius*scalar = scalar oldRadius = this->Radius; this->Radius = 1.0; if (range[0] < 0.0) { vtkWarningMacro(<< "Scalar values fall below zero when using absolute radius values!"); } } } if ( inVectors ) { maxSpeed = inVectors->GetMaxNorm(); } // Copy selected parts of cell data; certainly don't want normals // numNewCells = inLines->GetNumberOfCells() * this->NumberOfSides + 2; outCD->CopyNormalsOff(); outPD->CopyAllocate(pd,numNewCells); // Create points along each polyline that are connected into NumberOfSides // triangle strips. Texture coordinates are optionally generated. // this->Theta = 2.0*vtkMath::Pi() / this->NumberOfSides; vtkPolyLine *lineNormalGenerator = vtkPolyLine::New(); for (inCellId=0, inLines->InitTraversal(); inLines->GetNextCell(npts,pts) && !abort; inCellId++) { this->UpdateProgress((double)inCellId/numLines); abort = this->GetAbortExecute(); if (npts < 2) { vtkWarningMacro(<< "Less than two points in line!"); continue; //skip tubing this polyline } // If necessary calculate normals, each polyline calculates its // normals independently, avoiding conflicts at shared vertices. if (generateNormals) { singlePolyline->Reset(); //avoid instantiation singlePolyline->InsertNextCell(npts,pts); if ( !lineNormalGenerator->GenerateSlidingNormals(inPts,singlePolyline, inNormals) ) { vtkWarningMacro(<< "No normals for line!"); continue; //skip tubing this polyline } } // Generate the points around the polyline. The tube is not stripped // if the polyline is bad. // if ( !this->GeneratePoints(offset,npts,pts,inPts,newPts,pd,outPD, newNormals,inScalars,range,inVectors, maxSpeed,inNormals) ) { vtkWarningMacro(<< "Could not generate points!"); continue; //skip tubing this polyline } // Generate the strips for this polyline (including caps) // this->GenerateStrips(offset,npts,pts,inCellId,cd,outCD,newStrips); // Generate the texture coordinates for this polyline // if ( newTCoords ) { this->GenerateTextureCoords(offset,npts,pts,inPts,inScalars,newTCoords); } // Compute the new offset for the next polyline offset = this->ComputeOffset(offset,npts); }//for all polylines singlePolyline->Delete(); // reset the radius to ite orginal value if necessary if (this->VaryRadius == VTK_VARY_RADIUS_BY_ABSOLUTE_SCALAR) { this->Radius = oldRadius; } // Update ourselves // if ( deleteNormals ) { inNormals->Delete(); } if ( newTCoords ) { outPD->SetTCoords(newTCoords); newTCoords->Delete(); } output->SetPoints(newPts); newPts->Delete(); output->SetStrips(newStrips); newStrips->Delete(); outPD->SetNormals(newNormals); newNormals->Delete(); lineNormalGenerator->Delete(); output->Squeeze(); // // ========================================================================= // } ifrit-3.4.2/core/ilinetotubefilter.h0000644000175700010010000000310512167404414016036 0ustar HomeNone/*========================================================================= Program: Ionization FRont Interactive Tool (IFRIT) Language: C++ Copyright (c) 2002-2012 Nick Gnedin All rights reserved. This file may be distributed and/or modified under the terms of the GNU General Public License version 2 as published by the Free Software Foundation and appearing in the file LICENSE.GPL included in the packaging of this file. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHORS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. =========================================================================*/ #ifndef ILINETOTUBEFILTER_H #define ILINETOTUBEFILTER_H #include "igenericfilter.h" #include class iLineToTubeFilter : public iGenericPolyDataToPolyDataFilter { IGENERICFILTER_DECLARE(iLineToTubeFilter,vtkTubeFilter); protected: virtual void ProduceOutput(); }; #endif // ILINETOTUBEFILTER_H ifrit-3.4.2/core/ilookuptable.cpp0000755000175700010010000000712212167404432015340 0ustar HomeNone/*========================================================================= Program: Ionization FRont Interactive Tool (IFRIT) Language: C++ Copyright (c) 2002-2012 Nick Gnedin All rights reserved. This file may be distributed and/or modified under the terms of the GNU General Public License version 2 as published by the Free Software Foundation and appearing in the file LICENSE.GPL included in the packaging of this file. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHORS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. =========================================================================*/ #include "ilookuptable.h" #include "ierror.h" #include "imath.h" #include "ipalette.h" #include "ipaletteset.h" #include // // Optimized vtkLookupTable // iLookupTable* iLookupTable::New() { return new iLookupTable; } iLookupTable::iLookupTable() { mPaletteId = 0; } iLookupTable::~iLookupTable() { } void iLookupTable::SetPaletteId(int n) { if(n != mPaletteId) { mPaletteId = n; this->Modified(); this->Build(); } } void iLookupTable::SetReversed(bool s) { if(s && mPaletteId>0) { mPaletteId = -mPaletteId; this->Modified(); this->Build(); } if(!s && mPaletteId<0) { mPaletteId = -mPaletteId; this->Modified(); this->Build(); } } void iLookupTable::SetColor(const iColor &c) { double *rgb = c.ToVTK(); double hsv[3]; vtkMath::RGBToHSV(rgb,hsv); this->SetHueRange(hsv[0],hsv[0]); this->SetSaturationRange(hsv[1],hsv[1]); this->SetValueRange(0.0,1.0); this->Modified(); this->Build(); } void iLookupTable::OnStretchChanged() { switch(this->GetStretch()) { case iDataStretch::Log: { if(this->TableRange[0] < 1*iMath::_DoubleRes) this->TableRange[0] = 1*iMath::_DoubleRes; if(this->TableRange[1] < 2*iMath::_DoubleRes) this->TableRange[1] = 2*iMath::_DoubleRes; this->SetScaleToLog10(); break; } default: { this->SetScaleToLinear(); } } this->Modified(); } void iLookupTable::ForceBuild() { vtkLookupTable *lut = iPaletteSet::Default()->GetLookupTable(mPaletteId); if(lut != 0) { this->Table->Initialize(); this->Table->SetArray(lut->GetPointer(0),4*lut->GetNumberOfTableValues(),1); this->BuildTime.Modified(); } else { this->Table->Initialize(); vtkLookupTable::ForceBuild(); } } void iLookupTable::MapScalarsThroughTable2(void *input, unsigned char *output, int inputDataType, int numberOfValues, int inputIncrement, int outputFormat) { // // This is how this function is used. // //this->MapScalarsThroughTable2(scalars->GetVoidPointer(comp), // newColors->GetPointer(0), // scalars->GetDataType(), // scalars->GetNumberOfTuples(), // scalars->GetNumberOfComponents(), // VTK_RGBA); this->vtkLookupTable::MapScalarsThroughTable2(input,output,inputDataType,numberOfValues,inputIncrement,outputFormat); } ifrit-3.4.2/core/ilookuptable.h0000755000175700010010000000357412167404414015014 0ustar HomeNone/*========================================================================= Program: Ionization FRont Interactive Tool (IFRIT) Language: C++ Copyright (c) 2002-2012 Nick Gnedin All rights reserved. This file may be distributed and/or modified under the terms of the GNU General Public License version 2 as published by the Free Software Foundation and appearing in the file LICENSE.GPL included in the packaging of this file. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHORS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. =========================================================================*/ #ifndef ILOOKUPTABLE_H #define ILOOKUPTABLE_H #include #include "idatastretch.h" class iColor; class iLookupTable : public vtkLookupTable, public iDataStretchUser { public: static iLookupTable* New(); void SetPaletteId(int n); void SetReversed(bool s); void SetColor(const iColor &c); virtual void ForceBuild(); virtual void MapScalarsThroughTable2(void *input, unsigned char *output, int inputDataType, int numberOfValues, int inputIncrement, int outputFormat); protected: virtual ~iLookupTable(); private: iLookupTable(); virtual void OnStretchChanged(); int mPaletteId; }; #endif // ILOOKUPTABLE_H ifrit-3.4.2/core/imagnifier.cpp0000644000175700010010000002014212167404432014752 0ustar HomeNone/*========================================================================= Program: Ionization FRont Interactive Tool (IFRIT) Language: C++ Copyright (c) 2002-2012 Nick Gnedin All rights reserved. This file may be distributed and/or modified under the terms of the GNU General Public License version 2 as published by the Free Software Foundation and appearing in the file LICENSE.GPL included in the packaging of this file. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHORS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. =========================================================================*/ #include "imagnifier.h" #include "ierror.h" #include "itransform.h" #include #include #include #include #include #include #include iMagnifier* iMagnifier::New() { return new iMagnifier; } iMagnifier::iMagnifier() { this->Magnification = 1; mTileX = mTileY = 0; } iMagnifier::~iMagnifier() { } int iMagnifier::ProcessRequest(vtkInformation* request, vtkInformationVector** inputVector, vtkInformationVector* outputVector) { // generate the data if(request->Has(vtkDemandDrivenPipeline::REQUEST_DATA())) { this->RequestMyData(request, inputVector, outputVector); return 1; } // execute information if(request->Has(vtkDemandDrivenPipeline::REQUEST_INFORMATION())) { this->RequestInformation(request, inputVector, outputVector); return 1; } return this->Superclass::ProcessRequest(request, inputVector, outputVector); } void iMagnifier::RequestMyData(vtkInformation *, vtkInformationVector **, vtkInformationVector* outputVector) { vtkInformation *outInfo = outputVector->GetInformationObject(0); vtkImageData *data = vtkImageData::SafeDownCast(outInfo->Get(vtkDataObject::DATA_OBJECT())); data->SetExtent(outInfo->Get(vtkStreamingDemandDrivenPipeline::UPDATE_EXTENT())); data->AllocateScalars(); this->Render(data); } void iMagnifier::Render(vtkImageData *data) { // // The code between === lines is copied from vtkRenderLargeImage.cxx file with minor modifications, as marked behind /// comments // Below is the original copyright notice. // // Copyright (c) Ken Martin, Will Schroeder, Bill Lorensen // All rights reserved. // See Copyright.txt or http://www.kitware.com/Copyright.htm for details. // // ========================================================================= // int inExtent[6]; /// ++++++ Added ++++++++++++++++++++++++++++++++++++++++++++ vtkIdType inIncr[3]; /// +++++++++++++++++++++++++++++++++++++++++++++++++++++++++ int *size; int inWindowExtent[4]; /// ------ Removed ------------------------------------------ /// double viewAngle, parallelScale; /// --------------------------------------------------------- double windowCenter[2]; vtkCamera *cam; unsigned char *pixels, *outPtr; int x, y, row; int rowSize, rowStart, rowEnd, colStart, colEnd; int doublebuffer; int swapbuffers = 0; if (this->GetOutput()->GetScalarType() != VTK_UNSIGNED_CHAR) { vtkErrorMacro("mismatch in scalar types!"); return; } // Get the requested extents. this->GetOutput()->GetUpdateExtent(inExtent); // get and transform the increments data->GetIncrements(inIncr); // get the size of the render window size = this->Input->GetRenderWindow()->GetSize(); // convert the request into windows inWindowExtent[0] = inExtent[0]/size[0]; inWindowExtent[1] = inExtent[1]/size[0]; inWindowExtent[2] = inExtent[2]/size[1]; inWindowExtent[3] = inExtent[3]/size[1]; // store the old view angle & set the new cam = this->Input->GetActiveCamera(); cam->GetWindowCenter(windowCenter); /// ------ Removed ------------------------------------------ /// viewAngle = cam->GetViewAngle(); /// parallelScale = cam->GetParallelScale(); /// cam->SetViewAngle(asin(sin(viewAngle*3.1415926/360.0)/this->Magnification) /// * 360.0 / 3.1415926); /// cam->SetParallelScale(parallelScale/this->Magnification); /// --------------------------------------------------------- /// ++++++ Added ++++++++++++++++++++++++++++++++++++++++++++ // // A better way to magnify is to use the camera's UserTransform // vtkHomogeneousTransform *ct = cam->GetUserTransform(); if(ct != 0) ct->Register(this); iTransform *ut = iTransform::New(); cam->SetUserTransform(ut); ut->Delete(); /// +++++++++++++++++++++++++++++++++++++++++++++++++++++++++ // are we double buffering? If so, read from back buffer .... doublebuffer = this->Input->GetRenderWindow()->GetDoubleBuffer(); if (doublebuffer) { // save swap buffer state to restore later swapbuffers = this->Input->GetRenderWindow()->GetSwapBuffers(); this->Input->GetRenderWindow()->SetSwapBuffers(0); } // render each of the tiles required to fill this request for (y = inWindowExtent[2]; y <= inWindowExtent[3]; y++) { for (x = inWindowExtent[0]; x <= inWindowExtent[1]; x++) { /// ------ Removed ------------------------------------------ /// cam->SetWindowCenter(x*2 - this->Magnification*(1-windowCenter[0]) + 1, /// y*2 - this->Magnification*(1-windowCenter[1]) + 1); /// --------------------------------------------------------- /// ++++++ Added ++++++++++++++++++++++++++++++++++++++++++++ // // This is where the bug is - in perspective projection the view is skewed, so // a better way to magnify is to use the camera's UserTransform. // mTileX = x; mTileY = y; ut->Identity(); ut->Scale(this->Magnification,this->Magnification,1); ut->Translate(-double(2*x+1-this->Magnification)/this->Magnification,-double(2*y+1-this->Magnification)/this->Magnification,0.0); /// +++++++++++++++++++++++++++++++++++++++++++++++++++++++++ this->Input->GetRenderWindow()->Render(); pixels = this->Input->GetRenderWindow()->GetPixelData(0,0,size[0] - 1, size[1] - 1, !doublebuffer); // now stuff the pixels into the data row by row colStart = inExtent[0] - x*size[0]; if (colStart < 0) { colStart = 0; } colEnd = size[0] - 1; if (colEnd > (inExtent[1] - x*size[0])) { colEnd = inExtent[1] - x*size[0]; } rowSize = colEnd - colStart + 1; // get the output pointer and do arith on it if necc outPtr = (unsigned char *)data->GetScalarPointer(inExtent[0],inExtent[2],0); outPtr = outPtr + (x*size[0] - inExtent[0])*inIncr[0] + (y*size[1] - inExtent[2])*inIncr[1]; rowStart = inExtent[2] - y*size[1]; if (rowStart < 0) { rowStart = 0; } rowEnd = size[1] - 1; if (rowEnd > (inExtent[3] - y*size[1])) { rowEnd = (inExtent[3] - y*size[1]); } for (row = rowStart; row <= rowEnd; row++) { memcpy(outPtr + row*inIncr[1] + colStart*inIncr[0], pixels + row*size[0]*3 + colStart*3, rowSize*3); } // free the memory delete [] pixels; } } // restore the state of the SwapBuffers bit before we mucked with it. if (doublebuffer && swapbuffers) { this->Input->GetRenderWindow()->SetSwapBuffers(swapbuffers); } /// ------ Removed ------------------------------------------ /// cam->SetViewAngle(viewAngle); /// cam->SetParallelScale(parallelScale); /// --------------------------------------------------------- /// ++++++ Added ++++++++++++++++++++++++++++++++++++++++++++ cam->SetUserTransform(ct); if(ct != 0) ct->Delete(); /// +++++++++++++++++++++++++++++++++++++++++++++++++++++++++ cam->SetWindowCenter(windowCenter[0],windowCenter[1]); // // ========================================================================= // } ifrit-3.4.2/core/imagnifier.h0000644000175700010010000000357512167404414014432 0ustar HomeNone/*========================================================================= Program: Ionization FRont Interactive Tool (IFRIT) Language: C++ Copyright (c) 2002-2012 Nick Gnedin All rights reserved. This file may be distributed and/or modified under the terms of the GNU General Public License version 2 as published by the Free Software Foundation and appearing in the file LICENSE.GPL included in the packaging of this file. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHORS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. =========================================================================*/ // // vtkRenderLargeImage with a bug fix // #ifndef IMAGNIFIER_H #define IMAGNIFIER_H #include class iMagnifier : public vtkRenderLargeImage { public: static iMagnifier* New(); inline void GetTile(int &x, int &y){ x = mTileX; y = mTileY; } virtual int ProcessRequest(vtkInformation *request, vtkInformationVector **inInfo, vtkInformationVector *outInfo); protected: void RequestMyData(vtkInformation *request, vtkInformationVector **inInfo, vtkInformationVector *outInfo); virtual ~iMagnifier(); private: iMagnifier(); void Render(vtkImageData *data); int mTileX, mTileY; }; #endif // IMAGNIFIER_H ifrit-3.4.2/core/imarker.cpp0000755000175700010010000002064312167404432014303 0ustar HomeNone/*========================================================================= Program: Ionization FRont Interactive Tool (IFRIT) Language: C++ Copyright (c) 2002-2012 Nick Gnedin All rights reserved. This file may be distributed and/or modified under the terms of the GNU General Public License version 2 as published by the Free Software Foundation and appearing in the file LICENSE.GPL included in the packaging of this file. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHORS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. =========================================================================*/ #include "imarker.h" #include "icamera.h" #include "icaption.h" #include "idata.h" #include "ierror.h" #include "ipointglyph.h" #include "irendertool.h" #include "ireplicatedactor.h" #include "iviewmodule.h" #include "iviewobject.h" #include "iviewobjectfamily.h" #include #include #include // // Templates // #include "iarraytemplate.h" using namespace iParameter; IVIEWSUBJECT_DEFINE_TYPE(iMarker,Marker,m); IOBJECT_DEFINE_KEY(iMarker,ColorAutomatic,ca,Bool,1); IOBJECT_DEFINE_KEY(iMarker,CaptionText,ct,String,1); IOBJECT_DEFINE_KEY(iMarker,CaptionPosition,cx,Float,2); IOBJECT_DEFINE_KEY(iMarker,InteractiveMove,im,Bool,1); IOBJECT_DEFINE_KEY(iMarker,Scaled,sc,Bool,1); IOBJECT_DEFINE_KEY(iMarker,Type,t,Int,1); IOBJECT_DEFINE_KEY(iMarker,Transform,tf,Float,6); IOBJECT_DEFINE_DISTANCE_KEY(iMarker,Size,s); IOBJECT_DEFINE_KEY(iMarker,TypeAsString,-tas,String,1); // // Inherited keys // IVIEWSUBJECT_DEFINE_INHERITED_KEYS_COMMON(iMarker); IVIEWSUBJECT_DEFINE_INHERITED_KEYS_POSITION(iMarker); IVIEWSUBJECT_DEFINE_INHERITED_KEYS_COLOR(iMarker,1); IVIEWSUBJECT_DEFINE_INHERITED_KEYS_OPACITY(iMarker,1); iMarker* iMarker::New(iViewModule *vm) { IERROR_ASSERT(vm); iMarker *tmp = new iMarker(vm); IERROR_ASSERT(tmp); // non-inheritable, so no need to use ExtensionFactory tmp->Configure(); return tmp; } iMarker::iMarker(iViewModule *vm) : iSolidViewSubject(vm,iDataType::Null(),"Marker",1,ViewSubject::Flag::AlwaysShaded|ViewSubject::Flag::NoReplicating|ViewSubject::Flag::HasPosition|ViewSubject::Flag::NoPalette), mSize(vm,true) { mSubjectId = ViewSubject::Id::Undefined; mSize = 0.08; mColorAuto = true; mCaptionText = ""; mInteractiveMove = false; mTransform[0] = mTransform[1] = mTransform[2] = 0.0; mTransform[3] = mTransform[4] = mTransform[5] = 1.0; // // Do VTK stuff // mActors[0]->SetScaled(true); mObject = iPointGlyph::New(this); IERROR_ASSERT(mObject); mCaption = iCaption::New(vm->GetRenderTool()); IERROR_ASSERT(mCaption); mObject->SetType(PointGlyphType::Sphere); mActors[0]->SetInput(mObject->GetOutput()); // // Add observer to keep information about this object // const iPosition x(this->GetViewModule()); float xc[2] = { 0.0, 0.0 }; this->SetColor(0,iColor(255,0,0)); this->SetPosition(x); this->SetCaptionPosition(xc); this->SetSize(mSize); this->GetViewModule()->AddObject(mCaption); mCaption->VisibilityOff(); } iMarker::~iMarker() { if(mIsInitialized) { this->GetViewModule()->RemoveObject(mCaption); // // Update attached objects // for(int j=0; jUpdateAfterMarkerDelete(this); } this->GetViewModule()->RemoveObject(mCaption); mCaption->Delete(); mObject->Delete(); } void iMarker::FinishInitialization() { } void iMarker::SetType(int m) { mObject->SetType(m); this->ClearCache(); } int iMarker::GetType() const { return mObject->GetType(); } const iString iMarker::GetTypeAsString() const { return mObject->GetName(); } void iMarker::SetScaled(bool s) { mActors[0]->SetScaled(s); this->ClearCache(); } bool iMarker::GetScaled() const { return mActors[0]->GetScaled(); } void iMarker::UpdatePosition(const iPosition &) { this->Move(mPosition); if(!mInteractiveMove) this->FinishMoving(); // always finish this->ClearCache(); } void iMarker::Move(const iPosition& p) { mPosition = p; mActors[0]->SetPosition(mPosition); mCaption->SetAttachmentPoint(mPosition); if(mInteractiveMove) this->FinishMoving(); this->ClearCache(); } void iMarker::FinishMoving() { // // Update attached objects // int j; for(j=0; jUpdateAfterMarkerMove(); } void iMarker::SetCaptionPosition(const float *x) { this->SetCaptionPosition(x[0],x[1]); } void iMarker::SetCaptionPosition(float x, float y) { mCapPos[0] = x; mCapPos[1] = y; mCaption->SetPosition(x,y); this->ClearCache(); } void iMarker::SetSize(double s) { if(s > 0.0) { iDistance tmp(this->GetViewModule(),true); tmp = s; this->SetSize(tmp); } } void iMarker::SetSize(const iDistance &s) { if(s < 10.01) { mSize = s; mActors[0]->SetBasicScale(mSize); float ps = 10.0*pow(s,0.3); if(ps < 1.0) ps = 1.0; if(ps > 10.0) ps = 10.0; mActors[0]->GetProperty()->SetPointSize(ps); this->ClearCache(); } } void iMarker::SetCaptionText(const iString &s) { mCaptionText = s; mCaption->SetText(s); if(s.Length() > 0) mCaption->VisibilityOn(); else mCaption->VisibilityOff(); this->ClearCache(); } void iMarker::SetInteractiveMove(bool s) { mInteractiveMove = s; this->ClearCache(); } void iMarker::SetTransform(const float *t) { int i; for(i=0; i<6; i++) mTransform[i] = t[i]; mActors[0]->SetAxisScale(t[3],t[4],t[5]); mActors[0]->SetOrientation(t[0],t[1],t[2]); this->ClearCache(); } void iMarker::ShowBody(bool show) { if(show) { mActors[0]->VisibilityOn(); if(mCaptionText.Length() > 0) mCaption->VisibilityOn(); else mCaption->VisibilityOff(); } else { mActors[0]->VisibilityOff(); mCaption->VisibilityOff(); } } // // Two functions used in saving/restoring the state and in creating new instances with // void iMarker::SolidViewSubjectPackStateBody(iString &s) const { this->PackValue(s,KeyColorAutomatic(),mColorAuto); this->PackValue(s,KeyInteractiveMove(),mInteractiveMove); this->PackValue(s,KeyScaled(),this->GetScaled()); this->PackValue(s,KeyType(),this->GetType()); this->PackValue(s,KeyCaptionText(),mCaptionText); this->PackValueDistance(s,KeySize(),mSize); this->PackValue(s,KeyCaptionPosition(),mCapPos,2); this->PackValue(s,KeyTransform(),mTransform,6); this->PackValue(s,KeyTypeAsString(),this->GetTypeAsString()); } void iMarker::SolidViewSubjectUnPackStateBody(const iString &s) { int i; bool b; float fv[6]; iColor c; iString z; if(this->UnPackValue(s,KeyColorAutomatic(),b)) { mColorAuto = b; this->ClearCache(); } if(this->UnPackValue(s,KeyInteractiveMove(),b)) this->SetInteractiveMove(b); if(this->UnPackValue(s,KeyScaled(),b)) this->SetScaled(b); if(this->UnPackValue(s,KeyType(),i)) this->SetType(i); if(this->UnPackValue(s,KeyCaptionText(),z)) this->SetCaptionText(z); if(this->UnPackValueDistance(s,KeySize(),mSize)) this->SetSize(mSize); fv[0] = mCapPos[0]; fv[1] = mCapPos[1]; if(this->UnPackValue(s,KeyCaptionPosition(),fv,2)) this->SetCaptionPosition(fv); for(i=0; i<6; i++) fv[i] = mTransform[i]; if(this->UnPackValue(s,KeyTransform(),fv,6)) this->SetTransform(fv); } void iMarker::ShowColorBarsBody(bool) { } void iMarker::ResetPipeline() { } void iMarker::AttachViewSubject(iViewSubject *o) { mAttachedObjects.AddUnique(o); } void iMarker::DetachViewSubject(iViewSubject *o) { mAttachedObjects.Remove(o); } bool iMarker::CanBeShown() const { return true; } void iMarker::ViewSubjectSyncWithData(const iDataSyncRequest &) { // // Attach all vectors // int j; for(j=0; j<=this->GetViewModule()->GetViewObjectFamily(ViewSubject::Id::VectorField)->GetMaxMemberIndex(); j++) { this->AttachViewSubject(this->GetViewModule()->GetViewObjectFamily(ViewSubject::Id::VectorField)->GetMember(j)->GetViewSubject()); } // // Update attached objects // for(j=0; jUpdateAfterMarkerAdd(this); } ifrit-3.4.2/core/imarker.h0000755000175700010010000000733712167404414013755 0ustar HomeNone/*========================================================================= Program: Ionization FRont Interactive Tool (IFRIT) Language: C++ Copyright (c) 2002-2012 Nick Gnedin All rights reserved. This file may be distributed and/or modified under the terms of the GNU General Public License version 2 as published by the Free Software Foundation and appearing in the file LICENSE.GPL included in the packaging of this file. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHORS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. =========================================================================*/ #ifndef IMARKER_H #define IMARKER_H #include "isolidviewsubject.h" class iCaption; class iPointGlyph; class iMarker : public iSolidViewSubject { friend class iControlModule; public: vtkTypeMacro(iMarker,iSolidViewSubject); static iMarker* New(iViewModule *vm = 0); static const iObjectType& Type(); IOBJECT_DECLARE_GETSET2(Type,int); //virtual void SetType(int m); //int GetType() const; IOBJECT_DECLARE_GETSET1(CaptionText,const iString&); //virtual void SetCaptionText(const iString &s); //inline iString GetCaptionText() const { return mCaptionText; } IOBJECT_DECLARE_GETSET1(InteractiveMove,bool); //virtual void SetInteractiveMove(bool s); //inline bool GetInteractiveMoveShow() const { return mInteractiveMove; } IOBJECT_DECLARE_GETSET2(Scaled,bool); //virtual void SetScaled(bool s); //bool GetScaled() const; IOBJECT_DECLARE_GETSET(CaptionPosition,mCapPos,const float *); //virtual void SetCaptionPosition(const float *x); //inline const float* GetCaptionPosition() const { return mCapPos; } void SetCaptionPosition(float x, float y); IOBJECT_DECLARE_GET(ColorAutomatic,mColorAuto,bool); //inline bool isColorAutomatic() const { return mColorAuto; } IOBJECT_DECLARE_GETSET1(Transform,const float *); //virtual void SetTransform(const float *x); //inline const float* GetTransform() const { return mTransform; } IOBJECT_DECLARE_GETSET_DISTANCE(Size,mSize); //virtual void SetSize(const iDistance &s); //inline const iDistance& GetSize() const { return mSize; } virtual void SetSize(double s); const iString GetTypeAsString() const; static const iObjectKey& KeyTypeAsString(); void AttachViewSubject(iViewSubject *vs); void DetachViewSubject(iViewSubject *vs); inline iPointGlyph* GetMarkerObject() const { return mObject; } inline iCaption* GetMarkerCaption() const { return mCaption; } void Move(const iPosition& p); void FinishMoving(); virtual bool IsThereData() const { return true; } // // Inherited members // ISOLIDVIEWSUBJECT_DECLARE_INHERITED_KEYS; ISOLIDVIEWSUBJECT_DECLARE_INHERITED_MEMBERS; protected: virtual ~iMarker(); virtual void ConfigureBody(){} virtual void FinishInitialization(); virtual void UpdatePosition(const iPosition &oldPos); private: iMarker(iViewModule *vm); // // VTK stuff // iPointGlyph *mObject; iCaption *mCaption; iDistance mSize; float mCapPos[2], mTransform[6]; iString mCaptionText; bool mColorAuto, mInteractiveMove; iSearchableArray mAttachedObjects; }; #endif // IMARKER_H ifrit-3.4.2/core/imarkerfamily.cpp0000755000175700010010000001257212167404432015507 0ustar HomeNone/*========================================================================= Program: Ionization FRont Interactive Tool (IFRIT) Language: C++ Copyright (c) 2002-2012 Nick Gnedin All rights reserved. This file may be distributed and/or modified under the terms of the GNU General Public License version 2 as published by the Free Software Foundation and appearing in the file LICENSE.GPL included in the packaging of this file. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHORS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. =========================================================================*/ #include "imarkerfamily.h" #include "icommoneventobservers.h" #include "ilegend.h" #include "imarker.h" #include "ipointglyph.h" #include "irendertool.h" #include "iviewmodule.h" #include #include // // Templates // #include "iarraytemplate.h" #include "iviewfamilytemplate.h" using namespace iParameter; iMarkerFamily* iMarkerFamily::New(iViewModule *vm) { return new iMarkerFamily(vm); } iMarkerFamily::iMarkerFamily(iViewModule *vm) : iViewFamily(vm) { mLegendPosition = 0; mHandles = vtkPointWidget::New(); IERROR_ASSERT(mHandles); mHandles->XShadowsOn(); mHandles->YShadowsOn(); mHandles->ZShadowsOn(); mHandles->OutlineOff(); mHandles->TranslationModeOff(); mHandles->SetInteractor(mParent->GetRenderTool()->GetInteractor()); mHandles->GetProperty()->SetColor(0.0,0.0,0.0); mHandles->GetProperty()->SetLineWidth(4.0); // mHandles->GetSelectedProperty()->SetColor(1.0,0.0,0.0); mHandles->GetSelectedProperty()->SetLineWidth(2.0); mHandles->PlaceWidget(-1.0,1.0,-1.0,1.0,-1.0,1.0); mMotionObserver = iMarkerEventObserver::New(mParent); IERROR_ASSERT(mMotionObserver); mHandles->AddObserver(vtkCommand::InteractionEvent,mMotionObserver); mHandles->AddObserver(vtkCommand::EndInteractionEvent,mMotionObserver); // // vtkLegendBoxActor is defined under earlier VTK versions, but // markers cannot be positioned without the vtkPointWidgets, so the legend // is useless then too. // mLegend = iLegend::New(mParent->GetRenderTool()); IERROR_ASSERT(mLegend); this->SetLegendPosition(mLegendPosition); mLegend->VisibilityOff(); mParent->GetRenderTool()->AddObject(mLegend); } iMarkerFamily::~iMarkerFamily() { // // Legend needs to be deleted before markers - otherwise, markers get stuck somewhere and GarbareCollector crashes. // mParent->GetRenderTool()->RemoveObject(mLegend); mLegend->Delete(); mMotionObserver->Delete(); mHandles->Off(); mHandles->SetInteractor(0); mHandles->Delete(); } int iMarkerFamily::CreateMember() { int ret = this->iViewFamily::CreateMember(); if(ret > -1) { this->BuildLegend(); this->SetCurrentMemberIndex(ret); this->GetCurrentMember()->SetPosition(ViewSubject::Location::FocalPoint); } return ret; } bool iMarkerFamily::DeleteMember(int i) { bool c = (i == this->GetCurrentMemberIndex()); bool ret = this->iViewFamily::DeleteMember(i); if(ret) { this->BuildLegend(); if(c) this->ShowHandles(false); } return ret; } void iMarkerFamily::ShowLegend(bool s) { if(s) { this->BuildLegend(); mLegend->VisibilityOn(); } else mLegend->VisibilityOff(); } bool iMarkerFamily::IsLegendVisible() { return (mLegend->GetVisibility() != 0); } void iMarkerFamily::SetLegendPosition(int p) { if(p>=0 && p<=1) { mLegendPosition = p; switch (p) { case 0: { mLegend->SetPosition(0.73,0.02); break; } case 1: { mLegend->SetPosition(0.02,0.02); break; } } } } void iMarkerFamily::SetHandlesColor(const iColor &c) { mHandles->GetProperty()->SetColor(c.ToVTK()); } void iMarkerFamily::ShowHandles(bool s) { if(s) { mHandles->SetPosition(this->GetCurrentMember()->GetPosition()[0],this->GetCurrentMember()->GetPosition()[1],this->GetCurrentMember()->GetPosition()[2]); mHandles->On(); } else { mHandles->Off(); } } bool iMarkerFamily::IsHandlesVisible() { return (mHandles->GetEnabled() != 0); } void iMarkerFamily::UpdateLegend() { this->BuildLegend(-1); } void iMarkerFamily::BuildLegend(int n) { int i; if(n == -1) n = this->GetCurrentMemberIndex(); if(n<0 || n>this->GetMaxMemberIndex()) { mLegend->SetNumberOfEntries(1+this->GetMaxMemberIndex()); for(i=0; i<=this->GetMaxMemberIndex(); i++) { this->UpdateEntry(i); } } else this->UpdateEntry(n); } void iMarkerFamily::UpdateEntry(int n) { // // Fix a bug in vtkLegendBoxActor // iMarker *m = this->GetMember(n); if(m!=0 && m->GetCaptionText().Length()>0) { mLegend->SetEntry(n,m->GetMarkerObject()->GetOutput(),m->GetCaptionText().ToCharPointer(),m->GetColor(0).ToVTK()); } else { mLegend->SetEntry(n,m->GetMarkerObject()->GetOutput()," ",m->GetColor(0).ToVTK()); } } ifrit-3.4.2/core/imarkerfamily.h0000755000175700010010000000422112167404414015144 0ustar HomeNone/*========================================================================= Program: Ionization FRont Interactive Tool (IFRIT) Language: C++ Copyright (c) 2002-2012 Nick Gnedin All rights reserved. This file may be distributed and/or modified under the terms of the GNU General Public License version 2 as published by the Free Software Foundation and appearing in the file LICENSE.GPL included in the packaging of this file. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHORS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. =========================================================================*/ #ifndef IMARKERFAMILY_H #define IMARKERFAMILY_H #include "iviewfamily.h" class iColor; class iLegend; class iMarker; class iMarkerEventObserver; class iViewModule; class vtkPointWidget; class iMarkerFamily : public iViewFamily { public: static iMarkerFamily* New(iViewModule *vm); virtual int CreateMember(); virtual bool DeleteMember(int i); void ShowLegend(bool s); bool IsLegendVisible(); void UpdateLegend(); void SetLegendPosition(int p); inline int GetLegendPosition() const { return mLegendPosition; } void SetHandlesColor(const iColor &c); void ShowHandles(bool s); bool IsHandlesVisible(); protected: virtual ~iMarkerFamily(); private: iMarkerFamily(iViewModule *vm); void BuildLegend(int i = -2); void UpdateEntry(int i); int mLegendPosition; iMarkerEventObserver *mMotionObserver; vtkPointWidget *mHandles; iLegend *mLegend; }; #endif // IMARKERFAMILY_H ifrit-3.4.2/core/imath.cpp0000644000175700010010000000323512167404432013746 0ustar HomeNone/*========================================================================= Program: Ionization FRont Interactive Tool (IFRIT) Language: C++ Copyright (c) 2002-2012 Nick Gnedin All rights reserved. This file may be distributed and/or modified under the terms of the GNU General Public License version 2 as published by the Free Software Foundation and appearing in the file LICENSE.GPL included in the packaging of this file. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHORS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. =========================================================================*/ #include "imath.h" #include namespace iMath { bool Intersect3Planes(double *p1, double *p2, double *p3, double *x) { int i; double atmp[9], *a[3]; a[0] = atmp + 0; a[1] = atmp + 3; a[2] = atmp + 6; for(i=0; i<3; i++) { a[0][i] = p1[i]; a[1][i] = p2[i]; a[2][i] = p3[i]; } x[0] = -p1[3]; x[1] = -p2[3]; x[2] = -p3[3]; return (vtkMath::SolveLinearSystem(a,x,3) != 0); } } ifrit-3.4.2/core/imath.h0000755000175700010010000000731012167404414013414 0ustar HomeNone/*========================================================================= Program: Ionization FRont Interactive Tool (IFRIT) Language: C++ Copyright (c) 2002-2012 Nick Gnedin All rights reserved. This file may be distributed and/or modified under the terms of the GNU General Public License version 2 as published by the Free Software Foundation and appearing in the file LICENSE.GPL included in the packaging of this file. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHORS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. =========================================================================*/ // // A few functions and macros for easier math and template creation. // #ifndef IMATH_H #define IMATH_H #include #include #include namespace iMath { #ifdef INT_MAX const int _IntMax = INT_MAX; #else const int _IntMax = 2147483647; #endif #ifdef INT_MIN const int _IntMin = INT_MIN; #else const int _IntMin = -2147483648; #endif #ifdef UINT_MAX const unsigned int _UnsignedIntMax = UINT_MAX; #else const unsigned int _UnsignedIntMax = 4294967295U; #endif #ifdef FLT_MAX const float _FloatMax = FLT_MAX; #else const float _FloatMax = 3.402823466e+38F; #endif #ifdef FLT_MIN const float _FloatMin = FLT_MIN; #else const float _FloatMin = 1.175494351e-38F; #endif #ifdef FLT_EPSILON const float _FloatRes = FLT_EPSILON; #else const float _FloatRes = 1.192092896e-07F; #endif #ifdef DBL_MAX const double _DoubleMax = DBL_MAX; #else const double _DoubleMax = 1.7976931348623158e+308; #endif #ifdef DBL_MIN const double _DoubleMin = DBL_MIN; #else const double _DoubleMin = 2.2250738585072014e-308; #endif #ifdef DBL_EPSILON const double _DoubleRes = DBL_EPSILON; #else const double _DoubleRes = 2.2204460492503131e-016; #endif const float _LargeFloat = 1.0e36f; const int _LargeInt = _IntMax - 777; const float _FloatTolerance = 10.0f*_FloatRes; const double _DoubleTolerance = 30.0*_DoubleRes; inline float Deg2Rad(float x) { return 3.1415927f/180.0f*x; } inline double Deg2Rad(double x) { return 3.1415926535897932384626433832795/180.0*x; } inline int Round2Int(float x) { return (int)floorf(0.5f+x); } inline int Round2Int(double x) { return (int)floor(0.5+x); } /* inline long Round2Long(float x) { return (long)floorf(0.5f+x); } inline long Round2Long(double x) { return (long)floor(0.5+x); } */ inline double Pow10(double x) { return pow(10.0,x); } inline float Pow10(float x) { return powf(10.0f,x); } inline double Log10(double x) { return log10(x); } inline float Log10(float x) { return log10f(x); } inline double PowN(double x, int n) { return pow(x,double(n)); } inline float PowN(float x, int n) { return powf(x,float(n)); } inline int Abs(int v) { return (v < 0) ? -v : v; } bool Intersect3Planes(double *p1, double *p2, double *p3, double *x); } // // macros to overwrite default bindings // #define deg2rad(x) iMath::Deg2Rad(x) #define round(x) iMath::Round2Int(x) #define pow10(x) iMath::Pow10(x) #define log10(x) iMath::Log10(x) #endif ifrit-3.4.2/core/imeasuringbox.cpp0000755000175700010010000001363612167404432015531 0ustar HomeNone/*========================================================================= Program: Ionization FRont Interactive Tool (IFRIT) Language: C++ Copyright (c) 2002-2012 Nick Gnedin All rights reserved. This file may be distributed and/or modified under the terms of the GNU General Public License version 2 as published by the Free Software Foundation and appearing in the file LICENSE.GPL included in the packaging of this file. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHORS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. =========================================================================*/ #include "imeasuringbox.h" #include "iactor.h" #include "ierror.h" #include "irendertool.h" #include "itextactor.h" #include "iviewmodule.h" #include #include #include #include #include #include #include #include #include // // Templates // #include "iarraytemplate.h" #include "igenericproptemplate.h" using namespace iParameter; namespace iMeasuringBox_Private { class KeyboardObserver : public vtkCommand { public: vtkTypeMacro(KeyboardObserver,vtkCommand); static KeyboardObserver* New(iMeasuringBox *parent = 0) { IERROR_ASSERT(parent); return new KeyboardObserver(parent); } virtual void Execute(vtkObject *caller, unsigned long eventId, void *callData) { vtkInteractorStyle *s = vtkInteractorStyle::SafeDownCast(caller); if(eventId==vtkCommand::CharEvent && mParent->GetVisibility()!=0) { // catch keycodes switch(mParent->GetViewModule()->GetInteractor()->GetKeyCode()) { case '-': case 'a': case 'A': { mParent->SetSize(mParent->GetSize()*0.95); break; } case '+': case 'z': case 'Z': { mParent->SetSize(mParent->GetSize()/0.95); break; } case '<': case 's': case 'S': { mParent->SetOpacity(mParent->GetOpacity()*0.8); break; } case '>': case 'x': case 'X': { mParent->SetOpacity(mParent->GetOpacity()/0.8); break; } } mParent->GetViewModule()->GetInteractor()->Render(); } if(s != 0) s->OnChar(); } private: KeyboardObserver(iMeasuringBox *parent) : mParent(parent) { } iMeasuringBox *mParent; }; }; using namespace iMeasuringBox_Private; iMeasuringBox* iMeasuringBox::New(iViewModule *vm) { IERROR_ASSERT(vm); return new iMeasuringBox(vm); } iMeasuringBox::iMeasuringBox(iViewModule *vm) : iGenericProp(true), mViewModule(vm) { mStarted = false; mSize = 0.25; mBaseScale = 1.0; mFactor1r = 0.78; mFactor1g = 0.89; mFactor1b = 0.82; mFactor2 = 0.0; vtkCubeSource *cube = vtkCubeSource::New(); IERROR_ASSERT(cube); cube->SetCenter(0.0,0.0,0.0); cube->SetXLength(2.0); cube->SetYLength(2.0); cube->SetZLength(2.0); mWorkerActor = iActor::New(); IERROR_ASSERT(mWorkerActor); this->AppendComponent(mWorkerActor); mBoxActor = mWorkerActor; mFrameActor = this; mFrameActor->SetInput(cube->GetOutput()); mFrameActor->GetProperty()->SetRepresentationToWireframe(); mFrameActor->GetProperty()->SetLineWidth(2); mBoxActor->SetInput(cube->GetOutput()); mBoxActor->GetProperty()->SetOpacity(0.5); mBoxActor->GetProperty()->SetAmbient(0.5); mBoxActor->GetProperty()->SetDiffuse(0.5); mBoxActor->GetProperty()->SetSpecular(0.7); mBoxActor->GetProperty()->SetSpecularPower(50); cube->Delete(); mText = iTextActor::New(this->GetViewModule()->GetRenderTool()); IERROR_ASSERT(mText); this->AppendComponent(mText); mText->SetBold(true); mText->SetPosition(0.5,0.03); mText->SetJustification(0); iColor black; this->SetColor(black); mObserver = KeyboardObserver::New(this); } iMeasuringBox::~iMeasuringBox() { mObserver->Delete(); mWorkerActor->Delete(); mText->Delete(); } void iMeasuringBox::AttachToInteractorStyle(vtkInteractorStyle *s) { if(s != 0) s->AddObserver(vtkCommand::CharEvent,mObserver); } void iMeasuringBox::SetSize(float s) { if(s > 0.0) { mSize = s; this->Modified(); } } void iMeasuringBox::SetColor(iColor &c) { mBoxActor->GetProperty()->SetColor(mFactor1r+mFactor2*c.ToVTK()[0],mFactor1g+mFactor2*c.ToVTK()[1],mFactor1b+mFactor2*c.ToVTK()[2]); mFrameActor->GetProperty()->SetColor(c.ToVTK()); this->Modified(); } void iMeasuringBox::SetOpacity(float o) { if(o > 0.0) { if(o > 1.0) o = 1.0; mBoxActor->GetProperty()->SetOpacity(o); this->Modified(); } } void iMeasuringBox::UpdateGeometry(vtkViewport* viewport) { vtkRenderer *ren = vtkRenderer::SafeDownCast(viewport); if(ren == 0) { this->Disable(); return; } vtkCamera *cam = ren->GetActiveCamera(); if(cam == 0) { this->Disable(); return; } if(!mStarted) { mStarted = true; mBaseScale = cam->GetParallelScale(); } if(this->GetViewModule()->GetRenderTool()->GetRenderingMagnification() == 1) { float s = mSize*cam->GetParallelScale()/mBaseScale; char t[256]; sprintf(t,"Box size: %6.2g",s); mText->SetText(t); this->SetScale(s); mBoxActor->SetAxisScale(s,s,s); mBoxActor->SetPosition(cam->GetFocalPoint()); mFrameActor->SetAxisScale(s,s,s); mFrameActor->SetPosition(cam->GetFocalPoint()); } } void iMeasuringBox::SetBaseScale(float s) { mStarted = true; mBaseScale = s; } ifrit-3.4.2/core/imeasuringbox.h0000755000175700010010000000465612167404414015200 0ustar HomeNone/*========================================================================= Program: Ionization FRont Interactive Tool (IFRIT) Language: C++ Copyright (c) 2002-2012 Nick Gnedin All rights reserved. This file may be distributed and/or modified under the terms of the GNU General Public License version 2 as published by the Free Software Foundation and appearing in the file LICENSE.GPL included in the packaging of this file. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHORS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. =========================================================================*/ #ifndef IMEASURINGBOX_H #define IMEASURINGBOX_H #include "igenericprop.h" #include "iactor.h" #include "ipointermacro.h" #include class iColor; class iTextActor; class iViewModule; class vtkCommand; class vtkCubeSource; class vtkInteractorStyle; class vtkPolyDataMapper; class iMeasuringBox : public iGenericProp { IPOINTER_AS_PART(ViewModule); public: vtkTypeMacro(iMeasuringBox,iActor); static iMeasuringBox* New(iViewModule *vm = 0); void AttachToInteractorStyle(vtkInteractorStyle *s); void SetSize(float s); void SetOpacity(float s); void SetColor(iColor &c); void SetBaseScale(float s); inline float GetOpacity(){ return mBoxActor->GetProperty()->GetOpacity(); } inline float GetSize(){ return mSize; } virtual double *GetBounds(){ return 0; } // Set to zero so that the text is always displayed protected: virtual ~iMeasuringBox(); virtual void UpdateGeometry(vtkViewport *vp); private: iMeasuringBox(iViewModule *vm); iTextActor *mText; iActor *mFrameActor, *mBoxActor, *mWorkerActor; vtkCommand *mObserver; bool mStarted; float mSize, mBaseScale; float mFactor1r, mFactor1g, mFactor1b, mFactor2; }; #endif // IMEASURINGBOX_H ifrit-3.4.2/core/imergedatafilter.cpp0000755000175700010010000001252112167404432016155 0ustar HomeNone/*========================================================================= Program: Ionization FRont Interactive Tool (IFRIT) Language: C++ Copyright (c) 2002-2012 Nick Gnedin All rights reserved. This file may be distributed and/or modified under the terms of the GNU General Public License version 2 as published by the Free Software Foundation and appearing in the file LICENSE.GPL included in the packaging of this file. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHORS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. =========================================================================*/ #include "imergedatafilter.h" #include "idata.h" #include "idatalimits.h" #include "idatareader.h" #include "ierror.h" #include "imath.h" #include "iviewmodule.h" #include #include #include // // Templates // #include "igenericfiltertemplate.h" iMergeDataFilter::iMergeDataFilter(iViewSubject *vo) : iGenericFilter(vo,1,false,false) { mDataRank = 0; mDataInput = 0; } void iMergeDataFilter::SetDataInput(int rank, vtkDataSet *input) { if(rank>=0 && rank<3 && input!=0) { mDataRank = rank; mDataInput = input; this->SetNumberOfInputPorts(2); this->SetInputConnection(1,input->GetProducerPort()); } } bool iMergeDataFilter::HasData(int rank) { if(rank>=0 && rank<3) { this->Update(); switch(rank) { case 0: return (this->GetOutput()->GetPointData()->GetScalars()!=0 && this->GetOutput()->GetPointData()->GetScalars()->GetNumberOfTuples()>0); case 1: return (this->GetOutput()->GetPointData()->GetVectors()!=0 && this->GetOutput()->GetPointData()->GetVectors()->GetNumberOfTuples()>0); case 2: return (this->GetOutput()->GetPointData()->GetTensors()!=0 && this->GetOutput()->GetPointData()->GetTensors()->GetNumberOfTuples()>0); } } return false; } void iMergeDataFilter::InitExecution() { vtkDataSet *input = this->GetInput(); vtkDataSet *output = this->GetOutput(); output->SetWholeExtent(input->GetWholeExtent()); // God only knows why these two are needed, output->SetUpdateExtent(input->GetUpdateExtent()); // but it took me a lot of debugging to find out they must be here if(mDataInput != 0) mDataInput->SetUpdateExtentToWholeExtent(); if(mSavedOutputVector != 0) { vtkInformation* outInfo = mSavedOutputVector->GetInformationObject(0); outInfo->Set(vtkStreamingDemandDrivenPipeline::UPDATE_NUMBER_OF_PIECES(),1); outInfo->Set(vtkStreamingDemandDrivenPipeline::UPDATE_PIECE_NUMBER(),0); } } void iMergeDataFilter::ProduceOutput() { vtkDataSet *input = this->GetInput(); vtkDataSet *output = this->GetOutput(); vtkPointData *pd = input->GetPointData(); if(pd == 0) { output->Initialize(); return; } output->ShallowCopy(input); switch(mDataRank) { case 0: { if(this->AreDataSetsCompatible(input,this->GetDataInput()) && this->GetDataInput()->GetPointData()->GetScalars()!=0) { output->GetPointData()->SetScalars(this->GetDataInput()->GetPointData()->GetScalars()); } break; } case 1: { if(this->AreDataSetsCompatible(input,this->GetDataInput()) && this->GetDataInput()->GetPointData()->GetVectors()!=0) { output->GetPointData()->SetVectors(this->GetDataInput()->GetPointData()->GetVectors()); } break; } case 2: { if(this->AreDataSetsCompatible(input,this->GetDataInput()) && this->GetDataInput()->GetPointData()->GetTensors()!=0) { output->GetPointData()->SetTensors(this->GetDataInput()->GetPointData()->GetTensors()); } break; } } } bool iMergeDataFilter::AreDataSetsCompatible(vtkDataSet *ds1, vtkDataSet *ds2) const { int i, numArrays; if(ds1==0 || ds2==0) return false; if(ds1->GetNumberOfPoints() != ds2->GetNumberOfPoints()) return false; vtkIdType numTuples, numPts = ds1->GetNumberOfPoints(); numArrays = ds1->GetPointData()->GetNumberOfArrays(); for(i=0; iGetPointData()->GetArray(i)->GetNumberOfTuples(); if(numTuples>0 && numTuples!=numPts) return false; } numArrays = ds2->GetPointData()->GetNumberOfArrays(); for(i=0; iGetPointData()->GetArray(i)->GetNumberOfTuples(); if(numTuples>0 && numTuples!=numPts) return false; } // // If ImageData, check that the dimensions are identical // vtkImageData *id1 = vtkImageData::SafeDownCast(ds1); vtkImageData *id2 = vtkImageData::SafeDownCast(ds2); if((id1==0 && id2!=0) || (id1!=0 && id2==0)) return false; if(id1!=0 && id2!=0) { int dim1[3], dim2[3]; id1->GetDimensions(dim1); id2->GetDimensions(dim2); return (dim1[0]==dim2[0] && dim1[1]==dim2[1] && dim1[2]==dim2[2]); } // // Other data types can be added here // return true; } ifrit-3.4.2/core/imergedatafilter.h0000644000175700010010000000357112167404414015624 0ustar HomeNone/*========================================================================= Program: Ionization FRont Interactive Tool (IFRIT) Language: C++ Copyright (c) 2002-2012 Nick Gnedin All rights reserved. This file may be distributed and/or modified under the terms of the GNU General Public License version 2 as published by the Free Software Foundation and appearing in the file LICENSE.GPL included in the packaging of this file. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHORS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. =========================================================================*/ #ifndef IMERGEDATAFILTER_H #define IMERGEDATAFILTER_H #include "igenericfilter.h" #include class iMergeDataFilter : public iGenericFilter { IGENERICFILTER_DECLARE(iMergeDataFilter,vtkDataSetToDataSetFilter); public: inline vtkDataSet* GetDataInput(){ return mDataInput; } void SetDataInput(int rank, vtkDataSet *input); bool HasData(int rank); protected: virtual void InitExecution(); virtual void ProduceOutput(); private: bool AreDataSetsCompatible(vtkDataSet *ds1, vtkDataSet *ds2) const; int mDataRank; vtkDataSet *mDataInput; }; #endif ifrit-3.4.2/core/imultitypedataconsumer.cpp0000755000175700010010000000456012167404432017464 0ustar HomeNone/*========================================================================= Program: Ionization FRont Interactive Tool (IFRIT) Language: C++ Copyright (c) 2002-2012 Nick Gnedin All rights reserved. This file may be distributed and/or modified under the terms of the GNU General Public License version 2 as published by the Free Software Foundation and appearing in the file LICENSE.GPL included in the packaging of this file. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHORS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. =========================================================================*/ #include "imultitypedataconsumer.h" #include "idata.h" #include "idatareader.h" #include "ierror.h" #include "iviewmodule.h" // // Templates // #include "iarraytemplate.h" iMultiTypeDataConsumer::iMultiTypeDataConsumer(iViewModule *vm, const iDataInfo &info) : iDataConsumer(vm,iDataType::Null()) { *mPrimaryDataInfo = info; mActiveDataTypeIndex = 0; } const iDataType& iMultiTypeDataConsumer::GetDataType() const { return mPrimaryDataInfo->Type(mActiveDataTypeIndex); } void iMultiTypeDataConsumer::SetActiveDataType(const iDataType &type) { this->SetActiveDataTypeIndex(mPrimaryDataInfo->Index(type)); } bool iMultiTypeDataConsumer::IsActiveDataType(const iDataType &type) const { return type == mPrimaryDataInfo->Type(mActiveDataTypeIndex); } void iMultiTypeDataConsumer::SetActiveDataTypeIndex(int v) { if(v!=mActiveDataTypeIndex && v>=0 && vCount()) { int prev = mActiveDataTypeIndex; mActiveDataTypeIndex = v; this->UpdateDataType(prev); this->SyncWithData(this->Request(this->GetDataType())); } } int iMultiTypeDataConsumer::GetNumberOfTypes() const { return mPrimaryDataInfo->Count(); } ifrit-3.4.2/core/imultitypedataconsumer.h0000644000175700010010000000364012167404415017125 0ustar HomeNone/*========================================================================= Program: Ionization FRont Interactive Tool (IFRIT) Language: C++ Copyright (c) 2002-2012 Nick Gnedin All rights reserved. This file may be distributed and/or modified under the terms of the GNU General Public License version 2 as published by the Free Software Foundation and appearing in the file LICENSE.GPL included in the packaging of this file. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHORS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. =========================================================================*/ // // Multi-type data consumer // #ifndef IMULTITYPEDATACONSUMER_H #define IMULTITYPEDATACONSUMER_H #include "idataconsumer.h" class iMultiTypeDataConsumer : public iDataConsumer { public: virtual const iDataType& GetDataType() const; void SetActiveDataType(const iDataType &type); bool IsActiveDataType(const iDataType &type) const; void SetActiveDataTypeIndex(int v); inline int GetActiveDataTypeIndex() const { return mActiveDataTypeIndex; } int GetNumberOfTypes() const; protected: iMultiTypeDataConsumer(iViewModule *vm, const iDataInfo &info); virtual void UpdateDataType(int prev) = 0; int mActiveDataTypeIndex; }; #endif // IMULTITYPEDATACONSUMER_H ifrit-3.4.2/core/iobject.cpp0000755000175700010010000007471512167404432014301 0ustar HomeNone/*========================================================================= Program: Ionization FRont Interactive Tool (IFRIT) Language: C++ Copyright (c) 2002-2012 Nick Gnedin All rights reserved. This file may be distributed and/or modified under the terms of the GNU General Public License version 2 as published by the Free Software Foundation and appearing in the file LICENSE.GPL included in the packaging of this file. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHORS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. =========================================================================*/ #include "iobject.h" #include "ierror.h" #include "ierrorstatus.h" #include "iobjecthelp.h" #include "ipiecewisefunction.h" #include "irangecollection.h" // // Templates // #include "iarraytemplate.h" #define I_CHECK_DUPLICATES // // ***************************************************************** // // iObjectType implementation // // ***************************************************************** // iObjectType::iObjectType(ClassId c, const char *fullname, const char *shortname) { mClass = c; mFullName = fullname; mShortName = shortname; mHelp = new iObjectTypeHelp(this); } iObjectType::iObjectType() { mClass = _Any; mHelp = 0; } iObjectType::~iObjectType() { if(mHelp != 0) delete mHelp; } bool iObjectType::IsHidden() const { // // If the type short name start with -, it is hidden. // return (mShortName[0] == '-'); } bool iObjectType::IsMatch(const iString &p) const { return p==mFullName || p==mShortName; } bool iObjectType::IsMatch(const iObjectType &p) const { return p.mFullName == mFullName; } const iString& iObjectType::FullName() const { return mFullName; } const iString& iObjectType::ShortName() const { return mShortName; } bool iObjectType::operator==(const iObjectType &s) const { return (mFullName == s.mFullName); } bool iObjectType::operator<(const iObjectType &s) const { return mClass() const { return mPointer; } const iObjectType* GetPointer() const { return mPointer; } void operator=(const iObjectTypePointer &p) { mPointer = p.mPointer; } bool operator==(const iObjectTypePointer &p) const { return (mPointer->FullName() == p.mPointer->FullName()); } bool operator<(const iObjectTypePointer &p) const { return (mPointer->FullName() < p.mPointer->FullName()); } private: const iObjectType *mPointer; }; int iObjectTypeRegistry::mTraversalLocation = 0; iObjectType::ClassId iObjectTypeRegistry::mTraversalClass = iObjectType::_Any; iArray& iObjectTypeRegistry::List() { static iOrderedArray list(30); return list; } const iObjectType* iObjectTypeRegistry::CreateType(iObjectType::ClassId c, const char *fp, const char *sp) { iObjectType *tmp = new iObjectType(c,fp,sp); IERROR_ASSERT(tmp); #if defined(I_DEBUG) && defined (I_CHECK_DUPLICATES) const iObjectType *k; if((k=iObjectTypeRegistry::FindType(tmp->mFullName,true))!=0 || (k=iObjectTypeRegistry::FindType(tmp->mShortName,true))!=0) { IERROR_LOW("Duplicate type."); } #endif // // Register the type // List().Add(tmp); return tmp; } const iObjectType* iObjectTypeRegistry::FindType(const iString &str, bool hidden) { int i, n; const iObjectType *p; iArray &list = List(); n = list.Size(); for(i=0; imFullName || str==p->mShortName) { // // Is it hidden? // if(hidden || !p->IsHidden()) return p; else return 0; } } return 0; } void iObjectTypeRegistry::InitTraversal(iObjectType::ClassId c) { mTraversalLocation = 0; mTraversalClass = c; } const iObjectType* iObjectTypeRegistry::GetNextType(bool hidden) { iArray &list = List(); int n = list.Size(); if(mTraversalClass == iObjectType::_Any) { while(!hidden && mTraversalLocationIsHidden()) mTraversalLocation++; if(mTraversalLocation < n) { return list[mTraversalLocation++].GetPointer(); } } else { while(mTraversalLocation < n) { if(list[mTraversalLocation]->Class()==mTraversalClass && (hidden || !list[mTraversalLocation]->IsHidden())) return list[mTraversalLocation++].GetPointer(); mTraversalLocation++; } } return 0; } // // ***************************************************************** // // iObjectKey implementation // // ***************************************************************** // const char iObjectKey::mLastLetterOfDelimiter = iObjectKey::Delimiter()[iObjectKey::Delimiter().Length()-1]; const char iObjectKey::mLastLetterOfPrefixSeparator = iObjectKey::PrefixSeparator()[iObjectKey::PrefixSeparator().Length()-1]; bool iObjectKey::mUseShortKeys = false; iObjectKey::iObjectKey(const iObjectType *type, const char *fk, const char *sk, Arg a, int d, const iObjectType* parent) { this->Define(type,fk,sk,a,d,parent); } void iObjectKey::Define(const iObjectType *type, const char *fk, const char *sk, Arg a, int d, const iObjectType* parent) { mArg = a; mDim = d; // // Ignore the prefix for proper downcasting // if(type != 0) { mFullKey = fk; mSearchableFullKey = fk + FieldSeparator(); mSearchableIndexedFullKey = fk + LeftBracket(); mPrefixedFullKey = type->FullName() + PrefixSeparator() + fk; mShortKey = sk; mSearchableShortKey = sk + FieldSeparator(); mSearchableIndexedShortKey = sk + LeftBracket(); mPrefixedShortKey = type->ShortName() + PrefixSeparator() + sk; } mType = type; mParent = parent; mHelp = new iObjectKeyHelp(this); } iObjectKey::~iObjectKey() { if(mHelp != 0) delete mHelp; } bool iObjectKey::IsHidden() const { // // If the key short name start with -, it is hidden. // return mType->IsHidden() || (mShortKey[0] == '-'); } const iString& iObjectKey::PrefixSeparator() { static const iString s(":"); return s; } const iString& iObjectKey::FieldSeparator() { static const iString s("/"); return s; } const iString& iObjectKey::SubSeparator() { static const iString s(";"); return s; } const iString& iObjectKey::SubSubSeparator() { static const iString s(","); return s; } const iString& iObjectKey::Delimiter() { static const iString s(" "); return s; } const iString& iObjectKey::LeftBracket() { static const iString s("["); return s; } const iString& iObjectKey::RightBracket() { static const iString s("]"); return s; } const iString& iObjectKey::SpecialSeparator() { static const iString s("&&"); return s; } const iObjectType& iObjectKey::Type() const { IERROR_ASSERT(mType); return *mType; } const iObjectKey::Arg iObjectKey::Argument() const { return mArg; } const int iObjectKey::Dimension() const { return mDim; } const iString iObjectKey::PrefixedFullName(int index) const { if(index < 0) return mPrefixedFullKey; else return mPrefixedFullKey + LeftBracket() + iString::FromNumber(index+1) + RightBracket(); } const iString iObjectKey::PrefixedShortName(int index) const { if(index < 0) return mPrefixedShortKey; else return mPrefixedShortKey + LeftBracket() + iString::FromNumber(index+1) + RightBracket(); } const iString iObjectKey::UnprefixedFullName(int index) const { if(index < 0) return mFullKey; else return mFullKey + LeftBracket() + iString::FromNumber(index+1) + RightBracket(); } const iString iObjectKey::UnprefixedShortName(int index) const { if(index < 0) return mShortKey; else return mShortKey + LeftBracket() + iString::FromNumber(index+1) + RightBracket(); } const iString iObjectKey::PrefixedKey(int index) const { if(mUseShortKeys) return this->PrefixedShortName(index); else return this->PrefixedFullName(index); } const iString iObjectKey::UnprefixedKey(int index) const { if(mUseShortKeys) return this->UnprefixedShortName(index); else return this->UnprefixedFullName(index); } const iString iObjectKey::HelpEntryKey() const { if(mType != 0) { if(mParent == 0) return mType->ShortName() + "." + mShortKey; else return mParent->ShortName() + "." + mShortKey; } else return ""; } const iString iObjectKey::PackingKey(int index, bool prefixed) const { if(prefixed) return this->PrefixedKey(index); else return this->UnprefixedKey(index); } const iString iObjectKey::RetypedKey(const iObjectType &type, int index) const { if(mUseShortKeys) { return type.ShortName() + iObjectKey::PrefixSeparator() + this->UnprefixedShortName(index); } else { return type.FullName() + iObjectKey::PrefixSeparator() + this->UnprefixedFullName(index); } } bool iObjectKey::operator==(const iObjectKey &s) const { return (mPrefixedFullKey == s.mPrefixedFullKey); } bool iObjectKey::operator<(const iObjectKey &s) const { return (mPrefixedFullKey < s.mPrefixedFullKey); } int iObjectKey::FindFullMatch(const iString &str, const iString &pat) const { int ind = str.Find(pat); // // We have to be careful with keys - they may produce a match on just a piece // of another key. So, check that this is the complete key and not a part of // another one. I.e., the letter just before the key must be a last letter of either // the delimiter or the prefix separator. // while(ind>0 && str[ind-1]!=mLastLetterOfDelimiter && str[ind-1]!=mLastLetterOfPrefixSeparator) ind = str.Find(pat,ind+1); return ind; } int iObjectKey::FindInString(const iString &str, int &index) const { // // Search for the un-indexed key first // int ind = this->FindFullMatch(str,mSearchableFullKey); if(ind == -1) { ind = this->FindFullMatch(str,mSearchableShortKey); } if(ind >= 0) // key found { index = -1; return ind; } // // repeat for the indexed key // ind = this->FindFullMatch(str,mSearchableIndexedFullKey); if(ind == -1) ind = this->FindFullMatch(str,mSearchableIndexedShortKey); if(ind == -1) //not found { index = -1; return ind; } // // Get the index // bool ok; iString s = str.Part(ind); int i1 = s.Find(LeftBracket()); int i2 = s.Find(RightBracket()); if(i1+2 > i2) // wrong order { index = -1; return -1; } index = s.Part(i1+1,i2-i1-1).ToInt(ok) - 1; if(!ok || index<0) // syntax error { index = -1; return -1; } return ind; } // // iObjectKeyRegistry implementation // class iObjectKeyPointer { public: iObjectKeyPointer() { mPointer = 0; } iObjectKeyPointer(const iObjectKey *p) { mPointer = p; } const iObjectKey* operator->() const { return mPointer; } const iObjectKey* GetPointer() const { return mPointer; } void operator=(const iObjectKeyPointer &p) { mPointer = p.mPointer; } bool operator==(const iObjectKeyPointer &p) const { return (mPointer->PrefixedFullName() == p.mPointer->PrefixedFullName()); } bool operator<(const iObjectKeyPointer &p) const { return (mPointer->PrefixedFullName() < p.mPointer->PrefixedFullName()); } private: const iObjectKey *mPointer; }; int iObjectKeyRegistry::mTraversalLocation = 0; bool iObjectKeyRegistry::mTraversalWithInherited = true; const iObjectType* iObjectKeyRegistry::mTraversalType = 0; iArray& iObjectKeyRegistry::List() { static iOrderedArray list(100); return list; } iArray& iObjectKeyRegistry::TempKeys() { static iArray list; return list; } const iObjectKey* iObjectKeyRegistry::CreateKey(const iObjectType &type, const char *fk, const char *sk, iObjectKey::Arg a, int d, const iObjectType* parent, const iObjectKey* helpOwner) { iObjectKey *tmp = new iObjectKey(&type,fk,sk,a,d,parent); IERROR_ASSERT(tmp); #if defined(I_DEBUG) && defined (I_CHECK_DUPLICATES) const iObjectKey *k; if((k=iObjectKeyRegistry::FindKey(tmp->mPrefixedFullKey,true))!=0 || (k=iObjectKeyRegistry::FindKey(tmp->mPrefixedShortKey,true))!=0) { IERROR_LOW("Duplicate key."); } #endif // // Assign help // if(helpOwner != 0) tmp->mHelp = new iObjectKeyHelp(helpOwner); // // Register the key // List().Add(tmp); return tmp; } const iObjectKey& iObjectKeyRegistry::GetTempKey(const iObjectType &type, const iString &fk, int id) { iArray &tmp = TempKeys(); // // If any key is requested (id < 0), return the first unused one // if(id < 0) { for(id=0; idmFullKey.IsEmpty()) break; } } // // If all the keys are in use, create new ones // while(id >= tmp.Size()) { tmp.Add(new iObjectKey(&type,fk.ToCharPointer(),"-tmp",iObjectKey::_Any,0)); } // // Change the existing one to a proper value, unless it is the same one // if(!(tmp[id]->Type()==type) || tmp[id]->mFullKey!=fk) { tmp[id]->Define(&type,fk.ToCharPointer(),"-tmp",iObjectKey::_Any,0); } return *tmp[id]; } void iObjectKeyRegistry::ReleaseTempKey(const iObjectKey &key) { int i; iArray &tmp = TempKeys(); // // Find the key and remove its full name // for(i=0; imFullKey.Clear(); break; } } } const iObjectKey* iObjectKeyRegistry::FindKey(const iString &str0, bool hidden) { int i, n; const iObjectKey *p; iArray &list = List(); iString str = str0.Section(iObjectKey::LeftBracket(),0,0); n = list.Size(); for(i=0; imPrefixedFullKey || str==p->mPrefixedShortKey) { // // Is it hidden? // if(hidden || !p->IsHidden()) return p; else return 0; } } return 0; } void iObjectKeyRegistry::InitTraversal(const iObjectType *type, bool inherited) { mTraversalLocation = 0; mTraversalWithInherited = inherited; mTraversalType = type; } const iObjectKey* iObjectKeyRegistry::GetNextKey(bool hidden) { iArray &list = List(); int n = list.Size(); if(mTraversalType == 0) { while(!hidden && mTraversalLocationIsHidden()) mTraversalLocation++; if(mTraversalLocation < n) { return list[mTraversalLocation++].GetPointer(); } } else { const iObjectType &type = *mTraversalType; while(mTraversalLocation < n) { if(list[mTraversalLocation]->Type()==type && (hidden || !list[mTraversalLocation]->IsHidden()) && (mTraversalWithInherited || !list[mTraversalLocation]->IsInherited())) return list[mTraversalLocation++].GetPointer(); mTraversalLocation++; } } return 0; } // // ***************************************************************** // // iObject implementation // // ***************************************************************** // const iString iObject::mSlash = "@@"; int iObject::mMissingKeysStack = 0; void iObject::ReportMissingKeys(bool s) { if(s) mMissingKeysStack--; else mMissingKeysStack++; if(mMissingKeysStack < 0) mMissingKeysStack = 0; } void iObject::ReportAMissingKey(const iObjectKey &key) { if(mMissingKeysStack == 0) IERROR_LOW((iString("Missing key: ")+key.PrefixedFullName()).ToCharPointer()); } iObject::iObject(const iString &name) : mErrorStatus(name) { mUnPackedSomething = false; mCacheInvalid = true; } iObject::~iObject() { } void iObject::ClearCache() { mCacheInvalid = true; } void iObject::PackCompleteState(iString &s) const { this->PackState(s); } void iObject::UnPackCompleteState(const iString &s) { this->UnPackState(s); } void iObject::PackState(iString &s) const { if(mCacheInvalid || mCache.IsEmpty()) { s.Init(10000); this->PackStateBody(s); mCache = s; mCacheInvalid = false; } else { s = mCache; } } void iObject::UnPackState(const iString &s) { mUnPackedSomething = false; this->UnPackStateBody(s); } void iObject::CopyState(const iObject *p) { iString s; // // Read the parameters // p->PackCompleteState(s); // // Set the parameters of the new instance // this->UnPackCompleteState(s); } bool iObjectKey::IsArgumentCompatible(Arg a) const { // offset int and int have compatible types return mArg==_Any || a==mArg || (a==_OffsetInt && mArg==_Int) || (a==_Int && mArg==_OffsetInt); } bool iObjectKey::IndexHelper(Arg a, int n, int index, int &imin, int &imax) const { if(!this->IsArgumentCompatible(a)) { // incompatible arguments, exit without doing anything. IERROR_LOW("Incompatible key argument."); return true; } if(n<0 || (mDim!=0 && ((index<0 && n!=mDim) || (index>=0 && n!=1 && index>=mDim)))) // dim = 0 disables bound checking { // incorrect key index, exit without doing anything. IERROR_LOW("Incorrect key index."); return true; } if(index < 0) { if(n == 0) { IERROR_LOW("Incorrect key index."); return true; } imin = 0; imax = n; } else { if(mDim == 1) { IERROR_LOW("Incorrect key index."); return true; } imin = index; imax = index + 1; } return false; } // // Packing helpers // void iObject::PackValue(iString &s, const iObjectKey &key, const int* val, int num, int index, bool prefixed) const { int i, i1, i2, offset = 0; if(key.IndexHelper(iObjectKey::_Int,num,index,i1,i2)) return; s += key.PackingKey(index,prefixed); if(key.Argument() == iObjectKey::_OffsetInt) offset = 1; for(i=i1; i=0) { int i, i1, i2, offset = 0;; ok = true; iString tmp = s.Part(ind); if(key.IndexHelper(iObjectKey::_Int,num,index,i1,i2)) { return false; } if(key.Argument() == iObjectKey::_OffsetInt) offset = 1; int* v = new int[num+1]; IERROR_ASSERT(v); // num+1 is because arrays go from 1 to num for(i=i1; ok && i=0) { int i, i1, i2; ok = true; iString tmp = s.Part(ind); if(key.IndexHelper(iObjectKey::_Bool,num,index,i1,i2)) { return false; } bool* v = new bool[num+1]; IERROR_ASSERT(v); for(i=i1; ok && i=0) { int i, i1, i2; ok = true; iString tmp = s.Part(ind); if(key.IndexHelper(iObjectKey::_Float,num,index,i1,i2)) { return false; } float* v = new float[num+1]; IERROR_ASSERT(v); for(i=i1; ok && i=0) { int i, i1, i2; ok = true; iString tmp = s.Part(ind); if(key.IndexHelper(iObjectKey::_Double,num,index,i1,i2)) { return false; } double* v = new double[num+1]; IERROR_ASSERT(v); for(i=i1; ok && i=0) { int i, i1, i2; ok = true; iString tmp = s.Part(ind); if(key.IndexHelper(iObjectKey::_Color,num,index,i1,i2)) { return false; } iColor* v = new iColor[num+1]; IERROR_ASSERT(v); for(i=i1; ok && i=0) { int i, i1, i2; ok = true; iString tmp = s.Part(ind); if(key.IndexHelper(iObjectKey::_String,num,index,i1,i2)) { return false; } for(i=i1; ok && iN(); s += key.FieldSeparator() + iString::FromNumber(f[i]->Min()) + key.SubSubSeparator() + iString::FromNumber(f[i]->Max()); s += key.SubSeparator() + iString::FromNumber(f[i]->X(0)) + key.SubSubSeparator() + iString::FromNumber(f[i]->Y(0)); s += key.SubSeparator() + iString::FromNumber(f[i]->X(n-1)) + key.SubSubSeparator() + iString::FromNumber(f[i]->Y(n-1)); for(j=1; jX(j)) + key.SubSubSeparator() + iString::FromNumber(f[i]->Y(j)); } } s += key.FieldSeparator() + key.Delimiter(); } bool iObject::UnPackValuePiecewiseFunction(const iString &s, const iObjectKey &key, iPiecewiseFunction **f, int num) { bool ok; int index, ind = key.FindInString(s,index); if(ind >=0) { int i, j, i1, i2; ok = true; iString tmp = s.Part(ind); if(key.IndexHelper(iObjectKey::_Any,num,index,i1,i2)) { return false; } iPiecewiseFunction* v = iPiecewiseFunction::New(); IERROR_ASSERT(v); iString tmp1, tmp2; float x1, x2; bool ok1; for(i=i1; ok && iSetMinMax(x1,x2); j = 1; while(ok && !(tmp2=tmp1.Section(key.SubSeparator(),j,j)).IsEmpty()) { x1 = tmp2.Section(key.SubSubSeparator(),0,0).ToFloat(ok1); ok = ok && ok1; x2 = tmp2.Section(key.SubSubSeparator(),1,1).ToFloat(ok1); ok = ok && ok1; if(ok) { if(j < 3) v->MovePoint(j-1,x1,x2); else v->AddPoint(x1,x2); } j++; } if(ok) { if(f[i] != 0) f[i]->Copy(v); } else IERROR_LOW("Invalid key value."); } v->Delete(); } else ok = false; #ifdef I_CHECK1 if(!ok) ReportAMissingKey(key); #endif if(ok) mUnPackedSomething = true; return ok; } void iObject::PackValueRangeCollection(iString &s, const iObjectKey &key, const iRangeCollection * const *f, int num, int index, bool prefixed) const { int i, j, n, i1, i2; if(f == 0) return; if(key.IndexHelper(iObjectKey::_Any,num,index,i1,i2)) return; s += key.PackingKey(index,prefixed); for(i=i1; f[i]!=0 && iGetN(); s += key.FieldSeparator() + iString::FromNumber(f[i]->GetGlobalMin()) + key.SubSubSeparator() + iString::FromNumber(f[i]->GetGlobalMax()); for(j=0; jGetMin(j)) + key.SubSubSeparator() + iString::FromNumber(f[i]->GetMax(j)); } } s += key.FieldSeparator() + key.Delimiter(); } bool iObject::UnPackValueRangeCollection(const iString &s, const iObjectKey &key, iRangeCollection **f, int num) { bool ok; int index, ind = key.FindInString(s,index); if(ind >=0) { int i, j, i1, i2; ok = true; iString tmp = s.Part(ind); if(key.IndexHelper(iObjectKey::_Any,num,index,i1,i2)) { return false; } iRangeCollection* v = new iRangeCollection[num+1]; IERROR_ASSERT(v); iString tmp1, tmp2; float x1, x2; bool ok1; for(i=i1; ok && i 2) v[i].AddRange(x1,x2); else v[i].SetRange(0,x1,x2); } } } if(ok) { for(i=i1; f[i]!=0 && iCopy(v+i); } else IERROR_LOW("Invalid key value."); delete [] v; } else ok = false; #ifdef I_CHECK1 if(!ok) ReportAMissingKey(key); #endif if(ok) mUnPackedSomething = true; return ok; } void iObject::PackValuePosition(iString &s, const iObjectKey &key, const iPosition &val, int index, bool prefixed) const { // // Save the box position as a double array // this->PackValue(s,key,val.BoxPosition(),3,index,prefixed); // // Now save the OpenGL position // const iObjectKey &tmp = iObjectKeyRegistry::GetTempKey(key.Type(),key.UnprefixedFullName()+"GL"); this->PackValue(s,tmp,val,3,index,prefixed); iObjectKeyRegistry::ReleaseTempKey(tmp); } bool iObject::UnPackValuePosition(const iString &s, const iObjectKey &key, iPosition &val) { int i; double x[3]; // // Read the box position as a double array // for(i=0; i<3; i++) x[i] = val.BoxPosition(i); bool ret1 = this->UnPackValue(s,key,x,3); if(ret1) val.SetBoxPosition(x); // // Now read the OpenGL position: if it is present, it will overwrite the box value // const iObjectKey &tmp = iObjectKeyRegistry::GetTempKey(key.Type(),key.UnprefixedFullName()+"GL"); for(i=0; i<3; i++) x[i] = val[i]; bool ret2 = this->UnPackValue(s,tmp,x,3); if(ret2) val = x; iObjectKeyRegistry::ReleaseTempKey(tmp); return ret1 || ret2; } void iObject::PackValueDistance(iString &s, const iObjectKey &key, const iDistance &val, int index, bool prefixed) const { // // Save the box position as a double array // this->PackValue(s,key,val.BoxDistance(),index,prefixed); // // Now save the OpenGL position // const iObjectKey &tmp = iObjectKeyRegistry::GetTempKey(key.Type(),key.UnprefixedFullName()+"GL"); this->PackValue(s,tmp,val,index,prefixed); iObjectKeyRegistry::ReleaseTempKey(tmp); } bool iObject::UnPackValueDistance(const iString &s, const iObjectKey &key, iDistance &val) { double d; // // Read the box position as a double array // bool ret1 = this->UnPackValue(s,key,d); if(ret1) val.SetBoxDistance(d); // // Now read the OpenGL position: if it is present, it will overwrite the box value // const iObjectKey &tmp = iObjectKeyRegistry::GetTempKey(key.Type(),key.UnprefixedFullName()+"GL"); bool ret2 = this->UnPackValue(s,tmp,d); if(ret2) val = d; iObjectKeyRegistry::ReleaseTempKey(tmp); return ret1 || ret2; } ifrit-3.4.2/core/iobject.h0000755000175700010010000004152512167404415013740 0ustar HomeNone/*========================================================================= Program: Ionization FRont Interactive Tool (IFRIT) Language: C++ Copyright (c) 2002-2012 Nick Gnedin All rights reserved. This file may be distributed and/or modified under the terms of the GNU General Public License version 2 as published by the Free Software Foundation and appearing in the file LICENSE.GPL included in the packaging of this file. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHORS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. =========================================================================*/ // // A small set of common functionality for all IFrIT viewization objects // #ifndef IOBJECT_H #define IOBJECT_H #include #include "icolor.h" #include "ipointermacro.h" #include "iposition.h" #include "istring.h" #include template class iArray; class iErrorStatus; class iObjectKeyHelp; class iObjectKeyPointer; class iObjectTypeHelp; class iObjectTypePointer; class iPiecewiseFunction; class iRangeCollection; class iObjectType { friend class iObject; friend class iObjectTypeRegistry; public: enum ClassId { _Data, _View, _Module, _Helper, _Any }; const iString& FullName() const; const iString& ShortName() const; inline ClassId Class() const { return mClass; } bool IsMatch(const iString &p) const; bool IsMatch(const iObjectType &p) const; inline const iObjectTypeHelp* GetHelp() const { return mHelp; } bool operator==(const iObjectType &s) const; bool operator<(const iObjectType &s) const; bool IsHidden() const; private: iObjectType(); iObjectType(ClassId c, const char *fullname, const char *shortname); ~iObjectType(); ClassId mClass; iString mFullName, mShortName; iObjectTypeHelp* mHelp; }; class iObjectTypeRegistry { public: static const iObjectType* CreateType(iObjectType::ClassId c, const char *fp, const char *sp); static const iObjectType* FindType(const iString &str, bool hidden = false); static void InitTraversal(iObjectType::ClassId c = iObjectType::_Any); static const iObjectType* GetNextType(bool hidden = false); private: // // List cannot be a static variable because it must be created when it is first time // requested. // static iArray& List(); static int mTraversalLocation; static iObjectType::ClassId mTraversalClass; }; class iObjectKey { friend class iObject; friend class iObjectKeyRegistry; friend class iShell; public: enum Arg { _Any, _OffsetInt, _Int, _Bool, _Float, _Double, _Color, _String }; const iString PrefixedFullName(int index = -1) const; const iString PrefixedShortName(int index = -1) const; const iString UnprefixedFullName(int index = -1) const; const iString UnprefixedShortName(int index = -1) const; const iString PrefixedKey(int index = -1) const; const iString UnprefixedKey(int index = -1) const; const iString HelpEntryKey() const; const iString PackingKey(int index = -1, bool prefixed = false) const; const iString RetypedKey(const iObjectType &type, int index = -1) const; const iObjectType& Type() const; const Arg Argument() const; const int Dimension() const; bool IsArgumentCompatible(Arg a) const; bool IndexHelper(Arg a, int n, int index, int &imin, int &imax) const; int FindInString(const iString &str, int &index) const; inline bool IsIndexed() const { return (mDim > 1); } inline const iObjectKeyHelp* GetHelp() const { return mHelp; } static const iString& PrefixSeparator(); static const iString& FieldSeparator(); static const iString& SubSeparator(); static const iString& SubSubSeparator(); static const iString& Delimiter(); static const iString& LeftBracket(); static const iString& RightBracket(); static const iString& SpecialSeparator(); bool operator==(const iObjectKey &s) const; bool operator<(const iObjectKey &s) const; bool IsHidden() const; inline bool IsInherited() const { return (mParent != 0); } private: // // The constructor only calls Define function // iObjectKey(const iObjectType *type, const char *fk, const char *sk, Arg a, int d, const iObjectType* parent = 0); ~iObjectKey(); // // Allow the key to be redefined by the registry - this is a true constructor // void Define(const iObjectType *type, const char *fk, const char *sk, Arg a, int d, const iObjectType* parent = 0); int FindFullMatch(const iString &str, const iString &pat) const; Arg mArg; int mDim; const iObjectType *mType, *mParent; iString mShortKey, mFullKey; // formal keys iString mSearchableShortKey, mSearchableFullKey; // searchable keys iString mSearchableIndexedShortKey, mSearchableIndexedFullKey; // searchable keys with index iString mPrefixedShortKey, mPrefixedFullKey; // prefixed keys iObjectKeyHelp* mHelp; static const char mLastLetterOfDelimiter, mLastLetterOfPrefixSeparator; static bool mUseShortKeys; }; class iObjectKeyRegistry { public: static const iObjectKey* CreateKey(const iObjectType &type, const char *fk, const char *sk, iObjectKey::Arg a, int d, const iObjectType* parent = 0, const iObjectKey* helpOwner = 0); static const iObjectKey& GetTempKey(const iObjectType &type, const iString &fk, int id = -1); static void ReleaseTempKey(const iObjectKey &key); static const iObjectKey* FindKey(const iString &str, bool hidden = false); static void InitTraversal(const iObjectType *type = 0, bool inherited = true); static const iObjectKey* GetNextKey(bool hidden = false); private: // // List cannot be a static variable because it must be created when it is first time // requested. // static iArray& List(); static iArray& TempKeys(); static int mTraversalLocation; static bool mTraversalWithInherited; static const iObjectType *mTraversalType; }; #define IOBJECT_DECLARE_PACKUNPACK(_type1_,_type2_) \ void PackValue(iString &s, const iObjectKey &key, const _type1_* val, int num, int index = -1, bool prefixed = false) const; \ inline void PackValue(iString &s, const iObjectKey &key, _type2_ val, int index = -1, bool prefixed = false) const { if(index >= 0) PackValue(s,key,&val-index,1,index,prefixed); else PackValue(s,key,&val,1,index,prefixed); } \ bool UnPackValue(const iString &s, const iObjectKey &key, _type1_* val, int num); \ inline bool UnPackValue(const iString &s, const iObjectKey &key, _type1_ &val){ return !key.IsIndexed() && UnPackValue(s,key,&val,1); } class iObject : public vtkObjectBase { IPOINTER_AS_USER(ErrorStatus); public: vtkTypeMacro(iObject,vtkObjectBase); virtual void PackCompleteState(iString &s) const; virtual void UnPackCompleteState(const iString &s); void PackState(iString &s) const; void UnPackState(const iString &s); virtual void CopyState(const iObject *p); IOBJECT_DECLARE_PACKUNPACK(int,int); IOBJECT_DECLARE_PACKUNPACK(bool,bool); IOBJECT_DECLARE_PACKUNPACK(float,float); IOBJECT_DECLARE_PACKUNPACK(double,double); IOBJECT_DECLARE_PACKUNPACK(iColor,iColor); IOBJECT_DECLARE_PACKUNPACK(iString,const iString&); // // Packing helpers // void PackValuePiecewiseFunction(iString &s, const iObjectKey &key, const iPiecewiseFunction * const *f, int num, int index = -1, bool prefixed = false) const; bool UnPackValuePiecewiseFunction(const iString &s, const iObjectKey &key, iPiecewiseFunction **f, int num); inline void PackValuePiecewiseFunction(iString &s, const iObjectKey &key, const iPiecewiseFunction* val, int index = -1, bool prefixed = false) const { if(index >= 0) PackValuePiecewiseFunction(s,key,&val-index,1,index,prefixed); else PackValuePiecewiseFunction(s,key,&val,1,index,prefixed); } inline bool UnPackValuePiecewiseFunction(const iString &s, const iObjectKey &key, iPiecewiseFunction* &val){ return !key.IsIndexed() && UnPackValuePiecewiseFunction(s,key,&val,1); } void PackValueRangeCollection(iString &s, const iObjectKey &key, const iRangeCollection * const *f, int num, int index = -1, bool prefixed = false) const; bool UnPackValueRangeCollection(const iString &s, const iObjectKey &key, iRangeCollection **f, int num); inline void PackValueRangeCollection(iString &s, const iObjectKey &key, const iRangeCollection* val, int index = -1, bool prefixed = false) const { if(index >= 0) PackValueRangeCollection(s,key,&val-index,1,index,prefixed); else PackValueRangeCollection(s,key,&val,1,index,prefixed); } inline bool UnPackValueRangeCollection(const iString &s, const iObjectKey &key, iRangeCollection* &val){ return !key.IsIndexed() && UnPackValueRangeCollection(s,key,&val,1); } void PackValuePosition(iString &s, const iObjectKey &key, const iPosition &val, int index = -1, bool prefixed = false) const; bool UnPackValuePosition(const iString &s, const iObjectKey &key, iPosition &val); void PackValueDistance(iString &s, const iObjectKey &key, const iDistance &val, int index = -1, bool prefixed = false) const; bool UnPackValueDistance(const iString &s, const iObjectKey &key, iDistance &val); inline bool UnPackedSomething() const { return mUnPackedSomething; } inline void ClearUnPackedSomethingFlag() { mUnPackedSomething = false; } virtual void ClearCache(); static void ReportMissingKeys(bool s); protected: iObject(const iString &name); virtual ~iObject(); virtual void PackStateBody(iString &s) const = 0; virtual void UnPackStateBody(const iString &s) = 0; bool mUnPackedSomething; mutable bool mCacheInvalid; mutable iString mCache; private: static void ReportAMissingKey(const iObjectKey &key); static const iString mSlash; static int mMissingKeysStack; }; // // Helper macros: pointers to keys have to be global so that they exit // when the application starts. If they are declared as static members inside // functions, then they are created "on-demand", and key querying by strings // would not work. However, the opposite is true for types, since they are used // in key creation. // #define IOBJECT_DEFINE_TYPE(_object_,_fname_,_sname_,_class_) \ const iObjectType& _object_::Type() \ { \ static const iObjectType *pval = iObjectTypeRegistry::CreateType(_class_,#_fname_,#_sname_); \ return *pval; \ } #define IOBJECT_DEFINE_KEY(_object_,_fkey_,_skey_,_arg_,_dim_) \ static const iObjectKey *__p##_object_##_fkey_##_arg_ = iObjectKeyRegistry::CreateKey(_object_::Type(),#_fkey_,#_skey_,iObjectKey::_##_arg_,_dim_); \ const iObjectKey& _object_::Key##_fkey_() \ { \ return *__p##_object_##_fkey_##_arg_; \ } #define IOBJECT_DEFINE_EXTRINSIC_KEY(_owner_,_object_,_prefix_,_fkey_,_skey_,_arg_,_dim_) \ static const iObjectKey *__p##_object_##_fkey_##_arg_ = iObjectKeyRegistry::CreateKey(_owner_::Type(),#_prefix_"-"#_fkey_,#_skey_,iObjectKey::_##_arg_,_dim_); \ const iObjectKey& _object_::Key##_fkey_() \ { \ return *__p##_object_##_fkey_##_arg_; \ } #define IOBJECT_DEFINE_INHERITED_KEY(_parent_,_object_,_fkey_,_skey_,_arg_,_dim_) \ static const iObjectKey *__p##_object_##_fkey_##_arg_ = iObjectKeyRegistry::CreateKey(_object_::Type(),#_fkey_,#_skey_,iObjectKey::_##_arg_,_dim_,&_parent_::Type()); \ const iObjectKey& _object_::Key##_fkey_() \ { \ return *__p##_object_##_fkey_##_arg_; \ } #define IOBJECT_DECLARE_GETSET(_fun_,_var_,_type_) \ virtual void Set##_fun_(_type_); \ inline _type_ Get##_fun_() const { return _var_; } \ static const iObjectKey& Key##_fun_() #define IOBJECT_DECLARE_GETSET1(_fun_,_type_) \ virtual void Set##_fun_(_type_); \ inline _type_ Get##_fun_() const { return m##_fun_; } \ static const iObjectKey& Key##_fun_() #define IOBJECT_DECLARE_GETSET2(_fun_,_type_) \ virtual void Set##_fun_(_type_); \ _type_ Get##_fun_() const; \ static const iObjectKey& Key##_fun_() #define IOBJECT_DECLARE_GET(_fun_,_var_,_type_) \ inline _type_ Get##_fun_() const { return _var_; } \ static const iObjectKey& Key##_fun_() #define IOBJECT_DECLARE_GET1(_fun_,_type_) \ inline _type_ Get##_fun_() const { return m##_fun_; } \ static const iObjectKey& Key##_fun_() #define IOBJECT_DECLARE_GET2(_fun_,_type_) \ _type_ Get##_fun_() const; \ static const iObjectKey& Key##_fun_() #define IOBJECT_DECLARE_EXT_GETSET(_ext_,_fun_,_var_,_type_) \ virtual void Set##_fun_(_type_); \ inline _type_ Get##_fun_() const { return _ext_##_var_; } \ static const iObjectKey& Key##_fun_() #define IOBJECT_DECLARE_EXT_GETSET1(_ext_,_fun_,_type_) \ virtual void Set##_fun_(_type_); \ inline _type_ Get##_fun_() const { return _ext_##_fun_; } \ static const iObjectKey& Key##_fun_() #define IOBJECT_DECLARE_EXT_GET(_ext_,_fun_,_var_,_type_) \ inline _type_ Get##_fun_() const { return _ext_##_var_; } \ static const iObjectKey& Key##_fun_() #define IOBJECT_DECLARE_EXT_GET1(_ext_,_fun_,_type_) \ inline _type_ Get##_fun_() const { return _ext_##_fun_; } \ static const iObjectKey& Key##_fun_() #define IOBJECT_DEFINE_DISTANCE_KEY(_object_,_fkey_,_skey_) \ static const iObjectKey *__p##_object_##_fkey_##Double = iObjectKeyRegistry::CreateKey(_object_::Type(),#_fkey_,#_skey_,iObjectKey::_Double,1); \ const iObjectKey& _object_::Key##_fkey_(bool opengl) \ { \ static const iObjectKey *ogl = iObjectKeyRegistry::CreateKey(_object_::Type(),#_fkey_"GL","-"#_skey_,iObjectKey::_Double,1,0,__p##_object_##_fkey_##Double); \ if(opengl) return *ogl; else return *__p##_object_##_fkey_##Double; \ } #define IOBJECT_DEFINE_EXTRINSIC_DISTANCE_KEY(_owner_,_object_,_prefix_,_fkey_,_skey_) \ static const iObjectKey *__p##_object_##_fkey_##Double = iObjectKeyRegistry::CreateKey(_owner_::Type(),#_prefix_"-"#_fkey_,#_skey_,iObjectKey::_Double,1); \ const iObjectKey& _object_::Key##_fkey_(bool opengl) \ { \ static const iObjectKey *ogl = iObjectKeyRegistry::CreateKey(_owner_::Type(),#_prefix_"-"#_fkey_"GL","-"#_skey_,iObjectKey::_Double,1,0,__p##_object_##_fkey_##Double); \ if(opengl) return *ogl; else return *__p##_object_##_fkey_##Double; \ } #define IOBJECT_DEFINE_INHERITED_DISTANCE_KEY(_parent_,_object_,_fkey_,_skey_) \ static const iObjectKey *__p##_object_##_fkey_##Double = iObjectKeyRegistry::CreateKey(_object_::Type(),#_fkey_,#_skey_,iObjectKey::_Double,1,&_parent_::Type()); \ const iObjectKey& _object_::Key##_fkey_(bool opengl) \ { \ static const iObjectKey *ogl = iObjectKeyRegistry::CreateKey(_object_::Type(),#_fkey_"GL","-"#_skey_,iObjectKey::_Double,1,0,__p##_object_##_fkey_##Double); \ if(opengl) return *ogl; else return *__p##_object_##_fkey_##Double; \ } #define IOBJECT_DEFINE_POSITION_KEY(_object_,_fkey_,_skey_) \ static const iObjectKey *__p##_object_##_fkey_##Double = iObjectKeyRegistry::CreateKey(_object_::Type(),#_fkey_,#_skey_,iObjectKey::_Double,3); \ const iObjectKey& _object_::Key##_fkey_(bool opengl) \ { \ static const iObjectKey *ogl = iObjectKeyRegistry::CreateKey(_object_::Type(),#_fkey_"GL","-"#_skey_,iObjectKey::_Double,3,0,__p##_object_##_fkey_##Double); \ if(opengl) return *ogl; else return *__p##_object_##_fkey_##Double; \ } #define IOBJECT_DEFINE_EXTRINSIC_POSITION_KEY(_owner_,_object_,_prefix_,_fkey_,_skey_) \ static const iObjectKey *__p##_object_##_fkey_##Double = iObjectKeyRegistry::CreateKey(_owner_::Type(),#_prefix_"-"#_fkey_,#_skey_,iObjectKey::_Double,3); \ const iObjectKey& _object_::Key##_fkey_(bool opengl) \ { \ static const iObjectKey *ogl = iObjectKeyRegistry::CreateKey(_owner_::Type(),#_prefix_"-"#_fkey_"GL","-"#_skey_,iObjectKey::_Double,3,0,__p##_object_##_fkey_##Double); \ if(opengl) return *ogl; else return *__p##_object_##_fkey_##Double; \ } #define IOBJECT_DEFINE_INHERITED_POSITION_KEY(_parent_,_object_,_fkey_,_skey_) \ static const iObjectKey *__p##_object_##_fkey_##Double = iObjectKeyRegistry::CreateKey(_object_::Type(),#_fkey_,#_skey_,iObjectKey::_Double,3,&_parent_::Type()); \ const iObjectKey& _object_::Key##_fkey_(bool opengl) \ { \ static const iObjectKey *ogl = iObjectKeyRegistry::CreateKey(_object_::Type(),#_fkey_"GL","-"#_skey_,iObjectKey::_Double,3,0,__p##_object_##_fkey_##Double); \ if(opengl) return *ogl; else return *__p##_object_##_fkey_##Double; \ } #define IOBJECT_DECLARE_GETSET_POSITION(_fun_,_var_) \ virtual void Set##_fun_(const iPosition&); \ inline const iPosition& Get##_fun_() const { return _var_; } \ static const iObjectKey& Key##_fun_(bool opengl = false) #define IOBJECT_DECLARE_GETSET_DISTANCE(_fun_,_var_) \ virtual void Set##_fun_(const iDistance&); \ inline const iDistance& Get##_fun_() const { return _var_; } \ static const iObjectKey& Key##_fun_(bool opengl = false) #define IOBJECT_BACKWARD_COMPATIBLE #endif // IOBJECT_H ifrit-3.4.2/core/iobjectfactory.cpp0000755000175700010010000001372112167404432015657 0ustar HomeNone/*========================================================================= Program: Ionization FRont Interactive Tool (IFRIT) Language: C++ Copyright (c) 2002-2012 Nick Gnedin All rights reserved. This file may be distributed and/or modified under the terms of the GNU General Public License version 2 as published by the Free Software Foundation and appearing in the file LICENSE.GPL included in the packaging of this file. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHORS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. =========================================================================*/ #include "iobjectfactory.h" // // This file is documented only partially. // #include "iabstractextension.h" #include "ibasicdatasubjects.h" #include "icrosssectionviewsubject.h" #include "idatareader.h" #include "iedition.h" #include "iparticlesviewsubject.h" #include "ipicker.h" #include "ipointer.h" #include "isurfaceviewsubject.h" #include "itensorfieldviewsubject.h" #include "ivectorfieldviewsubject.h" #include "iviewmodule.h" #include "iviewobject.h" #include "ivolumeviewsubject.h" // // Templates // #include "iarraytemplate.h" // // Helper class // class iAbstractExtensionPointer : public iPointer::Ordered { public: iAbstractExtensionPointer(iAbstractExtension *ptr = 0) : iPointer::Ordered(ptr){} }; // // Main class // iArray& iObjectFactory::Extensions() { static iOrderedArray ext; return ext; } void iObjectFactory::AttachExtension(iAbstractExtension *ext) { if(ext != 0) Extensions().Add(ext); } // // ************************************************************************** // // IMPORTANT: Factory methods do not need to be checked for null pointers // since they are only called from within New() functions // // ************************************************************************** // iViewObject* iObjectFactory::CreateViewObject(iViewObjectParent *parent) { iViewModule *vm(parent->GetViewModule()); const iObjectType &type(parent->GetObjectType()); // // Particles are special - they are not single-type // iViewObject *obj = new iViewObject(parent,false,!type.IsMatch(iParticlesViewSubject::Type())); if(obj == 0) return 0; int i, j; iViewSubject *sub; iArray &ext(Extensions()); // // View objects // if(type.IsMatch(iCrossSectionViewSubject::Type())) { obj->AddSubject(new iCrossSectionViewSubject(vm,iUniformScalarsDataSubject::DataType(),"Cross Section")); for(i=0; iCreateCrossSectionSubject(vm,j++)) != 0) { obj->AddSubject(sub); } } } if(type.IsMatch(iParticlesViewSubject::Type())) { obj->AddSubject(new iParticlesViewSubject(vm,iBasicParticlesDataSubject::DataType(),"Particles")); for(i=0; iCreateParticlesSubject(vm,j++)) != 0) { obj->AddSubject(sub); } } } if(type.IsMatch(iSurfaceViewSubject::Type())) { obj->AddSubject(new iSurfaceViewSubject(vm,iUniformScalarsDataSubject::DataType(),"Surface")); for(i=0; iCreateSurfaceSubject(vm,j++)) != 0) { obj->AddSubject(sub); } } } if(type.IsMatch(iTensorFieldViewSubject::Type())) { obj->AddSubject(new iTensorFieldViewSubject(vm,iUniformTensorsDataSubject::DataType(),iUniformScalarsDataSubject::DataType(),"Tensor Field")); for(i=0; iCreateTensorFieldSubject(vm,j++)) != 0) { obj->AddSubject(sub); } } } if(type.IsMatch(iVectorFieldViewSubject::Type())) { obj->AddSubject(new iVectorFieldViewSubject(vm,iUniformVectorsDataSubject::DataType(),iUniformScalarsDataSubject::DataType(),"Vector Field")); for(i=0; iCreateVectorFieldSubject(vm,j++)) != 0) { obj->AddSubject(sub); } } } if(type.IsMatch(iVolumeViewSubject::Type())) { obj->AddSubject(new iVolumeViewSubject(vm,iUniformScalarsDataSubject::DataType(),"Volume")); for(i=0; iCreateVolumeSubject(vm,j++)) != 0) { obj->AddSubject(sub); } } } for(i=0; iCreateSpecialSubject(vm,j++,type)) != 0) { obj->AddSubject(sub); } } obj->Verify(); iEdition::ApplySettings(obj,type); return obj; } // // These functions install extensions on various extendable classes. // void iObjectFactory::InstallExtensions(iDataReader *reader) { int i; iArray &ext(Extensions()); iDataReaderExtension *s; for(i=0; iCreateDataReaderExtension(reader); if(s != 0) reader->InstallExtension(s); } } void iObjectFactory::InstallExtensions(iPicker *picker) { int i; iArray &ext(Extensions()); iPickerExtension *s; for(i=0; iCreatePickerExtension(picker); if(s != 0) picker->InstallExtension(s); } } void iObjectFactory::InstallExtensions(iViewModule *vm) { int i; iArray &ext(Extensions()); iViewModuleExtension *s; for(i=0; iCreateViewModuleExtension(vm); if(s != 0) vm->InstallExtension(s); } } ifrit-3.4.2/core/iobjectfactory.h0000755000175700010010000000372312167404415015326 0ustar HomeNone/*========================================================================= Program: Ionization FRont Interactive Tool (IFRIT) Language: C++ Copyright (c) 2002-2012 Nick Gnedin All rights reserved. This file may be distributed and/or modified under the terms of the GNU General Public License version 2 as published by the Free Software Foundation and appearing in the file LICENSE.GPL included in the packaging of this file. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHORS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. =========================================================================*/ #ifndef IOBJECTFACTORY_H #define IOBJECTFACTORY_H class iAbstractExtension; class iAbstractExtensionPointer; class iDataReader; template class iArray; class iPicker; class iViewModule; class iViewObject; class iViewObjectParent; class iObjectFactory { friend class iAbstractExtension; public: static iViewObject* CreateViewObject(iViewObjectParent *parent); // // Extensions for extendable objects // static void InstallExtensions(iDataReader *reader); static void InstallExtensions(iPicker *picker); static void InstallExtensions(iViewModule *vm); private: static void AttachExtension(iAbstractExtension *ext); static iArray& Extensions(); }; #endif // IOBJECTFACTORY_H ifrit-3.4.2/core/iobjecthelp.cpp0000755000175700010010000000511212167404432015133 0ustar HomeNone/*========================================================================= Program: Ionization FRont Interactive Tool (IFRIT) Language: C++ Copyright (c) 2002-2012 Nick Gnedin All rights reserved. This file may be distributed and/or modified under the terms of the GNU General Public License version 2 as published by the Free Software Foundation and appearing in the file LICENSE.GPL included in the packaging of this file. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHORS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. =========================================================================*/ #include "iobjecthelp.h" #include "ierror.h" #include "ihelpfactory.h" #include "iobject.h" iObjectHelpBase::iObjectHelpBase(const char *tag) { mData = 0; if(strlen(tag) > 15) { IERROR_FATAL("Tag is too long."); } else strcpy(mTag,tag); } iObjectHelpBase::~iObjectHelpBase() { if(mData != 0) delete mData; } iString iObjectHelpBase::GetText(int length) const { static const iString null; if(mData != 0) return mData->GetText(length); else return null; } iString iObjectHelpBase::GetHTML() const { static const iString null; if(mData != 0) return mData->GetHTML(); else return null; } // // Extra controls // const iString iObjectHelpBase::GetExtraTag(int type) const { static const iString null; if(mData != 0) return mData->GetExtraTag(type); else return null; } iObjectTypeHelp::iObjectTypeHelp(const iObjectType *type) : iObjectHelpBase(("or."+type->ShortName()).ToCharPointer()) { mType = type; if(type != 0) { mData = iHelpFactory::FindData(this->GetTag(),iHelpFactory::_ObjectReference,true); } } iObjectTypeHelp::~iObjectTypeHelp() { } iObjectKeyHelp::iObjectKeyHelp(const iObjectKey *key) : iObjectHelpBase(("or."+key->HelpEntryKey()).ToCharPointer()) { mKey = key; if(key != 0) { mData = iHelpFactory::FindData(this->GetTag(),iHelpFactory::_ObjectReference,true); } } iObjectKeyHelp::~iObjectKeyHelp() { } ifrit-3.4.2/core/iobjecthelp.h0000755000175700010010000000454412167404415014611 0ustar HomeNone/*========================================================================= Program: Ionization FRont Interactive Tool (IFRIT) Language: C++ Copyright (c) 2002-2012 Nick Gnedin All rights reserved. This file may be distributed and/or modified under the terms of the GNU General Public License version 2 as published by the Free Software Foundation and appearing in the file LICENSE.GPL included in the packaging of this file. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHORS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. =========================================================================*/ // // This interface provides help text for iObject types and keys // #ifndef IOBJECTHELP_H #define IOBJECTHELP_H #include "istring.h" class iHelpDataBuffer; class iObjectType; class iObjectKey; class iObjectHelpBase { public: inline const char* GetTag() const { return mTag; } iString GetText(int length = 0) const; iString GetHTML() const; // // Extra controls // const iString GetExtraTag(int type) const; protected: // // Cannot be created except by children // iObjectHelpBase(const char *tag); virtual ~iObjectHelpBase(); iHelpDataBuffer* mData; char mTag[16]; private: iObjectHelpBase(const iObjectHelpBase&); // Not implemented. void operator=(const iObjectHelpBase&); // Not implemented. }; class iObjectTypeHelp : public iObjectHelpBase { public: iObjectTypeHelp(const iObjectType *type = 0); virtual ~iObjectTypeHelp(); private: const iObjectType *mType; }; class iObjectKeyHelp : public iObjectHelpBase { // friend class iShell; public: iObjectKeyHelp(const iObjectKey *key = 0); virtual ~iObjectKeyHelp(); private: const iObjectKey *mKey; }; #endif // IOBJECTHELP_H ifrit-3.4.2/core/ioptimizepolydatafilter.cpp0000755000175700010010000000305212167404432017621 0ustar HomeNone/*========================================================================= Program: Ionization FRont Interactive Tool (IFRIT) Language: C++ Copyright (c) 2002-2012 Nick Gnedin All rights reserved. This file may be distributed and/or modified under the terms of the GNU General Public License version 2 as published by the Free Software Foundation and appearing in the file LICENSE.GPL included in the packaging of this file. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHORS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. =========================================================================*/ #include "ioptimizepolydatafilter.h" // // Templates // #include "igenericfiltertemplate.h" iOptimizePolyDataFilter::iOptimizePolyDataFilter(iViewSubject *vo) : iGenericPolyDataToPolyDataFilter(vo,1,true,false) { } void iOptimizePolyDataFilter::ProduceOutput() { this->ExecuteParent(); } ifrit-3.4.2/core/ioptimizepolydatafilter.h0000644000175700010010000000313612167404415017267 0ustar HomeNone/*========================================================================= Program: Ionization FRont Interactive Tool (IFRIT) Language: C++ Copyright (c) 2002-2012 Nick Gnedin All rights reserved. This file may be distributed and/or modified under the terms of the GNU General Public License version 2 as published by the Free Software Foundation and appearing in the file LICENSE.GPL included in the packaging of this file. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHORS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. =========================================================================*/ #ifndef IOPTIMIZEPOLYDATAFILTER_H #define IOPTIMIZEPOLYDATAFILTER_H #include "igenericfilter.h" #include class iOptimizePolyDataFilter : public iGenericPolyDataToPolyDataFilter { IGENERICFILTER_DECLARE(iOptimizePolyDataFilter,vtkStripper); protected: virtual void ProduceOutput(); }; #endif // IOPTIMIZEPOLYDATAFILTER_H ifrit-3.4.2/core/iorthopolygonplanefilter.cpp0000755000175700010010000001423312167404432020011 0ustar HomeNone/*========================================================================= Program: Ionization FRont Interactive Tool (IFRIT) Language: C++ Copyright (c) 2002-2012 Nick Gnedin All rights reserved. This file may be distributed and/or modified under the terms of the GNU General Public License version 2 as published by the Free Software Foundation and appearing in the file LICENSE.GPL included in the packaging of this file. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHORS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. =========================================================================*/ #include "iorthopolygonplanefilter.h" #include "ierror.h" #include "iorthoslicer.h" #include "ivtk.h" #include #include #include #include #include #include // // Templates // #include "igenericfiltertemplate.h" #ifndef IVTK_QUAD_ORDER #error Misconfiguration: missing IVTK_QUAD_ORDER define. !TERMINATE! #endif iOrthoPolygonPlaneFilter::iOrthoPolygonPlaneFilter(iViewSubject *vo) : iGenericFilter(vo,1,true,false) { mInterpolate = true; mOldDimU = mOldDimV = 0; // // Keep our quds so that we do not have to re-create them unless something changes // mNewQuads = vtkCellArray::New(); IERROR_ASSERT(mNewQuads); } iOrthoPolygonPlaneFilter::~iOrthoPolygonPlaneFilter() { mNewQuads->Delete(); } void iOrthoPolygonPlaneFilter::SetInterpolation(bool s) { mInterpolate = s; this->Modified(); } void iOrthoPolygonPlaneFilter::ProduceOutput() { int dims[3]; double org[3], spa[3]; vtkImageData *input = this->GetInput(); vtkPolyData *output = this->GetOutput(); output->Initialize(); // // Do we have cell or point data? // bool isPointData; if(input->GetPointData()->GetScalars() != 0) { isPointData = true; } else if(input->GetCellData()->GetScalars() != 0) { isPointData = false; } else { // // Must be quiet here for parallel execution // return; } input->GetOrigin(org); input->GetSpacing(spa); input->GetDimensions(dims); int i, j, k, Axis = -1; for(i=0; i<3; i++) { if(dims[i] == 1) Axis = i; } if(Axis == -1) { vtkErrorMacro("iOrthoPolygonPlaneFilter: input data are not a plane."); return; } int u, v, dimU, dimV; iOrthoSlicer::GetUV(Axis,u,v); if(isPointData) { dimU = dims[u]; dimV = dims[v]; } else { dimU = dims[u] + 1; dimV = dims[v] + 1; } if(dimU<1 || dimV<1) { return; } vtkIdType numPts = (vtkIdType)dimU*dimV; vtkPoints *newPts = vtkPoints::New(VTK_FLOAT); IERROR_ASSERT(newPts); newPts->SetNumberOfPoints(numPts); float xyz[3]; xyz[Axis] = org[Axis]; float *p = (float *)newPts->GetVoidPointer(0); for(j=0; jUpdateProgress(float(j)/dimV); if(this->GetAbortExecute()) break; xyz[v] = org[v] + spa[v]*j; for(i=0; iDelete(); mNewQuads = vtkCellArray::New(); IERROR_ASSERT(mNewQuads); mNewQuads->Allocate(mNewQuads->EstimateSize((dimV-1)*(dimU-1),4)); vtkIdType l[4]; for(j=0; jUpdateProgress(float(j)/(dimV-1)); if(this->GetAbortExecute()) break; for(i=0; iInsertNextCell(4,l); } } mOldDimU = dimU; mOldDimV = dimV; } output->SetPolys(mNewQuads); output->SetPoints(newPts); newPts->Delete(); // // Assign scalars // if(isPointData) { if(!mInterpolate) { // // Correct for flat shading // if(!this->ScalarsInit(input->GetPointData())) return; float *pl, *ql; for(j=0; jScalarsDone(output->GetPointData()); } else { output->GetPointData()->SetScalars(input->GetPointData()->GetScalars()); } } else { if(!this->ScalarsInit(input->GetCellData(),numPts)) return; int du = dimU - 1; if(mInterpolate) { float *ql; int i1, j1, i2, j2; for(j=0; jScalarsDone(output->GetPointData()); } } ifrit-3.4.2/core/iorthopolygonplanefilter.h0000644000175700010010000000355412167404415017460 0ustar HomeNone/*========================================================================= Program: Ionization FRont Interactive Tool (IFRIT) Language: C++ Copyright (c) 2002-2012 Nick Gnedin All rights reserved. This file may be distributed and/or modified under the terms of the GNU General Public License version 2 as published by the Free Software Foundation and appearing in the file LICENSE.GPL included in the packaging of this file. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHORS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. =========================================================================*/ #ifndef IORTHOPOLYGONPLANEFILTER_H #define IORTHOPOLYGONPLANEFILTER_H #include "igenericfilter.h" #include class vtkCellArray; class iOrthoPolygonPlaneFilter : public iGenericFilter { IGENERICFILTER_DECLARE(iOrthoPolygonPlaneFilter,vtkStructuredPointsToPolyDataFilter); public: void SetInterpolation(bool s); protected: virtual ~iOrthoPolygonPlaneFilter(); virtual void ProduceOutput(); private: bool mInterpolate; int mOldDimU, mOldDimV; vtkCellArray *mNewQuads; }; #endif // IORTHOPOLYGONPLANEFILTER_H ifrit-3.4.2/core/iorthoslicer.cpp0000755000175700010010000001530312167404432015354 0ustar HomeNone/*========================================================================= Program: Ionization FRont Interactive Tool (IFRIT) Language: C++ Copyright (c) 2002-2012 Nick Gnedin All rights reserved. This file may be distributed and/or modified under the terms of the GNU General Public License version 2 as published by the Free Software Foundation and appearing in the file LICENSE.GPL included in the packaging of this file. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHORS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. =========================================================================*/ #include "iorthoslicer.h" #include "idata.h" #include "ierror.h" #include "iuniformgriddata.h" #include "iviewmodule.h" #include #include #include using namespace iParameter; // // Templates // #include "igenericfiltertemplate.h" iOrthoSlicer::iOrthoSlicer(iViewSubject *vo) : iGenericFilter(vo,1,true,false) { mCurVar = 0; mPos[0] = mPos[1] = mPos[2] = 0; mDir = 2; mSampleRate = 1; mInterpolate = true; } iOrthoSlicer::~iOrthoSlicer() { } void iOrthoSlicer::SetCurrentVar(int n) { if(n>=0 && n!=mCurVar) { mCurVar = n; this->Modified(); } } void iOrthoSlicer::SetInterpolation(bool s) { if(s != mInterpolate) { mInterpolate = s; this->Modified(); } } void iOrthoSlicer::SetPos(double p) { mPos[mDir] = p; this->Modified(); } void iOrthoSlicer::SetDir(int d) { if(d>=0 && d<3 && d!=mDir) { mDir = d; this->Modified(); } } void iOrthoSlicer::ProduceOutput() { int numCellsIn[3], dimsIn[3], dimsOut[3]; double orgIn[3], spaIn[3]; double orgOut[3], spaOut[3]; int u, v; iOrthoSlicer::GetUV(mDir,u,v); iUniformGridData *input = iUniformGridData::SafeDownCast(this->GetInput()); vtkImageData *output = this->GetOutput(); output->Initialize(); if(input == 0) return; input->GetNumCells(numCellsIn); if(numCellsIn[u]<1 || numCellsIn[v]<1) return; // // Get info about out configuration // input->GetSpacing(spaIn); input->GetGlobalOrigin(orgIn); input->GetDimensions(dimsIn); // // Compute the sub-sampling factor // int step = mSampleRate; step = (numCellsIn[u]/8 > step) ? step : numCellsIn[u]/8; step = (numCellsIn[v]/8 > step) ? step : numCellsIn[v]/8; if(step < 1) step = 1; // // Decide what we do: cell vs point data, how many points, etc. // if(input->GetVoxelLocation() == VoxelLocation::Vertex) { // // Place points as we get them // dimsOut[u] = numCellsIn[u]/step + 1; dimsOut[v] = numCellsIn[v]/step + 1; if(dimsOut[u]<2 || dimsOut[v]<2) return; spaOut[u] = (spaIn[u]*numCellsIn[u])/(dimsOut[u]-1); spaOut[v] = (spaIn[v]*numCellsIn[v])/(dimsOut[v]-1); } else { // // Create points around cells, but throw away periodic offsets // dimsOut[u] = numCellsIn[u]/step; dimsOut[v] = numCellsIn[v]/step; if(dimsOut[u]<1 || dimsOut[v]<1) return; spaOut[u] = (spaIn[u]*numCellsIn[u])/dimsOut[u]; spaOut[v] = (spaIn[v]*numCellsIn[v])/dimsOut[v]; } dimsOut[mDir] = 1; spaOut[mDir] = 1.0; orgOut[u] = orgIn[u]; orgOut[v] = orgIn[v]; orgOut[mDir] = mPos[mDir]; // // Find the intersection // int ijk[3], ijk1[3], ijk2[3]; float ht = (mPos[mDir]-orgIn[mDir])/spaIn[mDir]; //Normalized height // // Must do that for parallel work // if(ht<-0.01 || ht>numCellsIn[mDir]+0.01) { return; } if(input->GetVoxelLocation() == VoxelLocation::Center) ht -= 0.5; // // Add a little bit of a cushion // if(ht < 0.01) ht = 0.01; if(ht > numCellsIn[mDir]-0.01) ht = numCellsIn[mDir] - 0.01; ijk1[mDir] = ijk2[mDir] = int(ht); //Grid Point below if(ijk2[mDir] < dimsIn[mDir]-1) ijk2[mDir]++; #ifdef I_CHECK1 if(ijk1[mDir]<0 || ijk2[mDir]>=dimsIn[mDir]) { IERROR_REPORT_BUG; } #endif float ss2 = ht - ijk1[mDir]; float ss1 = 1.0 - ss2; output->SetDimensions(dimsOut); output->SetOrigin(orgOut); output->SetSpacing(spaOut); // // Prepare output scalars // vtkIdType numPts = dimsOut[u]*dimsOut[v]; if(!this->ScalarsInit(input->GetPointData(),numPts,1)) return; wScalarPtrIn += mCurVar; vtkIdType loffOut, loffIn1, loffIn2; for(ijk[v]=0; ijk[v]UpdateProgress((float)ijk[v]/dimsOut[v]); if(this->GetAbortExecute()) break; for(ijk[u]=0; ijk[u]GetVoxelLocation() == VoxelLocation::Vertex) { this->ScalarsDone(output->GetPointData()); } else { this->ScalarsDone(output->GetCellData()); } } void iOrthoSlicer::GetUV(int Axis, int &u, int &v) { switch(Axis) { case 0: { u = 1; v = 2; return; } case 1: { u = 0; v = 2; return; } case 2: { u = 0; v = 1; return; } } } ifrit-3.4.2/core/iorthoslicer.h0000644000175700010010000000441112167404415015015 0ustar HomeNone/*========================================================================= Program: Ionization FRont Interactive Tool (IFRIT) Language: C++ Copyright (c) 2002-2012 Nick Gnedin All rights reserved. This file may be distributed and/or modified under the terms of the GNU General Public License version 2 as published by the Free Software Foundation and appearing in the file LICENSE.GPL included in the packaging of this file. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHORS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. =========================================================================*/ #ifndef IORTHOSLICER_H #define IORTHOSLICER_H #include "igenericfilter.h" #include class iOrthoSlicer : public iGenericFilter { IGENERICFILTER_DECLARE(iOrthoSlicer,vtkStructuredPointsToStructuredPointsFilter); public: void SetCurrentVar(int n); inline int GetCurrentVar() const { return mCurVar; } void SetDir(int d); inline int GetDir() const { return mDir; } void SetPos(double p); inline double GetPos() const { return mPos[mDir]; } void SetInterpolation(bool s); inline bool GetInterpolation() const { return mInterpolate; } void SetSampleRate(int r){ mSampleRate = r; Modified(); } inline int GetSampleRate() const { return mSampleRate; } static void GetUV(int Axis, int &Uidx, int &Vidx); protected: virtual ~iOrthoSlicer(); virtual void ProduceOutput(); private: int mCurVar; double mPos[3]; int mDir, mSampleRate; bool mInterpolate; }; #endif // IORTHOSLICER_H ifrit-3.4.2/core/iorthotextureplanefilter.cpp0000755000175700010010000002322312167404432020021 0ustar HomeNone/*========================================================================= Program: Ionization FRont Interactive Tool (IFRIT) Language: C++ Copyright (c) 2002-2012 Nick Gnedin All rights reserved. This file may be distributed and/or modified under the terms of the GNU General Public License version 2 as published by the Free Software Foundation and appearing in the file LICENSE.GPL included in the packaging of this file. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHORS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. =========================================================================*/ #include "iorthotextureplanefilter.h" #include "idatalimits.h" #include "ierror.h" #include "iorthoslicer.h" #include "imath.h" #include #include #include #include // // Templates // #include "igenericfiltertemplate.h" iOrthoTexturePlaneFilter::iOrthoTexturePlaneFilter(iViewSubject *vo) : iGenericFilter(vo,1,true,false) { mTexture = 0; mOffX = mOffY = 0; } void iOrthoTexturePlaneFilter::SetTexturePiece(vtkImageData *texture, int offx, int offy, double globalOrg[3], int globalDims[3]) { int i; mTexture = texture; mOffX = offx; mOffY = offy; for(i=0; i<3; i++) { mGlobalOrg[i] = globalOrg[i]; mGlobalDims[i] = globalDims[i]; } this->Modified(); } void iOrthoTexturePlaneFilter::ProduceOutput() { int dims[3], dimsTexture[3]; double org[3], spa[3]; vtkImageData *input = this->GetInput(); vtkPolyData *output = this->GetOutput(); output->Initialize(); if(mTexture == 0) return; // // Do we have cell or point data? // vtkFloatArray *scalars; bool isPointData; if(input->GetPointData()->GetScalars() != 0) { isPointData = true; scalars = vtkFloatArray::SafeDownCast(input->GetPointData()->GetScalars()); } else if(input->GetCellData()->GetScalars() != 0) { isPointData = false; scalars = vtkFloatArray::SafeDownCast(input->GetCellData()->GetScalars()); } else { // // Must be quiet here for parallel execution // return; } if(scalars == 0) return; // // Prepare texture support // input->GetOrigin(org); input->GetSpacing(spa); input->GetDimensions(dims); int i, Axis = -1; for(i=0; i<3; i++) { if(dims[i] == 1) Axis = i; } if(Axis == -1) return; int u, v, dimU, dimV; iOrthoSlicer::GetUV(Axis,u,v); if(isPointData) { dimU = dims[u] - 1; dimV = dims[v] - 1; } else { dimU = dims[u]; dimV = dims[v]; } if(dimU<1 || dimV<1) { return; } mTexture->GetDimensions(dimsTexture); // // AppendPolyDataFilter does not merge texture coordinates into one, so we need to create the correct texture support here. // We create it for zero offset instance, and skip it altogether for other instances. // if(mOffX==0 && mOffY==0) { float tc[2], pad; static vtkIdType pts[4]={0,1,2,3}; int dimU, dimV; if(isPointData) { dimU = mGlobalDims[u] - 1; dimV = mGlobalDims[v] - 1; pad = 0.0; } else { dimU = mGlobalDims[u] - 1; dimV = mGlobalDims[v] - 1; pad = 0.5; } // // We'll create the building blocks of polydata including data attributes. // vtkPoints *points; points = vtkPoints::New(VTK_FLOAT); IERROR_ASSERT(points); vtkCellArray *polys; polys = vtkCellArray::New(); IERROR_ASSERT(polys); vtkFloatArray *tcoords; tcoords = vtkFloatArray::New(); IERROR_ASSERT(tcoords); points->SetNumberOfPoints(4); tcoords->SetNumberOfComponents(2); tcoords->SetNumberOfTuples(4); // // Load the cell, and data attributes. // polys->InsertNextCell(4,pts); // // Place the support plane // double x1[3]; x1[Axis] = org[Axis]; // // LL point // x1[u] = mGlobalOrg[u] - pad*spa[u]; x1[v] = mGlobalOrg[v] - pad*spa[v]; points->SetPoint(0,x1); tc[0] = 0.0; tc[1] = 0.0; tcoords->SetTuple(0,tc); // // LR point // x1[u] = mGlobalOrg[u] - pad*spa[u] + spa[u]*dimU; x1[v] = mGlobalOrg[v] - pad*spa[v]; points->SetPoint(1,x1); tc[0] = float(dimU)/dimsTexture[0]; tc[1] = 0.0; tcoords->SetTuple(1,tc); // // UR point // x1[u] = mGlobalOrg[u] - pad*spa[u] + spa[u]*dimU; x1[v] = mGlobalOrg[v] - pad*spa[v] + spa[v]*dimV; points->SetPoint(2,x1); tc[0] = float(dimU)/dimsTexture[0]; tc[1] = float(dimV)/dimsTexture[1]; tcoords->SetTuple(2,tc); // // UL point // x1[u] = mGlobalOrg[u] - pad*spa[u]; x1[v] = mGlobalOrg[v] - pad*spa[v] + spa[v]*dimV; points->SetPoint(3,x1); tc[0] = 0.0; tc[1] = float(dimV)/dimsTexture[1]; tcoords->SetTuple(3,tc); // // We now assign the pieces to the vtkPolyData. // output->SetPolys(polys); output->SetPoints(points); output->GetPointData()->SetTCoords(tcoords); polys->Delete(); points->Delete(); tcoords->Delete(); } // // Fill in our portion of the texture // int ncomIn = scalars->GetNumberOfComponents(); float *ptrIn = scalars->GetPointer(0); float *ptrOut = (float *)mTexture->GetScalarPointer(); if(ptrOut == 0) { vtkErrorMacro("Texture data has not been allocated properly."); return; } int ijk[3], ijkmin[3], ijknum[3]; ijk[Axis] = 0; ijkmin[u] = 0; ijkmin[v] = 0; ijknum[u] = dimU; ijknum[v] = dimV; if(mOffX < 0) ijkmin[u] -= mOffX; if(mOffY < 0) ijkmin[v] -= mOffY; if(mOffX+ijknum[u] > dimsTexture[0]) ijknum[u] = dimsTexture[0] - mOffX; if(mOffY+ijknum[v] > dimsTexture[1]) ijknum[v] = dimsTexture[1] - mOffY; vtkIdType off1 = 0, off2 = 0, off3; switch(Axis) { case 0: { // // u = 1, v = 2; // off1 = dims[0]; off2 = dims[0]*dims[1]; break; } case 1: { // // u = 0, v = 1; // off1 = 1; off2 = dims[0]*dims[1]; break; } case 2: { // // u = 0, v = 1; // off1 = 1; off2 = dims[0]; break; } } off1 *= ncomIn; off2 *= ncomIn; off3 = off1 + off2; vtkIdType lIn, lOut; for(ijk[v]=ijkmin[v]; ijk[v]UpdateProgress((float)(ijk[v]-ijkmin[v])/(ijknum[v]-ijkmin[v])); if(this->GetAbortExecute()) break; for(ijk[u]=ijkmin[u]; ijk[u]Modified(); } void iOrthoTexturePlaneFilter::UpdateBoundaryConditions() { // // Do it only for master // if(mTexture==0 || mOffX!=0 || mOffY!=0) return; int dims[3], dimsTexture[3]; vtkImageData *input = this->GetInput(); // // Do we have cell or point data? // bool isPointData; if(input->GetPointData()->GetScalars() != 0) { isPointData = true; } else if(input->GetCellData()->GetScalars() != 0) { isPointData = false; } else { // // Must be quiet here for parallel execution // return; } input->GetDimensions(dims); int i, Axis = -1; for(i=0; i<3; i++) { if(dims[i] == 1) Axis = i; } if(Axis == -1) return; int u, v, dimU, dimV; iOrthoSlicer::GetUV(Axis,u,v); if(isPointData) { dimU = dims[u] - 1; dimV = dims[v] - 1; } else { dimU = dims[u]; dimV = dims[v]; } if(dimU<1 || dimV<1) { return; } mTexture->GetDimensions(dimsTexture); float *ptrOut = (float *)mTexture->GetScalarPointer(); // // Boundary conditions for proper interpolation // int i1off, i2off; bool per[3]; this->GetLimits()->GetPeriodicities(per); if(dimU < dimsTexture[0]) { i1off = per[u] ? dimU-1 : 0; i2off = per[u] ? 0 : dimU-1; for(i=0; iModified(); } ifrit-3.4.2/core/iorthotextureplanefilter.h0000644000175700010010000000372712167404415017473 0ustar HomeNone/*========================================================================= Program: Ionization FRont Interactive Tool (IFRIT) Language: C++ Copyright (c) 2002-2012 Nick Gnedin All rights reserved. This file may be distributed and/or modified under the terms of the GNU General Public License version 2 as published by the Free Software Foundation and appearing in the file LICENSE.GPL included in the packaging of this file. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHORS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. =========================================================================*/ #ifndef IORTHOTEXTUREPLANEFILTER_H #define IORTHOTEXTUREPLANEFILTER_H #include "igenericfilter.h" #include class iOrthoTexturePlaneFilter : public iGenericFilter { IGENERICFILTER_DECLARE(iOrthoTexturePlaneFilter,vtkStructuredPointsToPolyDataFilter); public: // // Offsets needed for parallel work // void SetTexturePiece(vtkImageData *texture, int offX, int offY, double globalOrg[3], int globalDims[3]); void UpdateBoundaryConditions(); protected: virtual void ProduceOutput(); private: vtkImageData *mTexture; int mOffX, mOffY; double mGlobalOrg[3]; int mGlobalDims[3]; }; #endif // IORTHOTEXTUREPLANEFILTER_H ifrit-3.4.2/core/ioutputchannel.cpp0000755000175700010010000002317212167404433015714 0ustar HomeNone/*========================================================================= Program: Ionization FRont Interactive Tool (IFRIT) Language: C++ Copyright (c) 2002-2012 Nick Gnedin All rights reserved. This file may be distributed and/or modified under the terms of the GNU General Public License version 2 as published by the Free Software Foundation and appearing in the file LICENSE.GPL included in the packaging of this file. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHORS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. =========================================================================*/ #include "ioutputchannel.h" #include "ifile.h" #include "imath.h" #include "ishell.h" #include #include #include using namespace iParameter; iOutputChannel* iOutputChannel::mInstance = 0; namespace iOutputChannel_Private { // // Converts a Gregorian date to a Julian day. // This algorithm is taken from Communications of the ACM, Vol 6, No 8. // unsigned int DateToJd(int y, int m, int d) { unsigned int c, ya; if ( y <= 99 ) y += 1900; if ( m > 2 ) { m -= 3; } else { m += 9; y--; } c = y; c /= 100; ya = y - 100*c; return 1721119 + d + (146097*c)/4 + (1461*ya)/4 + (153*m+2)/5; } // // Converts a Julian day to a Gregorian date. // This algorithm is taken from Communications of the ACM, Vol 6, No 8. // void JdToDate(unsigned int jd, int &y, int &m, int &d) { unsigned int x; unsigned int j = jd - 1721119; y = (j*4 - 1)/146097; j = j*4 - 146097*y - 1; x = j/4; j = (x*4 + 3) / 1461; y = 100*y + j; x = (x*4) + 3 - 1461*j; x = (x + 4)/4; m = (5*x - 3)/153; x = 5*x - 3 - 153*m; d = (x + 5)/5; if ( m < 10 ) { m += 3; } else { m -= 9; y++; } } // // Converts Universal Coordinated time to a Julian day // unsigned int UctToJd(double uct) { return 2440588 + int(uct/86400.0); } // // Converts a Julian day to Universal Coordinated time // double JdToUct(unsigned int jd) { return 86400.0*(jd-2440588); } // // Converts Universal Coordinated time to Gregorian date/time // void UctToDateTime(double uct, int &year, int &month, int &day, int &hour, int &minute, int &second) { unsigned int jd = UctToJd(uct); JdToDate(jd,year,month,day); unsigned int s = round(uct-JdToUct(jd)); hour = s/3600; minute = (s-3600*hour)/60; second = s - 3600*hour - 60*minute; } // // Take over VTK display function to prevent it from displaying extra windows // class OutputWindow : public vtkOutputWindow { vtkTypeMacro(OutputWindow,vtkOutputWindow); static OutputWindow* New(iOutputChannel *c = 0) { if(c == 0) return 0; else return new OutputWindow(c); } // // Don't overwrite those, they ARE thread-safe // virtual void DisplayText(const char* message) { if(mMutex!=0 && mOutput!=0 && !mInDisplay) { mMutex->Lock(); mInDisplay = true; mOutput->Display(iConsole::_Info,message,0,0); mInDisplay = false; mMutex->Unlock(); } } virtual void DisplayErrorText(const char* message) { if(mMutex!=0 && mOutput!=0 && !mInDisplay) { const char* fm = this->FormattedErrorMessage(message); if(fm != 0) { mMutex->Lock(); mInDisplay = true; mOutput->Display(iConsole::_LowError,fm,0,0); mInDisplay = false; mMutex->Unlock(); } } } virtual void DisplayWarningText(const char* message) { if(mMutex!=0 && mOutput!=0 && !mInDisplay) { mMutex->Lock(); mInDisplay = true; mOutput->Display(iConsole::_Warning,message,0,0); mInDisplay = false; mMutex->Unlock(); } } virtual void DisplayGenericWarningText(const char* message) { this->DisplayWarningText(message); } virtual void DisplayDebugText(const char* message) { #ifdef I_DEBUG this->DisplayText(message); #endif } protected: virtual ~OutputWindow() { if(mMutex != 0) mMutex->Delete(); } private: OutputWindow(iOutputChannel *c) { mInDisplay = false; mOutput = c; mMutex = vtkMutexLock::New(); } const char* FormattedErrorMessage(const char* message) const { // // Block some of the VTK error messages - not all are useful // const int nBlockError = 4; const char *classBlockError[] = { "vtkDecimate", "vtkPolyDataNormals", "vtkWindowedSincPolyDataFilter", "vtkStreamingDemandDrivenPipeline" }; const char *messgBlockError[] = { "No data to decimate!", "No data to generate normals for!", "No data to smooth!", "The update extent specified in the information for output port" }; int i; for(i=0; iDelete(); mInstance = c; OutputWindow *ow = OutputWindow::New(c); vtkOutputWindow::SetInstance(ow); ow->Delete(); } } iOutputChannel::iOutputChannel(iShell *s) { mInDisplay = mLoggingBlocked = mLogCreated = mInUpdateLog = false; if(s != 0) { // // Attach the log file // mLogFileName = s->GetEnvironment(Environment::Base) + "ifrit.err"; } } iOutputChannel::~iOutputChannel() { } void iOutputChannel::UpdateLog(const iString &message, const char* file, int line) { if(mLogFileName.IsEmpty() || mLoggingBlocked || mInUpdateLog) return; mInUpdateLog = true; iFile F(mLogFileName); if(F.Open(iFile::_Append,iFile::_Text) || F.Open(iFile::_Write,iFile::_Text)) { iString ws = message + " File: " + file + " Line: " + iString::FromNumber(line); if(!mLogCreated) { double s = vtkTimerLog::GetUniversalTime(); int year, month, day, hour, minute, second; UctToDateTime(s,year,month,day,hour,minute,second); F.WriteLine(" "); F.WriteLine("New run: "+iString::FromNumber(year)+"/"+iString::FromNumber(month)+"/"+iString::FromNumber(day)+"/"+iString::FromNumber(hour)+"/"+iString::FromNumber(minute)+"/"+iString::FromNumber(second)); F.WriteLine("---------------------------"); } if(F.WriteLine(ws)) mLogCreated = true; F.Close(); } mInUpdateLog = false; } void iOutputChannel::Display(iConsole::MessageType type, const iString &message, const char *file, int line) { if(mInDisplay) return; mInDisplay = true; #ifdef I_DEBUG if(type == iConsole::_Info) { iConsole::PrintDebugMessage(message); } else { if(message.Part(0,12) != "Missing key:") { const char *ptr = message.ToCharPointer(); int ooo = 0; } } #endif this->DisplayBody(type,message,file,line); // // Update log // switch(type) { case iConsole::_HighError: // case iConsole::_LowError: { this->UpdateLog(message,file,line); break; } case iConsole::_FatalError: { this->UpdateLog(message,file,line); exit(1); break; } } mInDisplay = false; } void iOutputChannel::DisplayBody(iConsole::MessageType type, const iString &message, const char *file, int line) { // // Send everything to the standard vtkOutputWindow // if(type == iConsole::_Notification) vtkOutputWindow::GetInstance()->PromptUserOn(); vtkOutputWindow::GetInstance()->DisplayText(this->FormPlainTextMessage(type,message,file,line).ToCharPointer()); vtkOutputWindow::GetInstance()->PromptUserOff(); } iString iOutputChannel::FormPlainTextMessage(iConsole::MessageType type, const iString &message, const char *file, int line) { iString text; switch(type) { case iConsole::_Info: case iConsole::_Notification: { text = message + "\n"; break; } case iConsole::_Warning: { text = "!IMPORTANT: " + message + "\n"; break; } case iConsole::_LowError: case iConsole::_HighError: { text = "! NON-FATAL ERROR: " + message + "\n"; if(file != 0) { text += " FILE: " + iString(file) + "\n"; text += " LINE: " + iString::FromNumber(line) + "\n"; } break; } case iConsole::_FatalError: { text = "!!! FATAL ERROR: " + message + "\n"; if(file != 0) { text += " FILE: " + iString(file) + "\n"; text += " LINE: " + iString::FromNumber(line) + "\n"; } text += "IFrIT will now abort.\n"; break; } } return text; } void iOutputChannel::BlockLogging(bool s) { mLoggingBlocked = s; } void iOutputChannel::NotifyIfLogCreated() { if(mLogCreated) { iString ws = "A log of all error messages was created in the file:\n" + mLogFileName + "\n Please, consider e-mailing this file to ifrit.bugs@gmail.com"; this->Display(iConsole::_Warning,ws,0,0); } } ifrit-3.4.2/core/ioutputchannel.h0000755000175700010010000000465112167404415015362 0ustar HomeNone/*========================================================================= Program: Ionization FRont Interactive Tool (IFRIT) Language: C++ Copyright (c) 2002-2012 Nick Gnedin All rights reserved. This file may be distributed and/or modified under the terms of the GNU General Public License version 2 as published by the Free Software Foundation and appearing in the file LICENSE.GPL included in the packaging of this file. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHORS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. =========================================================================*/ // // Method for outputing messages // #ifndef IOUTPUTCHANNEL_H #define IOUTPUTCHANNEL_H #include #include "iconsole.h" #include "istring.h" #include class iShell; class iOutputChannel : public vtkObjectBase { friend class iConsole; friend class iShell; public: vtkTypeMacro(iOutputChannel,vtkObjectBase); static void SetInstance(iOutputChannel *c); // // Use this function to report errors and display text // void Display(iConsole::MessageType type, const iString &message, const char *file, int line); // // Log functions // void NotifyIfLogCreated(); void BlockLogging(bool s); protected: iOutputChannel(iShell *s); virtual ~iOutputChannel(); virtual void DisplayBody(iConsole::MessageType type, const iString &message, const char *file, int line); iString FormPlainTextMessage(iConsole::MessageType type, const iString &message, const char *file, int line); private: static iOutputChannel* GetInstance(); static iOutputChannel* mInstance; iString mLogFileName; bool mInDisplay, mLogCreated, mInUpdateLog, mLoggingBlocked; void UpdateLog(const iString &message, const char* file, int line); }; #endif // IOUTPUTCHANNEL_H ifrit-3.4.2/core/ioverlayhelper.cpp0000755000175700010010000000730012167404433015677 0ustar HomeNone/*========================================================================= Program: Ionization FRont Interactive Tool (IFRIT) Language: C++ Copyright (c) 2002-2012 Nick Gnedin All rights reserved. This file may be distributed and/or modified under the terms of the GNU General Public License version 2 as published by the Free Software Foundation and appearing in the file LICENSE.GPL included in the packaging of this file. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHORS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. =========================================================================*/ #include "ioverlayhelper.h" #include "ierror.h" #include "imagnifier.h" #include "imath.h" #include "irendertool.h" #include #include #include #include using namespace iParameter; iOverlayHelper* iOverlayHelper::New(iRenderTool *rt) { IERROR_ASSERT(rt); return new iOverlayHelper(rt); } iOverlayHelper::iOverlayHelper(iRenderTool *rt) : mRenderTool(rt) { mIsAutoColor = true; mFontFactor = 1.0f; } iOverlayHelper::~iOverlayHelper() { } const iColor& iOverlayHelper::GetColor(vtkViewport* viewport) { if(mIsAutoColor && viewport!=0) { int i; double bg[3]; viewport->GetBackground(bg); for(i=0; i<3; i++) bg[i] = 1.0 - bg[i]; wColor = iColor(bg); } else { wColor = mFixedColor; } return wColor; } int iOverlayHelper::GetRenderingMagnification() const { return mRenderTool->GetRenderingMagnification(); } void iOverlayHelper::ComputePositionShiftsUnderMagnification(int winij[2]) { int mag = mRenderTool->GetRenderingMagnification(); // // Compute position shifts if under magnification // if(mag > 1) { mRenderTool->GetMagnifier()->GetTile(winij[0],winij[1]); } else winij[0] = winij[1] = 0; } vtkCamera* iOverlayHelper::GetCamera(vtkViewport *vp) const { vtkRenderer *ren = vtkRenderer::SafeDownCast(vp); if(ren == 0) return 0; else return ren->GetActiveCamera(); } int iOverlayHelper::GetFontSize(vtkViewport *vp, float factor) const { float v = factor*16*mFontFactor*exp(0.3*mRenderTool->GetFontScale())/480; vtkRenderer *ren = vtkRenderer::SafeDownCast(vp); if(ren != 0) { if(ren->GetActiveCamera()->GetUseHorizontalViewAngle() != 0) { return round(v*vp->GetSize()[0]); } else { return round(v*vp->GetSize()[1]); } } else return round(v*480); } void iOverlayHelper::UpdateTextProperty(vtkViewport *vp, vtkTextProperty *prop) { #ifdef I_CHECK1 int mag = mRenderTool->GetRenderingMagnification(); if(mag > 1) { IERROR_LOW("Extra call to iOverlayHelper::UpdateTextProperty"); } #endif if(prop != 0) { switch(mRenderTool->GetFontType()) { case TextType::Arial: { prop->SetFontFamilyToArial(); mFontFactor = 1.0; break; } case TextType::Courier: { prop->SetFontFamilyToCourier(); mFontFactor = 1.2; break; } case TextType::Times: { prop->SetFontFamilyToTimes(); mFontFactor = 1.0; break; } } prop->ItalicOff(); prop->ShadowOn(); prop->SetColor(this->GetColor(vp).ToVTK()); } } ifrit-3.4.2/core/ioverlayhelper.h0000644000175700010010000000505612167404415015347 0ustar HomeNone/*========================================================================= Program: Ionization FRont Interactive Tool (IFRIT) Language: C++ Copyright (c) 2002-2012 Nick Gnedin All rights reserved. This file may be distributed and/or modified under the terms of the GNU General Public License version 2 as published by the Free Software Foundation and appearing in the file LICENSE.GPL included in the packaging of this file. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHORS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. =========================================================================*/ // // A helper class for all 2D objects; includes basic functionality for working under // magnification. // #ifndef IOVERLAYHELPER_H #define IOVERLAYHELPER_H #include #include "icolor.h" #include "ipointermacro.h" #include class iRenderTool; class vtkCamera; class vtkProperty2D; class vtkTextProperty; class vtkViewport; class iOverlayHelper : public vtkObjectBase { IPOINTER_AS_PART(RenderTool); public: vtkTypeMacro(iOverlayHelper,vtkObjectBase); static iOverlayHelper* New(iRenderTool *rv = 0); int GetFontSize(vtkViewport *vp, float factor = 1.0f) const; void UpdateTextProperty(vtkViewport *vp, vtkTextProperty *prop); vtkCamera* GetCamera(vtkViewport *viewport) const; int GetRenderingMagnification() const; void ComputePositionShiftsUnderMagnification(int winij[2]); void SetFixedColor(const iColor &c){ mFixedColor = c; } inline const iColor& GetFixedColor() const { return mFixedColor; } const iColor& GetColor(vtkViewport* viewport); void SetAutoColor(bool s){ mIsAutoColor = s; } inline bool IsAutoColor() const { return mIsAutoColor; } protected: virtual ~iOverlayHelper(); private: iOverlayHelper(iRenderTool *rv); iColor mFixedColor; bool mIsAutoColor; float mFontFactor; // // Work variable // iColor wColor; }; #endif // IOVERLAYHELPER_H ifrit-3.4.2/core/ipalette.cpp0000755000175700010010000001143412167404433014457 0ustar HomeNone/*========================================================================= Program: Ionization FRont Interactive Tool (IFRIT) Language: C++ Copyright (c) 2002-2012 Nick Gnedin All rights reserved. This file may be distributed and/or modified under the terms of the GNU General Public License version 2 as published by the Free Software Foundation and appearing in the file LICENSE.GPL included in the packaging of this file. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHORS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. =========================================================================*/ #include "ipalette.h" #include "ierror.h" #include "iimage.h" #include "imath.h" #include "ipiecewisefunction.h" #include #include // // Templates // #include "iarraytemplate.h" // // Implementation of iPalette class // iPalette::iPalette() { mName = "empty"; mCTF[0] = vtkColorTransferFunction::New(); IERROR_ASSERT(mCTF[0]); mCTF[1] = vtkColorTransferFunction::New(); IERROR_ASSERT(mCTF[1]); mLT[0] = vtkLookupTable::New(); IERROR_ASSERT(mLT[0]); mLT[1] = vtkLookupTable::New(); IERROR_ASSERT(mLT[1]); mFun[0] = iPiecewiseFunction::New(); IERROR_ASSERT(mFun[0]); mFun[1] = iPiecewiseFunction::New(); IERROR_ASSERT(mFun[1]); mFun[2] = iPiecewiseFunction::New(); IERROR_ASSERT(mFun[2]); mCTF[0]->SetColorSpaceToRGB(); mCTF[1]->SetColorSpaceToRGB(); mLT[0]->SetNumberOfTableValues(256); mLT[1]->SetNumberOfTableValues(256); // // Image representation // mImage = new iImage(3); IERROR_ASSERT(mImage); mImageNeedsUpdate = true; mImageWidth = 256; mImageHeight = 32; } iPalette::~iPalette() { delete mImage; mCTF[0]->Delete(); mCTF[1]->Delete(); mLT[0]->Delete(); mLT[1]->Delete(); mFun[0]->Delete(); mFun[1]->Delete(); mFun[2]->Delete(); } void iPalette::SetComponents(const iPiecewiseFunction *r, const iPiecewiseFunction *g, const iPiecewiseFunction *b) { if(r != 0) mFun[0]->Copy(r); if(g != 0) mFun[1]->Copy(g); if(b != 0) mFun[2]->Copy(b); this->Update(); } iColor iPalette::GetColor(int n) const { n = ( n < 0 ) ? 0 : n; n = ( n > 255 ) ? 255 : n; float x = (float)n/255.0; float r = mFun[0]->GetValue(x); float g = mFun[1]->GetValue(x); float b = mFun[2]->GetValue(x); return iColor(round(255.0*r),round(255.0*g),round(255.0*b)); } void iPalette::Update() { int i, ir, ig, ib; float x; // // Update vtkColorTransferFunction // mCTF[0]->RemoveAllPoints(); mCTF[1]->RemoveAllPoints(); ir = ig = ib = 0; while(irN() && igN() && ibN()) { x = mFun[0]->X(ir); if(x > mFun[1]->X(ig)) x = mFun[1]->X(ig); if(x > mFun[2]->X(ib)) x = mFun[2]->X(ib); mCTF[0]->AddRGBPoint(255.0*x,mFun[0]->GetValue(x),mFun[1]->GetValue(x),mFun[2]->GetValue(x)); mCTF[1]->AddRGBPoint(255.0*(1.0-x),mFun[0]->GetValue(x),mFun[1]->GetValue(x),mFun[2]->GetValue(x)); if(fabs(x-mFun[0]->X(ir)) < 1.0e-4) ir++; if(fabs(x-mFun[1]->X(ig)) < 1.0e-4) ig++; if(fabs(x-mFun[2]->X(ib)) < 1.0e-4) ib++; } // // Update vtkLookupTable // for(i=0; i<256; i++) { x = (float)i/255.0; mLT[0]->SetTableValue(i,mFun[0]->GetValue(x),mFun[1]->GetValue(x),mFun[2]->GetValue(x)); mLT[1]->SetTableValue(255-i,mFun[0]->GetValue(x),mFun[1]->GetValue(x),mFun[2]->GetValue(x)); } mImageNeedsUpdate = true; } void iPalette::Copy(iPalette *p) { mFun[0]->Copy(p->mFun[0]); mFun[1]->Copy(p->mFun[1]); mFun[2]->Copy(p->mFun[2]); mName = p->mName; this->Update(); } const iImage* iPalette::GetImage() { if(mImageNeedsUpdate) { mImageNeedsUpdate = false; // // Update the image // mImage->Scale(mImageWidth,mImageHeight); unsigned char *dPtr = mImage->DataPointer(); int i; float x; unsigned char r, g, b; // // Fill first row // for(i=0; iGetValue(x))); g = char(round(255.0*mFun[1]->GetValue(x))); b = char(round(255.0*mFun[2]->GetValue(x))); dPtr[3*i+0] = r; dPtr[3*i+1] = g; dPtr[3*i+2] = b; } // // Copy to the rest of rows // for(i=1; i=0 && n<3) ? mFun[n] : 0; } inline const iPiecewiseFunction* const * GetComponents() const { return mFun; } void Update(); private: inline vtkLookupTable* GetLookupTable(bool reverse) const { return mLT[reverse?1:0]; } inline vtkColorTransferFunction* GetColorTransferFunction(bool reverse) const { return mCTF[reverse?1:0]; } iString mName; iPiecewiseFunction *mFun[3]; vtkColorTransferFunction *mCTF[2]; vtkLookupTable *mLT[2]; int mImageWidth, mImageHeight; bool mImageNeedsUpdate; iImage *mImage; }; #endif // IPALETTE_H ifrit-3.4.2/core/ipaletteset.cpp0000755000175700010010000002537112167404433015200 0ustar HomeNone/*========================================================================= Program: Ionization FRont Interactive Tool (IFRIT) Language: C++ Copyright (c) 2002-2012 Nick Gnedin All rights reserved. This file may be distributed and/or modified under the terms of the GNU General Public License version 2 as published by the Free Software Foundation and appearing in the file LICENSE.GPL included in the packaging of this file. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHORS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. =========================================================================*/ #include "ipaletteset.h" #include "ipalette.h" #include "ipointer.h" #include "ipiecewisefunction.h" #include "istring.h" // // templates // #include "iarraytemplate.h" IOBJECT_DEFINE_TYPE(iPaletteSet,PaletteSet,-ps,iObjectType::_Helper); IOBJECT_DEFINE_KEY(iPaletteSet,Palette,-p,Any,0); IOBJECT_DEFINE_KEY(iPaletteSet,Red,-r,Any,1); IOBJECT_DEFINE_KEY(iPaletteSet,Green,-g,Any,1); IOBJECT_DEFINE_KEY(iPaletteSet,Blue,-b,Any,1); // // Helper functions hidden in a private namespace // namespace iPaletteSet_Private { int Decode(int id, bool &r) { if(id < 0) { r = true; return -id - 1; } else { r = false; return id - 1; } } }; using namespace iPaletteSet_Private; // // Main class // iPaletteSet* iPaletteSet::New() { return new iPaletteSet; } iPaletteSet::iPaletteSet() : iObject("PaletteSet") { this->CreateDefaultPalettes(); } iPaletteSet::~iPaletteSet() { int i; for(i=0; i self; return self; } iPalette* iPaletteSet::GetPalette(int n) const { if(n>=0 && n=0 && nGetLookupTable(r); else return 0; } vtkColorTransferFunction* iPaletteSet::GetColorTransferFunction(int id) const { bool r; int n = Decode(id,r); if(n>=0 && nGetColorTransferFunction(r); else return 0; } bool iPaletteSet::AddEmptyPalette() { iPalette *tmp = new iPalette; if(tmp == 0) return false; mList.Add(tmp); return true; } // // Saving and restoring the state // void iPaletteSet::PackStateBody(iString &s) const { int i; // // Save the palettes // this->PackValue(s,iPaletteSet::KeyPalette(),mList.Size()); for(i=0; iPackValuePalette(s,mList[i]); } } void iPaletteSet::UnPackStateBody(const iString &s) { /* if(ws == "Palette") { k = line.Section(" ",1,1).ToInt(ok); if(!ok) return Error(F); ok = true; if(k<0 || k>=100000) ok = false; // // Do not read reversed palettes saved under CompatibilityMode=11 // if(CompatibilityMode==11 && line.Section(" ",2,2).Section("/",0,0).Find("*reversed")>-1) ok = false; while(k>=mPalList.Size() && ok) { ok = this->AddEmptyPalette(); } if(ok) { ws = line.Section(" ",2); if(!this->UnPackValuePalette(ws,mPalList[k])) return Error(F); } } */ } void iPaletteSet::PackValuePalette(iString &s, const iPalette *p) const { s = p->GetName().Substitute(" ","*") + iObjectKey::FieldSeparator(); this->PackValuePiecewiseFunction(s,KeyPalette(),p->GetComponents(),3); } bool iPaletteSet::UnPackValuePalette(const iString &s, iPalette *p) { bool ok = true; iString ws; ws = s.Section(iObjectKey::FieldSeparator(),0,0); ws.Replace("*"," "); if(!ws.IsEmpty()) p->SetName(ws); else ok = false; if(ok) { ws = s.Section(iObjectKey::FieldSeparator(),1); iPiecewiseFunction **c = p->GetComponents(); ok = this->UnPackValuePiecewiseFunction(ws,KeyPalette(),c,3); if(!ok) { // // Try the deprecated form // ok = this->UnPackValuePiecewiseFunction(ws,KeyRed(),c[0]) && this->UnPackValuePiecewiseFunction(ws,KeyGreen(),c[1]) && this->UnPackValuePiecewiseFunction(ws,KeyBlue(),c[2]); } if(ok) p->Update(); } return ok; } void iPaletteSet::CreateDefaultPalettes() { iPalette* tmp; iPiecewiseFunction *r, *g, *b; tmp = new iPalette; IERROR_ASSERT(tmp); tmp->SetName("Rainbow"); r = tmp->GetComponents()[0]; g = tmp->GetComponents()[1]; b = tmp->GetComponents()[2]; r->MovePoint(0,0.0,0.0); g->MovePoint(0,0.0,0.0); b->MovePoint(0,0.0,0.1); r->MovePoint(1,1.0,1.0); g->MovePoint(1,1.0,0.9); b->MovePoint(1,1.0,0.9); r->AddPoint(1.0/6.0,0.0); g->AddPoint(1.0/6.0,0.0); b->AddPoint(1.0/6.0,1.0); r->AddPoint(2.0/6.0,0.0); g->AddPoint(2.0/6.0,1.0); b->AddPoint(2.0/6.0,1.0); r->AddPoint(3.0/6.0,0.0); g->AddPoint(3.0/6.0,1.0); b->AddPoint(3.0/6.0,0.0); r->AddPoint(4.0/6.0,1.0); g->AddPoint(4.0/6.0,1.0); b->AddPoint(4.0/6.0,0.0); r->AddPoint(5.0/6.0,1.0); g->AddPoint(5.0/6.0,0.0); b->AddPoint(5.0/6.0,0.0); tmp->Update(); mList.Add(tmp); tmp = new iPalette; IERROR_ASSERT(tmp); tmp->SetName("Temperature"); r = tmp->GetComponents()[0]; g = tmp->GetComponents()[1]; b = tmp->GetComponents()[2]; r->MovePoint(0,0.0,0.3); g->MovePoint(0,0.0,0.0); b->MovePoint(0,0.0,0.0); r->MovePoint(1,1.0,1.0); g->MovePoint(1,1.0,0.8); b->MovePoint(1,1.0,0.8); r->AddPoint(0.7,1.0); g->AddPoint(0.6,0.0); b->AddPoint(0.8,0.0); tmp->Update(); mList.Add(tmp); tmp = new iPalette; IERROR_ASSERT(tmp); tmp->SetName("Greyscale"); r = tmp->GetComponents()[0]; g = tmp->GetComponents()[1]; b = tmp->GetComponents()[2]; r->MovePoint(0,0.0,0.0); g->MovePoint(0,0.0,0.0); b->MovePoint(0,0.0,0.0); r->MovePoint(1,1.0,1.0); g->MovePoint(1,1.0,1.0); b->MovePoint(1,1.0,1.0); tmp->Update(); mList.Add(tmp); tmp = new iPalette; IERROR_ASSERT(tmp); tmp->SetName("Blue-white"); r = tmp->GetComponents()[0]; g = tmp->GetComponents()[1]; b = tmp->GetComponents()[2]; r->MovePoint(0,0.0,0.0); g->MovePoint(0,0.0,0.0); b->MovePoint(0,0.0,0.1); r->MovePoint(1,1.0,0.9); g->MovePoint(1,1.0,0.9); b->MovePoint(1,1.0,1.0); r->AddPoint(0.75,0.0); g->AddPoint(0.38,0.0); b->AddPoint(0.78,1.0); tmp->Update(); mList.Add(tmp); tmp = new iPalette; IERROR_ASSERT(tmp); tmp->SetName("Prizm"); r = tmp->GetComponents()[0]; g = tmp->GetComponents()[1]; b = tmp->GetComponents()[2]; r->MovePoint(0,0.0,0.0); g->MovePoint(0,0.0,0.0); b->MovePoint(0,0.0,0.0); r->MovePoint(1,1.0,0.0); g->MovePoint(1,1.0,0.0); b->MovePoint(1,1.0,0.0); r->AddPoint(0.25,1.0); g->AddPoint(0.25,0.0); b->AddPoint(0.25,0.0); r->AddPoint(0.50,0.0); g->AddPoint(0.50,1.0); b->AddPoint(0.50,0.0); r->AddPoint(0.75,0.0); g->AddPoint(0.75,0.0); b->AddPoint(0.75,1.0); tmp->Update(); mList.Add(tmp); tmp = new iPalette; IERROR_ASSERT(tmp); tmp->SetName("Green-white"); r = tmp->GetComponents()[0]; g = tmp->GetComponents()[1]; b = tmp->GetComponents()[2]; r->MovePoint(0,0.0,0.0); g->MovePoint(0,0.0,0.1); b->MovePoint(0,0.0,0.0); r->MovePoint(1,1.0,1.0); g->MovePoint(1,1.0,1.0); b->MovePoint(1,1.0,1.0); r->AddPoint(0.375,0.0); b->AddPoint(0.750,0.0); tmp->Update(); mList.Add(tmp); tmp = new iPalette; IERROR_ASSERT(tmp); tmp->SetName("Blue-red"); r = tmp->GetComponents()[0]; g = tmp->GetComponents()[1]; b = tmp->GetComponents()[2]; r->MovePoint(0,0.0,0.0); g->MovePoint(0,0.0,0.0); b->MovePoint(0,0.0,0.0); r->MovePoint(1,1.0,1.0); g->MovePoint(1,1.0,0.0); b->MovePoint(1,1.0,0.0); r->AddPoint(0.25,0.0); g->AddPoint(0.25,1.0); b->AddPoint(0.25,1.0); r->AddPoint(0.5,0.0); g->AddPoint(0.5,0.0); b->AddPoint(0.5,1.0); r->AddPoint(0.75,1.0); g->AddPoint(0.75,0.0); b->AddPoint(0.75,1.0); tmp->Update(); mList.Add(tmp); tmp = new iPalette; IERROR_ASSERT(tmp); tmp->SetName("Stern"); r = tmp->GetComponents()[0]; g = tmp->GetComponents()[1]; b = tmp->GetComponents()[2]; r->MovePoint(0,0.0,0.0); g->MovePoint(0,0.0,0.0); b->MovePoint(0,0.0,0.0); r->MovePoint(1,1.0,1.0); g->MovePoint(1,1.0,1.0); b->MovePoint(1,1.0,1.0); r->AddPoint(0.05,1.0); r->AddPoint(0.25,0.0); b->AddPoint(0.50,1.0); b->AddPoint(0.75,0.0); tmp->Update(); mList.Add(tmp); tmp = new iPalette; IERROR_ASSERT(tmp); tmp->SetName("Haze"); r = tmp->GetComponents()[0]; g = tmp->GetComponents()[1]; b = tmp->GetComponents()[2]; r->MovePoint(0,0.0,1.0); g->MovePoint(0,0.0,0.8); b->MovePoint(0,0.0,1.0); r->MovePoint(1,1.0,1.0); g->MovePoint(1,1.0,0.8); b->MovePoint(1,1.0,0.0); r->AddPoint(0.5,0.0); g->AddPoint(0.5,0.1); b->AddPoint(0.5,0.5); tmp->Update(); mList.Add(tmp); tmp = new iPalette; IERROR_ASSERT(tmp); tmp->SetName("Starlight"); r = tmp->GetComponents()[0]; g = tmp->GetComponents()[1]; b = tmp->GetComponents()[2]; r->MovePoint(0,0.0,0.5); g->MovePoint(0,0.0,0.0); b->MovePoint(0,0.0,0.0); r->MovePoint(1,1.0,1.0); g->MovePoint(1,1.0,1.0); b->MovePoint(1,1.0,0.7); r->AddPoint(0.5,0.9); g->AddPoint(0.5,0.7); b->AddPoint(0.5,0.2); tmp->Update(); mList.Add(tmp); tmp = new iPalette; IERROR_ASSERT(tmp); tmp->SetName("3 color"); r = tmp->GetComponents()[0]; g = tmp->GetComponents()[1]; b = tmp->GetComponents()[2]; r->MovePoint(0,0.0,1.0); g->MovePoint(0,0.0,0.0); b->MovePoint(0,0.0,0.0); r->MovePoint(1,1.0,0.0); g->MovePoint(1,1.0,0.0); b->MovePoint(1,1.0,1.0); r->AddPoint(0.3333,1.0); g->AddPoint(0.3333,0.0); b->AddPoint(0.3333,0.0); r->AddPoint(0.3334,0.0); g->AddPoint(0.3334,1.0); b->AddPoint(0.3334,0.0); r->AddPoint(0.6666,0.0); g->AddPoint(0.6666,1.0); b->AddPoint(0.6666,0.0); r->AddPoint(0.6667,0.0); g->AddPoint(0.6667,0.0); b->AddPoint(0.6667,1.0); tmp->Update(); mList.Add(tmp); tmp = new iPalette; IERROR_ASSERT(tmp); tmp->SetName("4 color"); r = tmp->GetComponents()[0]; g = tmp->GetComponents()[1]; b = tmp->GetComponents()[2]; r->MovePoint(0,0.0,1.0); g->MovePoint(0,0.0,0.0); b->MovePoint(0,0.0,0.0); r->MovePoint(1,1.0,0.0); g->MovePoint(1,1.0,0.0); b->MovePoint(1,1.0,1.0); r->AddPoint(0.249,1.0); g->AddPoint(0.249,0.0); b->AddPoint(0.249,0.0); r->AddPoint(0.250,1.0); g->AddPoint(0.250,1.0); b->AddPoint(0.250,0.0); r->AddPoint(0.499,1.0); g->AddPoint(0.499,1.0); b->AddPoint(0.499,0.0); r->AddPoint(0.500,0.0); g->AddPoint(0.500,1.0); b->AddPoint(0.500,0.0); r->AddPoint(0.749,0.0); g->AddPoint(0.749,1.0); b->AddPoint(0.749,0.0); r->AddPoint(0.750,0.0); g->AddPoint(0.750,0.0); b->AddPoint(0.750,1.0); tmp->Update(); mList.Add(tmp); } ifrit-3.4.2/core/ipaletteset.h0000755000175700010010000000514312167404415014640 0ustar HomeNone/*========================================================================= Program: Ionization FRont Interactive Tool (IFRIT) Language: C++ Copyright (c) 2002-2012 Nick Gnedin All rights reserved. This file may be distributed and/or modified under the terms of the GNU General Public License version 2 as published by the Free Software Foundation and appearing in the file LICENSE.GPL included in the packaging of this file. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHORS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. =========================================================================*/ #ifndef IPALETTESET_H #define IPALETTESET_H #include "iobject.h" #include "iarray.h" class iPalette; class vtkColorTransferFunction; class vtkLookupTable; // // We inherit from iObejct to get access to state saving // class iPaletteSet : public iObject { public: vtkTypeMacro(iPaletteSet,iObject); static iPaletteSet* New(); static const iObjectType& Type(); // // Default set, available everywhere // static iPaletteSet* Default(); // // Palette interface // inline int GetNumberOfPalettes() const { return mList.Size(); } iPalette* GetPalette(int n) const; vtkLookupTable* GetLookupTable(int id) const; vtkColorTransferFunction* GetColorTransferFunction(int id) const; bool AddEmptyPalette(); // // Palette packing helpers (not using keys) - internal access for shells etc // void PackValuePalette(iString &s, const iPalette *p) const; bool UnPackValuePalette(const iString &s, iPalette *p); protected: virtual ~iPaletteSet(); virtual void PackStateBody(iString &s) const; virtual void UnPackStateBody(const iString &s); private: iPaletteSet(); void CreateDefaultPalettes(); static const iObjectKey& KeyPalette(); // // Deprecated access // static const iObjectKey& KeyRed(); static const iObjectKey& KeyGreen(); static const iObjectKey& KeyBlue(); // // Palettes // iArray mList; }; #endif // IPALETTESET_H ifrit-3.4.2/core/iparallel.cpp0000644000175700010010000000247212167404433014614 0ustar HomeNone/*========================================================================= Program: Ionization FRont Interactive Tool (IFRIT) Language: C++ Copyright (c) 2002-2012 Nick Gnedin All rights reserved. This file may be distributed and/or modified under the terms of the GNU General Public License version 2 as published by the Free Software Foundation and appearing in the file LICENSE.GPL included in the packaging of this file. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHORS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. =========================================================================*/ #include "iparallel.h" // // A placeholder for future additions // ifrit-3.4.2/core/iparallel.h0000644000175700010010000000351212167404416014256 0ustar HomeNone/*========================================================================= Program: Ionization FRont Interactive Tool (IFRIT) Language: C++ Copyright (c) 2002-2012 Nick Gnedin All rights reserved. This file may be distributed and/or modified under the terms of the GNU General Public License version 2 as published by the Free Software Foundation and appearing in the file LICENSE.GPL included in the packaging of this file. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHORS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. =========================================================================*/ #ifndef IPARALLEL_H #define IPARALLEL_H // // Misc parallelization tools // namespace iParallel { const unsigned long InformationEvent = 1001; struct ProcessorInfo { int NumProcs; int ThisProc; ProcessorInfo(){ ThisProc = 0; NumProcs = 1; } // Must initialize to serial state!!! }; // // Helpers // template inline void SplitRange(ProcessorInfo &p, T n, T &lbeg, T &lend, T &lstp) { lstp = (n+p.NumProcs-1)/p.NumProcs; lbeg = lstp*p.ThisProc; lend = lbeg + lstp; if(p.ThisProc+1 == p.NumProcs) { lend = n; lstp = lend - lbeg; } } }; #endif // IPARALLEL_H ifrit-3.4.2/core/iparallelmanager.cpp0000755000175700010010000001672412167404433016157 0ustar HomeNone/*========================================================================= Program: Ionization FRont Interactive Tool (IFRIT) Language: C++ Copyright (c) 2002-2012 Nick Gnedin All rights reserved. This file may be distributed and/or modified under the terms of the GNU General Public License version 2 as published by the Free Software Foundation and appearing in the file LICENSE.GPL included in the packaging of this file. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHORS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. =========================================================================*/ #include "iparallelmanager.h" #include "iarray.h" #include "ierror.h" #include "ieventobserver.h" #include "iparallel.h" #include "iparallelworker.h" #include "iviewmodule.h" #include #ifdef VTK_USE_PARALLEL #include #endif #include #if defined(I_DEBUG) #include "icontrolmodule.h" #include "ishell.h" #endif // // Templates // #include "iarraytemplate.h" using namespace iParallel; #ifdef I_DEBUG int iParallelManager::DebugSwitch = 0; #endif // // Helper classes // class iParallelTimer { public: iParallelTimer() { mClock = vtkTimerLog::New(); IERROR_ASSERT(mClock); mValue = 0.0; } ~iParallelTimer() { mClock->Delete(); } void Reset() { mValue = 0.0; } void Start() { mClock->StartTimer(); } void Stop() { mClock->StopTimer(); mValue += mClock->GetElapsedTime(); } double GetValue() const { return mValue; } private: vtkTimerLog *mClock; double mValue; }; class iParallelHelper { public: iParallelHelper() { mWallTimer = 0; } virtual ~iParallelHelper() { int i; if(mWallTimer != 0) delete mWallTimer; for(i=0; iGetMinMax(minnp,maxnp); mWallTimer = new iParallelTimer; IERROR_ASSERT(mWallTimer); iParallelTimer *tmp; while(mProcTimers.Size() < maxnp) { tmp = new iParallelTimer; IERROR_ASSERT(tmp); mProcTimers.Add(tmp); } } void ResetMaxNumProcs(int &n) { this->SetNumProcs(n); iParallelTimer *tmp; while(mProcTimers.Size() < n) { tmp = new iParallelTimer; IERROR_ASSERT(tmp); mProcTimers.Add(tmp); } while(mProcTimers.Size() > n) delete mProcTimers.RemoveLast(); } void StartTimers() { int i; for(i=0; iReset(); if(mWallTimer != 0) { mWallTimer->Reset(); mWallTimer->Start(); } } bool StopTimers() { if(mWallTimer != 0) mWallTimer->Stop(); if(mProcTimers[0] != 0) return (mProcTimers[0]->GetValue() > 0.01); else return false; } double GetProcessorExecutionTime(int n) const { if(n>=0 && nGetValue(); else return 0.0; } double GetWallClockExecutionTime() const { if(mWallTimer != 0) return mWallTimer->GetValue(); else return 0.0; } int ExecuteWorkerInParallel(iParallelWorker *worker, ProcessorInfo &p) { if(worker!=0 && p.NumProcs<=mProcTimers.Size() && p.ThisProc>=0 && p.ThisProcStart(); int ret = worker->ExecuteInternal(p); mProcTimers[p.ThisProc]->Stop(); return ret; } else return 1; } virtual void GetMinMax(int &minnp, int &maxnp) = 0; virtual void SetNumProcs(int &np) = 0; virtual int ExecuteWorker(iParallelWorker *worker) = 0; protected: iArray mProcTimers; iParallelTimer *mWallTimer; }; // // Private namespace with actual helpers // namespace iParallelManager_Private { #ifdef VTK_USE_PARALLEL class SharedMemoryHelper : public iParallelHelper { public: SharedMemoryHelper() { mExec = vtkMultiThreader::New(); IERROR_ASSERT(mExec); } virtual ~SharedMemoryHelper() { mExec->Delete(); } virtual void GetMinMax(int &minnp, int &maxnp) { minnp = 1; maxnp = mExec->GetGlobalDefaultNumberOfThreads(); } virtual void SetNumProcs(int &np) { mExec->SetNumberOfThreads(np); np = mExec->GetNumberOfThreads(); } virtual int ExecuteWorker(iParallelWorker *worker) { Data d; d.Self = this; d.Worker = worker; d.Value = 0; if(worker != 0) { mExec->SetSingleMethod(MySingleMethod,&d); mExec->SingleMethodExecute(); } return d.Value; } static VTK_THREAD_RETURN_TYPE MySingleMethod(void *input) { if(input != 0) { vtkMultiThreader::ThreadInfo *ti = (vtkMultiThreader::ThreadInfo * )input; Data *d = (Data * )ti->UserData; if(d != 0) { ProcessorInfo p; p.NumProcs = ti->NumberOfThreads; p.ThisProc = ti->ThreadID; d->Value = d->Self->ExecuteWorkerInParallel(d->Worker,p); } } return VTK_THREAD_RETURN_VALUE; } protected: struct Data { SharedMemoryHelper *Self; iParallelWorker *Worker; int Value; }; vtkMultiThreader *mExec; }; #endif }; using namespace iParallelManager_Private; iParallelManager* iParallelManager::New(iControlModule *cm) { return new iParallelManager(cm); } iParallelManager::iParallelManager(iControlModule *cm) : mControlModule(cm) { #ifdef VTK_USE_PARALLEL mHelper = new SharedMemoryHelper(); IERROR_ASSERT(mHelper); mHelper->Initialize(mMinNumProcs,mMaxNumProcs); this->SetNumberOfProcessors(1); #if defined(I_DEBUG) iConsole::PrintDebugMessage("Max # of procs: "+iString::FromNumber(mMaxNumProcs)); #endif mCount = 0; #else mNumProcs = mMinNumProcs = mMaxNumProcs = 1; #endif } iParallelManager::~iParallelManager() { #ifdef VTK_USE_PARALLEL delete mHelper; #endif } int iParallelManager::ExecuteWorker(iParallelWorker *worker) { int ret; #ifdef VTK_USE_PARALLEL bool single = (mCount == 0); if(single) this->StartCounters(); if(mNumProcs > 1) { ret = mHelper->ExecuteWorker(worker); } else { #endif ProcessorInfo p; if(worker != 0) ret = worker->ExecuteInternal(p); else ret = 1; #ifdef VTK_USE_PARALLEL } if(single) this->StopCounters(); #endif return ret; } void iParallelManager::SetNumberOfProcessors(int n) { #ifdef VTK_USE_PARALLEL if(n == 0) n = mMaxNumProcs; // auto-set to max available number if(n>0 && n<=mMaxNumProcs) { mNumProcs = n; mHelper->SetNumProcs(mNumProcs); } #endif } double iParallelManager::GetProcessorExecutionTime(int n) const { #ifdef VTK_USE_PARALLEL return mHelper->GetProcessorExecutionTime(n); #else return 0.0; #endif } double iParallelManager::GetWallClockExecutionTime() const { #ifdef VTK_USE_PARALLEL return mHelper->GetWallClockExecutionTime(); #else return 0.0; #endif } void iParallelManager::StartCounters() { #ifdef VTK_USE_PARALLEL if(mCount == 0) { mHelper->StartTimers(); } mCount++; #endif } void iParallelManager::StopCounters() { #ifdef VTK_USE_PARALLEL mCount--; if(mCount == 0) { if(mHelper->StopTimers()) this->InvokeEvent(InformationEvent,0); } #ifdef I_CHECK1 if(mCount < 0) IERROR_LOW("Imbalanced start/stop counters."); #endif #endif } ifrit-3.4.2/core/iparallelmanager.h0000755000175700010010000000440712167404416015620 0ustar HomeNone/*========================================================================= Program: Ionization FRont Interactive Tool (IFRIT) Language: C++ Copyright (c) 2002-2012 Nick Gnedin All rights reserved. This file may be distributed and/or modified under the terms of the GNU General Public License version 2 as published by the Free Software Foundation and appearing in the file LICENSE.GPL included in the packaging of this file. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHORS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. =========================================================================*/ #ifndef IPARALLELMANAGER_H #define IPARALLELMANAGER_H #include #include "ipointermacro.h" class iControlModule; class iParallelHelper; class iParallelUpdateEventObserver; class iParallelWorker; class iParallelManager : public vtkObject { IPOINTER_AS_PART(ControlModule); public: static iParallelManager* New(iControlModule *cm); int ExecuteWorker(iParallelWorker *worker); inline int GetMinNumberOfProcessors() const { return mMinNumProcs; } inline int GetMaxNumberOfProcessors() const { return mMaxNumProcs; } inline int GetNumberOfProcessors() const { return mNumProcs; } void SetNumberOfProcessors(int n); void StartCounters(); void StopCounters(); double GetProcessorExecutionTime(int n) const; double GetWallClockExecutionTime() const; #ifdef I_DEBUG static int DebugSwitch; #endif protected: virtual ~iParallelManager(); private: iParallelManager(iControlModule *cm); int mNumProcs, mMinNumProcs, mMaxNumProcs; int mCount; iParallelHelper *mHelper; }; #endif // IPARALLELMANAGER_H ifrit-3.4.2/core/iparallelworker.cpp0000755000175700010010000000427112167404433016050 0ustar HomeNone/*========================================================================= Program: Ionization FRont Interactive Tool (IFRIT) Language: C++ Copyright (c) 2002-2012 Nick Gnedin All rights reserved. This file may be distributed and/or modified under the terms of the GNU General Public License version 2 as published by the Free Software Foundation and appearing in the file LICENSE.GPL included in the packaging of this file. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHORS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. =========================================================================*/ #include "iparallelworker.h" #include "ierror.h" #include "iparallel.h" #include "iparallelmanager.h" #include "iviewmodule.h" using namespace iParallel; iParallelWorker::iParallelWorker(iParallelManager *pm) { mManager = pm; mSerial = false; } iParallelWorker::~iParallelWorker() { } iParallelManager* iParallelWorker::GetManager() const { return mManager; } int iParallelWorker::ParallelExecute(int step) { int ret = 0; if(mSerial || mManager==0) { ProcessorInfo p; ret = this->ExecuteStep(step,p); } else { wStep = step; ret = mManager->ExecuteWorker(this); } if(ret != 0) IERROR_LOW("Failure in iParallelWorker::ParallelExecute."); return ret; } int iParallelWorker::ExecuteInternal(ProcessorInfo &p) { // // p is guaranteed to have the correct value for ThisProc and NumProcs (0<=ThisProcExecuteStep(wStep,p); } bool iParallelWorker::IsMaster(ProcessorInfo &p) { return p.ThisProc == 0; } ifrit-3.4.2/core/iparallelworker.h0000644000175700010010000000400012167404416015501 0ustar HomeNone/*========================================================================= Program: Ionization FRont Interactive Tool (IFRIT) Language: C++ Copyright (c) 2002-2012 Nick Gnedin All rights reserved. This file may be distributed and/or modified under the terms of the GNU General Public License version 2 as published by the Free Software Foundation and appearing in the file LICENSE.GPL included in the packaging of this file. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHORS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. =========================================================================*/ #ifndef IPARALLELWORKER_H #define IPARALLELWORKER_H namespace iParallel { struct ProcessorInfo; }; class iParallelManager; class iParallelWorker { friend class iParallelHelper; friend class iParallelManager; public: iParallelManager* GetManager() const; void SetExecuteSerially(bool s){ mSerial = s; } inline bool GetExecuteSerially(){ return mSerial; } virtual int ParallelExecute(int step); protected: iParallelWorker(iParallelManager *pp); virtual ~iParallelWorker(); virtual int ExecuteStep(int step, iParallel::ProcessorInfo &p) = 0; bool IsMaster(iParallel::ProcessorInfo &p); bool mSerial; iParallelManager *mManager; private: int wStep; // work variable int ExecuteInternal(iParallel::ProcessorInfo &p); }; #endif // IPARALLELWORKER_H ifrit-3.4.2/core/iparticleconnector.cpp0000755000175700010010000001534012167404433016537 0ustar HomeNone/*========================================================================= Program: Ionization FRont Interactive Tool (IFRIT) Language: C++ Copyright (c) 2002-2012 Nick Gnedin All rights reserved. This file may be distributed and/or modified under the terms of the GNU General Public License version 2 as published by the Free Software Foundation and appearing in the file LICENSE.GPL included in the packaging of this file. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHORS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. =========================================================================*/ #include "iparticleconnector.h" #include "ierror.h" #include "imath.h" #include #include #include #include #include // // Templates // #include "igenericfiltertemplate.h" #define EQTOL 1.001 namespace iParticleConnector_Private { // // Do our own quick sort for efficiency reason (based on a Java code by Denis Ahrens) // #define SAVE(CELL,i1) { itmp = indx[i1]; } #define MOVE(i1,i2) { indx[i1] = indx[i2]; } #define RESTORE(i2,CELL) { indx[i2] = itmp; } #define SWAP(i1,i2) { SAVE(1,i1); MOVE(i1,i2); RESTORE(i2,1); } #define GREATER1(ind1,ind2) (data[mAttCon+nc*ind1]>data[mAttCon+nc*ind2]) #define GREATER2(ind1,ind2) ((data[mAttSep+nc*ind1]>EQTOL*data[mAttSep+nc*ind2])||((EQTOL*data[mAttSep+nc*ind1]>data[mAttSep+nc*ind2])&&(data[mAttCon+nc*ind1]>data[mAttCon+nc*ind2]))) // // Recursive worker // void SortWorker1(iParticleConnector *me, vtkIdType l, vtkIdType r, int nc, int mAttCon, float *data, vtkIdType *indx) { const int M = 8; vtkIdType i, j; vtkIdType v, itmp; if(me->GetAbortExecute()) return; if((r-l) > M) { // // Use quicksort // i = (r+l)/2; if(GREATER1(indx[l],indx[i])) // Tri-Median Method! { SWAP(l,i); } if(GREATER1(indx[l],indx[r])) { SWAP(l,r); } if(GREATER1(indx[i],indx[r])) { SWAP(i,r); } j = r-1; SWAP(i,j); i = l; v = indx[j]; for(;;) { do i++; while(GREATER1(v,indx[i])); // no ++i/--j in macro expansion! do j--; while(GREATER1(indx[j],v)); if(j < i) break; SWAP(i,j); } SWAP(i,r-1); SortWorker1(me,l,j,nc,mAttCon,data,indx); SortWorker1(me,i+1,r,nc,mAttCon,data,indx); } else { // // Array is small, use insertion sort. // for(i=l+1; i<=r; i++) { SAVE(1,i); v = indx[i]; j = i; while(j>l && GREATER1(indx[j-1],v)) { MOVE(j,j-1); j--; } RESTORE(j,1); } } } // // Interface // void Index1(iParticleConnector *me, vtkIdType n, int nc, int mAttCon, float *data, vtkIdType *indx) { vtkIdType j; for(j=0; jGetAbortExecute()) return; if((r-l) > M) { // // Use quicksort // i = (r+l)/2; if(GREATER2(indx[l],indx[i])) // Tri-Median Method! { SWAP(l,i); } if(GREATER2(indx[l],indx[r])) { SWAP(l,r); } if(GREATER2(indx[i],indx[r])) { SWAP(i,r); } j = r-1; SWAP(i,j); i = l; v = indx[j]; for(;;) { do i++; while(GREATER2(v,indx[i])); // no ++i/--j in macro expansion! do j--; while(GREATER2(indx[j],v)); if(j < i) break; SWAP(i,j); } SWAP(i,r-1); SortWorker2(me,l,j,nc,mAttSep,mAttCon,data,indx); SortWorker2(me,i+1,r,nc,mAttSep,mAttCon,data,indx); } else { // // Array is small, use insertion sort. // for(i=l+1; i<=r; i++) { SAVE(1,i); v = indx[i]; j = i; while(j>l && GREATER2(indx[j-1],v)) { MOVE(j,j-1); j--; } RESTORE(j,1); } } } // // Interface // void Index2(iParticleConnector *me, vtkIdType n, int nc, int mAttSep, int mAttCon, float *data, vtkIdType *indx) { vtkIdType j; for(j=0; j(vo,1,true,false) { mAttCon = mAttSep = -1; } void iParticleConnector::SetAttributeToConnect(int a) { if(a>=-1 && a!=mAttCon) { mAttCon = a; this->Modified(); } } void iParticleConnector::SetAttributeToSeparate(int a) { if(a>=-1 && a!=mAttSep) { mAttSep = a; this->Modified(); } } void iParticleConnector::ProduceOutput() { vtkPolyData *input = this->GetInput(); vtkPolyData *output = this->GetOutput(); output->ShallowCopy(input); if(mAttCon==-1 || input->GetPointData()->GetScalars()==0 || mAttSep==mAttCon) return; vtkFloatArray *inAtts = iRequiredCast(INFO,input->GetPointData()->GetScalars()); vtkIdType np = input->GetNumberOfPoints(); vtkIdType nc = inAtts->GetNumberOfComponents(); if(mAttCon<0 || mAttCon>=nc || mAttSep<-1 || mAttSep>=nc) return; vtkCellArray *olin; olin = vtkCellArray::New(); IERROR_ASSERT(olin); vtkIdType id[2]; vtkIdType l; vtkIdType *ind; ind = new vtkIdType[np]; IERROR_ASSERT(ind); float *data = inAtts->GetPointer(0); if(mAttSep == -1) // no separation { Index1(this,np,nc,mAttCon,data,ind); #ifdef I_CHECK2 for(l=0; lUpdateProgress((float)l/np); if(this->GetAbortExecute()) break; } id[0] = ind[l]; id[1] = ind[l+1]; olin->InsertNextCell(2,id); } } else { Index2(this,np,nc,mAttSep,mAttCon,data,ind); #ifdef I_CHECK2 for(l=0; lUpdateProgress((float)l/np); if(this->GetAbortExecute()) break; } if(data[mAttSep+nc*ind[l]]*EQTOL > data[mAttSep+nc*ind[l+1]]) { id[0] = ind[l]; id[1] = ind[l+1]; olin->InsertNextCell(2,id); } } } delete [] ind; output->SetLines(olin); olin->Delete(); } ifrit-3.4.2/core/iparticleconnector.h0000755000175700010010000000352312167404416016205 0ustar HomeNone/*========================================================================= Program: Ionization FRont Interactive Tool (IFRIT) Language: C++ Copyright (c) 2002-2012 Nick Gnedin All rights reserved. This file may be distributed and/or modified under the terms of the GNU General Public License version 2 as published by the Free Software Foundation and appearing in the file LICENSE.GPL included in the packaging of this file. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHORS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. =========================================================================*/ #ifndef IPARTICLECONNECTOR_H #define IPARTICLECONNECTOR_H #include "igenericfilter.h" #include class iParticleConnector : public iGenericPolyDataToPolyDataFilter { IGENERICFILTER_DECLARE(iParticleConnector,vtkPolyDataToPolyDataFilter); public: inline int GetAttributeToConnect(){ return mAttCon; } virtual void SetAttributeToConnect(int a); inline int GetAttributeToSeparate(){ return mAttSep; } virtual void SetAttributeToSeparate(int a); protected: virtual void ProduceOutput(); private: int mAttCon, mAttSep; }; #endif ifrit-3.4.2/core/iparticledataconverter.cpp0000755000175700010010000003011112167404433017377 0ustar HomeNone/*========================================================================= Program: Ionization FRont Interactive Tool (IFRIT) Language: C++ Copyright (c) 2002-2012 Nick Gnedin All rights reserved. This file may be distributed and/or modified under the terms of the GNU General Public License version 2 as published by the Free Software Foundation and appearing in the file LICENSE.GPL included in the packaging of this file. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHORS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. =========================================================================*/ #include "iparticledataconverter.h" #include "idatalimits.h" #include "idatastretch.h" #include "ierror.h" #include "ifunctionmapping.h" #include "imath.h" #include "iparticlegroup.h" #include "ipiecewisefunction.h" #include "ipointglyph.h" #include "iviewmodule.h" #include #include #include #include #include #include #include #include // // Templates (needed for some compilers) // #include "iarraytemplate.h" #include "igenericfiltertemplate.h" using namespace iParameter; iParticleDataConverter::iParticleDataConverter(iViewSubject *vo) : iGenericPolyDataToPolyDataFilter(vo,1,true,true) { mSize = 0.005; mPoint = iPointGlyph::New(vo); IERROR_ASSERT(mPoint); this->SetType(PointGlyphType::Point); } iParticleDataConverter::~iParticleDataConverter() { mPoint->Delete(); } int iParticleDataConverter::GetType() const { return mPoint->GetType(); } void iParticleDataConverter::SetType(int t) { mPoint->SetType(t); this->Modified(); } void iParticleDataConverter::SetSize(float s) { if(s>0.0 && s<1000.1) { mSize = 0.005*s; this->Modified(); } } void iParticleDataConverter::ProduceOutput() { int i, j; vtkIdType lp, lv; vtkIdType nCell1, *pCell1, pCell2[999]; double x0[3], x1[3], x2[3]; vtkPolyData *input = this->GetInput(); vtkPolyData *output = this->GetOutput(); output->ShallowCopy(input); if(mPoint->GetType() == PointGlyphType::Point) return; vtkPoints *inpPnts = input->GetPoints(); if(inpPnts == 0) return; vtkCellArray *inpVrts = input->GetVerts(); if(inpVrts == 0) return; // // Direct access to the input data // vtkIdType nInpVrts = inpVrts->GetNumberOfCells(); vtkIdType nInpPnts = inpPnts->GetNumberOfPoints(); if(nInpVrts<=0 || nInpPnts<=0) return; int sop; switch(inpPnts->GetDataType()) { case VTK_FLOAT: { sop = sizeof(float); break; } case VTK_DOUBLE: { sop = sizeof(double); break; } default: return; } // // Direct access to the glyph data // mPoint->Update(); vtkPoints *srcPnts = mPoint->GetOutput()->GetPoints(); if(srcPnts->GetDataType() != VTK_FLOAT) { vtkErrorMacro("Source points are not floats."); return; } float *srcPntsArr = (float *)srcPnts->GetVoidPointer(0); bool srcCellPoly = true; vtkCellArray *srcClls = mPoint->GetOutput()->GetPolys(); if(srcClls==0 || srcClls->GetNumberOfCells()==0) { srcClls = mPoint->GetOutput()->GetVerts(); srcCellPoly = false; } if(srcClls==0 || srcClls->GetNumberOfCells()==0) { vtkErrorMacro("Incorrect input to iParticleDataConverter"); return; } int sSrcNmls = 0; vtkFloatArray *srcNmls = 0; if(mPoint->GetOutput()->GetPointData()->GetNormals() != 0) { srcNmls = iRequiredCast(INFO,mPoint->GetOutput()->GetPointData()->GetNormals()); sSrcNmls = 1; } else if(mPoint->GetOutput()->GetCellData()->GetNormals() != 0) { srcNmls = iRequiredCast(INFO,mPoint->GetOutput()->GetCellData()->GetNormals()); sSrcNmls = -1; } float *srcNmlsArr = 0; if(srcNmls != 0) srcNmlsArr = (float *)srcNmls->GetVoidPointer(0); vtkIdType nSrcPnts = srcPnts->GetNumberOfPoints(); vtkIdType nSrcClls = srcClls->GetNumberOfCells(); vtkIdType nSrcCellMax = srcClls->GetMaxCellSize(); bool rotate = mPoint->GetOriented(); bool orient = false; // // Check if lines specified too // vtkIdType nOutPntsOff = 0; vtkCellArray *inpLins = 0; float *inpPntsDir = 0; if(input->GetLines()!=0 && input->GetLines()->GetNumberOfCells()>0) { inpLins = input->GetLines(); nOutPntsOff = nInpPnts; // // If lines are present, arrows and cones are oriented along the lines // if(mPoint->GetType()==PointGlyphType::Cone || mPoint->GetType()==PointGlyphType::Arrow) { orient = true; inpPntsDir = new float[3*nInpPnts]; if(inpPntsDir == 0) { vtkErrorMacro("There is not enough memory to convert the particle set data"); return; } memset(inpPntsDir,0,3*nInpPnts*sizeof(float)); inpLins->InitTraversal(); while(inpLins->GetNextCell(nCell1,pCell1) != 0) { #ifdef I_CHECK1 if(nCell1 != 2) { IERROR_LOW("Line contains more than 2 points!"); break; } #endif inpPnts->GetPoint(pCell1[0],x1); inpPnts->GetPoint(pCell1[1],x2); for(j=0; j<3; j++) { x0[j] = x2[j] - x1[j]; } vtkMath::Normalize(x0); for(j=0; j<3; j++) { inpPntsDir[3*pCell1[0]+j] += x0[j]; inpPntsDir[3*pCell1[1]+j] += x0[j]; } } for(lp=0; lpGetDataType()); IERROR_ASSERT(outPnts); vtkCellArray *outClls = vtkCellArray::New(); IERROR_ASSERT(outClls); // // Allocates and Sets MaxId // outPnts->SetNumberOfPoints(nOutPnts); // // If not enough memory - revert to points // if(outPnts->GetVoidPointer(0)==0 || outClls->Allocate(outClls->EstimateSize(nOutClls,nSrcCellMax))==0) { if(inpPntsDir != 0) delete [] inpPntsDir; outPnts->Delete(); outClls->Delete(); vtkErrorMacro("There is not enough memory to convert the particle set data"); return; } // // Output normals // vtkFloatArray *outNmls = vtkFloatArray::New(); IERROR_ASSERT(outNmls); outNmls->SetNumberOfComponents(3); float *outNmlsArr = 0; if(sSrcNmls > 0) { // Allocates and Sets MaxId outNmls->SetNumberOfTuples(nOutPnts); outNmlsArr = (float *)outNmls->GetVoidPointer(0); } else if(sSrcNmls < 0) { // Allocates and Sets MaxId outNmls->SetNumberOfTuples(nOutClls); outNmlsArr = (float *)outNmls->GetVoidPointer(0); } if(sSrcNmls!=0 && outNmlsArr==0) { if(inpPntsDir != 0) delete [] inpPntsDir; outPnts->Delete(); outClls->Delete(); outNmls->Delete(); vtkErrorMacro("There is not enough memory to convert the particle set data"); return; } if(!this->ScalarsInit(input->GetPointData(),nOutPnts)) { outPnts->Delete(); outClls->Delete(); outNmls->Delete(); return; } // // Attributes for scaling // int catt; float cattLo = 0.0, cattHi = 0.0; int cattSt = 0; catt = iRequiredCast(INFO,this->GetViewSubject())->GetAttributeToSize(); if(catt>=0 && this->GetLimits()->GetNumVars()) { iParticleGroup *pg = iRequiredCast(INFO,this->GetViewSubject()); cattSt = pg->GetStretchToSize(); cattLo = iDataStretch::ApplyStretch(pg->GetLowerLimitToSize(),cattSt,false); cattHi = iDataStretch::ApplyStretch(pg->GetUpperLimitToSize(),cattSt,true); } // // Set fixed seed to make sure particles do not jump in an animation // vtkMath::RandomSeed(123456789); // // If lines specified, add original points first // if(nOutPntsOff > 0) { memcpy(outPnts->GetVoidPointer(0),inpPnts->GetVoidPointer(0),nInpPnts*3*sop); if(wScalarDimIn > 0) memcpy(wScalarPtrOut,wScalarPtrIn,nInpPnts*wScalarDimIn*sizeof(float)); if(sSrcNmls != 0) { memset(outNmlsArr,0,nInpPnts*3*sizeof(float)); // for(lp=0; lp(INFO,this->GetViewSubject()); iPiecewiseFunction *pFun = myParticles->GetSizeFunction()->GetFunction(); bool doDirect = myParticles->GetAttributeSizeDirect(); float scale = 2.0*myParticles->GetAttributeSizeExtraFactor(); // // Main loop // double mat[3][3]; double en, e[4]; // Euler quaternion float *s0 = 0, latt; double s, ct, st, cp, sp; vtkIdType llPnts = nOutPntsOff, llClls = 0; outClls->InitTraversal(); inpVrts->InitTraversal(); for(lv=0; lvUpdateProgress((float)lv/nInpVrts); if(this->GetAbortExecute()) break; } inpVrts->GetNextCell(nCell1,pCell1); #ifdef I_CHECK1 if(nCell1 != 1) { IERROR_LOW("Vert contains more than 1 point!"); break; } #endif lp = pCell1[0]; inpPnts->GetPoint(lp,x0); s = mSize; if(wScalarDimIn > 0) { s0 = wScalarPtrIn + wScalarDimIn*lp; if(catt >= 0) { if(doDirect) { // // use the attribute as the precise value of the size scaled by scale // s = scale*s0[catt]; } else { latt = iDataStretch::ApplyStretch(s0[catt],cattSt,false); latt = (latt-cattLo)/(cattHi-cattLo); s *= pFun->GetValue(latt); } } } if(rotate) { if(orient) { ct = inpPntsDir[3*lp+2]; cp = inpPntsDir[3*lp+0]; st = sqrt(1.0-ct*ct); sp = sqrt(1.0-cp*cp); if(inpPntsDir[3*lp+1] < 0.0) sp = -sp; mat[0][0] = ct*cp; mat[1][0] = ct*sp; mat[2][0] = -st; mat[0][1] = -sp; mat[1][1] = cp; mat[2][1] = 0.0; mat[0][2] = st*cp; mat[1][2] = st*sp; mat[2][2] = ct; } else { en = 0.0; for(j=0; j<4; j++) { e[j] = vtkMath::Random(); en += e[j]*e[j]; } en = 1.0/sqrt(en); for(j=0; j<4; j++) e[j] *= en; // // There is a bug in VTK: the quaternion must be normalized, despite the claim to the opposite in the help // vtkMath::QuaternionToMatrix3x3(e,mat); } } srcClls->InitTraversal(); for(i=0; iGetNextCell(nCell1,pCell1); for(j=0; jInsertNextCell(nCell1,pCell2); if(sSrcNmls < 0) // cell normals { for(j=0; j<3; j++) outNmlsArr[3*llClls+j] = srcNmlsArr[3*i+j]; } llClls++; } for(i=0; iSetPoint(llPnts,x1); if(wScalarDimIn > 0) { for(j=0; j 0) // point normals { for(j=0; j<3; j++) outNmlsArr[3*llPnts+j] = srcNmlsArr[3*i+j]; } llPnts++; } } if(inpPntsDir != 0) delete [] inpPntsDir; output->SetPoints(outPnts); outPnts->Delete(); // // remove verts // output->SetVerts(0); if(srcCellPoly) { output->SetPolys(outClls); } else { output->SetVerts(outClls); } outClls->Delete(); this->ScalarsDone(output->GetPointData()); if(sSrcNmls > 0) { output->GetPointData()->SetNormals(outNmls); } else if(sSrcNmls < 0) { output->GetCellData()->SetNormals(outNmls); } else { output->GetPointData()->SetNormals(0); output->GetCellData()->SetNormals(0); } outNmls->Delete(); } float iParticleDataConverter::GetMemorySize() { if(this->GetType() == PointGlyphType::Point) return 0.0; else return this->iGenericPolyDataToPolyDataFilter::GetMemorySize(); } ifrit-3.4.2/core/iparticledataconverter.h0000755000175700010010000000402412167404416017051 0ustar HomeNone/*========================================================================= Program: Ionization FRont Interactive Tool (IFRIT) Language: C++ Copyright (c) 2002-2012 Nick Gnedin All rights reserved. This file may be distributed and/or modified under the terms of the GNU General Public License version 2 as published by the Free Software Foundation and appearing in the file LICENSE.GPL included in the packaging of this file. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHORS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. =========================================================================*/ // // Ifrit data filter: takes PolyData data with only vertices specified and // changes the point symbol. // #ifndef IPARTICLEDATACONVERTER_H #define IPARTICLEDATACONVERTER_H #include "igenericfilter.h" #include class iPointGlyph; class iParticleDataConverter: public iGenericPolyDataToPolyDataFilter { IGENERICFILTER_DECLARE(iParticleDataConverter,vtkPolyDataToPolyDataFilter); public: int GetType() const; inline float GetSize() const { return mSize; } virtual void SetType(int t); virtual void SetSize(float s); virtual float GetMemorySize(); protected: virtual ~iParticleDataConverter(); virtual void ProduceOutput(); private: float mSize; iPointGlyph *mPoint; }; #endif // IPARTICLEDATACONVERTER_H ifrit-3.4.2/core/iparticledatasubject.cpp0000755000175700010010000000733112167404433017037 0ustar HomeNone/*========================================================================= Program: Ionization FRont Interactive Tool (IFRIT) Language: C++ Copyright (c) 2002-2012 Nick Gnedin All rights reserved. This file may be distributed and/or modified under the terms of the GNU General Public License version 2 as published by the Free Software Foundation and appearing in the file LICENSE.GPL included in the packaging of this file. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHORS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. =========================================================================*/ #include "iparticledatasubject.h" #include "idata.h" #include "idatalimits.h" #include "ierror.h" #include "iparticlefileloader.h" #include "iparticleprobefilter.h" // // Templates // #include "iarraytemplate.h" IOBJECT_DEFINE_TYPE(iParticleDataSubject,ParticleData,-dp,iObjectType::_Data); IOBJECT_DEFINE_KEY(iParticleDataSubject,DensityAttribute,ad,OffsetInt,1); IOBJECT_DEFINE_KEY(iParticleDataSubject,OrderIsAttribute,ao,Bool,1); IOBJECT_DEFINE_KEY(iParticleDataSubject,DownsampleFactor,df,Int,1); IOBJECT_DEFINE_KEY(iParticleDataSubject,DownsampleMode,dm,Int,1); IOBJECT_DEFINE_KEY(iParticleDataSubject,TypeIncluded,ti,Bool,1); IOBJECT_DEFINE_KEY(iParticleDataSubject,UseExtras,ue,Bool,1); iParticleDataSubject::iParticleDataSubject(iParticleFileLoader *fl, const iString &name) : iDataSubject(fl,name), mParticleLoader(fl) { } const iObjectType& iParticleDataSubject::GetObjectType() const { return iParticleDataSubject::Type(); } iDataLimits* iParticleDataSubject::CreateLimits() const { return iDataLimits::New(this,3,"Attribute"); } void iParticleDataSubject::DataSubjectPackStateBody(iString &s) const { this->PackValue(s,KeyTypeIncluded(),mParticleLoader->GetTypeIncluded(mId)); this->PackValue(s,KeyDownsampleMode(),mParticleLoader->GetDownsampleMode()); this->PackValue(s,KeyDownsampleFactor(),mParticleLoader->GetDownsampleFactor(mId)); this->PackValue(s,KeyOrderIsAttribute(),mParticleLoader->GetOrderIsAttribute(mId)); this->PackValue(s,KeyDensityAttribute(),mParticleLoader->GetDensityAttribute(mId)); this->PackValue(s,KeyUseExtras(),mParticleLoader->IsUsingExtras()); this->ParticleDataSubjectPackStateBody(s); } void iParticleDataSubject::DataSubjectUnPackStateBody(const iString &s) { int i; bool b; if(this->UnPackValue(s,KeyTypeIncluded(),b)) { mParticleLoader->SetTypeIncluded(mId,b); this->ClearCache(); } if(this->UnPackValue(s,KeyDownsampleMode(),i)) { mParticleLoader->SetDownsampleMode(i); this->ClearCache(); } if(this->UnPackValue(s,KeyDownsampleFactor(),i)) { mParticleLoader->SetDownsampleFactor(mId,i); this->ClearCache(); } if(this->UnPackValue(s,KeyOrderIsAttribute(),b)) { mParticleLoader->SetOrderIsAttribute(mId,b); this->ClearCache(); } if(this->UnPackValue(s,KeyDensityAttribute(),i)) { mParticleLoader->SetDensityAttribute(mId,i); this->ClearCache(); } this->ParticleDataSubjectUnPackStateBody(s); } iProbeFilter* iParticleDataSubject::CreateProbeFilter(iViewSubject *vo) const { return iParticleProbeFilter::New(vo); } ifrit-3.4.2/core/iparticledatasubject.h0000755000175700010010000001116012167404416016500 0ustar HomeNone/*========================================================================= Program: Ionization FRont Interactive Tool (IFRIT) Language: C++ Copyright (c) 2002-2012 Nick Gnedin All rights reserved. This file may be distributed and/or modified under the terms of the GNU General Public License version 2 as published by the Free Software Foundation and appearing in the file LICENSE.GPL included in the packaging of this file. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHORS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. =========================================================================*/ // // A base class for all DataSubjects of particle types. // #ifndef IPARTICLEDATASUBJECT_H #define IPARTICLEDATASUBJECT_H #include "idatasubject.h" class iParticleFileLoader; class iParticleDataSubject : public iDataSubject { friend class iParticleFileLoader; public: vtkTypeMacro(iParticleDataSubject,iDataSubject); static const iObjectType& Type(); virtual const iObjectType& GetObjectType() const; static const iObjectKey& KeyUseExtras(); static const iObjectKey& KeyTypeIncluded(); static const iObjectKey& KeyDownsampleMode(); static const iObjectKey& KeyDownsampleFactor(); static const iObjectKey& KeyOrderIsAttribute(); static const iObjectKey& KeyDensityAttribute(); virtual iProbeFilter* CreateProbeFilter(iViewSubject *vo) const; protected: iParticleDataSubject(iParticleFileLoader *fl, const iString &name); virtual iDataLimits* CreateLimits() const; virtual void DataSubjectPackStateBody(iString &s) const; virtual void DataSubjectUnPackStateBody(const iString &s); virtual void ParticleDataSubjectPackStateBody(iString &) const {} virtual void ParticleDataSubjectUnPackStateBody(const iString &){} private: iParticleFileLoader *mParticleLoader; }; // // Useful macros to declare all members that have to be overwritten in children // #define IPARTICLEDATASUBJECT_DECLARE_INHERITED_MEMBERS \ IDATASUBJECT_DECLARE_INHERITED_MEMBERS #define IPARTICLEDATASUBJECT_DECLARE_INHERITED_KEYS \ IDATASUBJECT_DECLARE_INHERITED_KEYS; \ static const iObjectKey& KeyUseExtras(); \ static const iObjectKey& KeyTypeIncluded(); \ static const iObjectKey& KeyDownsampleMode(); \ static const iObjectKey& KeyDownsampleFactor(); \ static const iObjectKey& KeyOrderIsAttribute(); \ static const iObjectKey& KeyDensityAttribute() #define IPARTICLEDATASUBJECT_DEFINE_TYPE(_object_,_id_,_fname_,_sname_,_keywords_,_environment_) \ IDATASUBJECT_DEFINE_TYPE(_object_,_id_,_fname_,_sname_,0,_keywords_,_environment_) #define IPARTICLEDATASUBJECT_DEFINE_INHERITED_KEYS(_type_) \ IDATASUBJECT_DEFINE_INHERITED_KEYS(_type_); \ IOBJECT_DEFINE_INHERITED_KEY(iParticleDataSubject,_type_,UseExtras,ue,Bool,1); \ IOBJECT_DEFINE_INHERITED_KEY(iParticleDataSubject,_type_,TypeIncluded,ti,Bool,1); \ IOBJECT_DEFINE_INHERITED_KEY(iParticleDataSubject,_type_,DownsampleMode,dm,Int,1); \ IOBJECT_DEFINE_INHERITED_KEY(iParticleDataSubject,_type_,DownsampleFactor,df,Int,1); \ IOBJECT_DEFINE_INHERITED_KEY(iParticleDataSubject,_type_,OrderIsAttribute,oa,Bool,1); \ IOBJECT_DEFINE_INHERITED_KEY(iParticleDataSubject,_type_,DensityAttribute,da,OffsetInt,1) #define IPARTICLEDATASUBJECT_DECLARE_CLASS(_prefix_,_name_) \ class _prefix_##_name_##DataSubject : public iParticleDataSubject \ { \ public: \ vtkTypeMacro(_prefix_##_name_##DataSubject,iParticleDataSubject); \ _prefix_##_name_##DataSubject(iParticleFileLoader *fl); \ IPARTICLEDATASUBJECT_DECLARE_INHERITED_KEYS; \ IPARTICLEDATASUBJECT_DECLARE_INHERITED_MEMBERS; \ } #define IPARTICLEDATASUBJECT_DEFINE_CLASS(_prefix_,_name_,_fname_,_sname_,_keywords_,_environment_) \ IPARTICLEDATASUBJECT_DEFINE_TYPE(_prefix_##_name_##DataSubject,_prefix_##Extension::SubjectId(),_fname_,_sname_,_keywords_,_environment_); \ IPARTICLEDATASUBJECT_DEFINE_INHERITED_KEYS(_prefix_##_name_##DataSubject); \ _prefix_##_name_##DataSubject::_prefix_##_name_##DataSubject(iParticleFileLoader *fl) : iParticleDataSubject(fl,_prefix_##_name_##DataSubject::Type().FullName()){} #endif ifrit-3.4.2/core/iparticledensityestimator.cpp0000755000175700010010000001042412167404433020152 0ustar HomeNone/*========================================================================= Program: Ionization FRont Interactive Tool (IFRIT) Language: C++ Copyright (c) 2002-2012 Nick Gnedin All rights reserved. This file may be distributed and/or modified under the terms of the GNU General Public License version 2 as published by the Free Software Foundation and appearing in the file LICENSE.GPL included in the packaging of this file. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHORS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. =========================================================================*/ #include "iparticledensityestimator.h" #include "ierror.h" #include "iparallel.h" #include "iparticlefileloader.h" #include "iviewmodule.h" #include #include #include #include #include #include #include iParticleDensityEstimator* iParticleDensityEstimator::New(iParticleFileLoader *loader) { IERROR_ASSERT(loader); return new iParticleDensityEstimator(loader); } iParticleDensityEstimator::iParticleDensityEstimator(iParticleFileLoader *loader) : iParallelWorker(loader->GetViewModule()->GetParallelManager()) { mNumNeighbors = 16; mLocator = vtkPointLocator::New(); IERROR_ASSERT(mLocator); mData = vtkPolyData::New(); IERROR_ASSERT(mData); mLocator->SetDataSet(mData); } iParticleDensityEstimator::~iParticleDensityEstimator() { mLocator->Delete(); mData->Delete(); } void iParticleDensityEstimator::SetNumNeighbors(int num) { if(num > 1) { mNumNeighbors = num; } } void iParticleDensityEstimator::ComputeDensity(vtkPoints *points, vtkFloatArray *scalars, int attIn, int attOut) { if(points==0 || scalars==0 || scalars->GetDataType()!=VTK_FLOAT || attIn<-1 || attIn>=scalars->GetNumberOfComponents() || attOut<0 || attOut>=scalars->GetNumberOfComponents()) return; wAttrIn = attIn; wAttrOut = attOut; mData->SetPoints(points); mData->GetPointData()->SetScalars(scalars); this->InvokeEvent(vtkCommand::StartEvent); this->PrepareForStep(); this->ParallelExecute(1); this->InvokeEvent(vtkCommand::EndEvent); mData->SetPoints(0); mData->GetPointData()->SetScalars(0); } void iParticleDensityEstimator::PrepareForStep() { mLocator->BuildLocator(); } int iParticleDensityEstimator::ExecuteStep(int step, iParallel::ProcessorInfo &p) { vtkIdType l, kstp, kbeg, kend; vtkIdType id; int i, n; iParallel::SplitRange(p,mData->GetNumberOfPoints(),kbeg,kend,kstp); double r2, sr0, sr2, r2max, x[3], x1[3]; vtkPoints *points = mData->GetPoints(); int nc = mData->GetPointData()->GetScalars()->GetNumberOfComponents(); vtkIdList *result = vtkIdList::New(); if(result == 0) return 1; float v; float *ptrIn = (float *)mData->GetPointData()->GetScalars()->GetVoidPointer(0) + wAttrIn; float *ptrOut = (float *)mData->GetPointData()->GetScalars()->GetVoidPointer(0) + wAttrOut; for(l=kbeg; lIsMaster(p)) { this->UpdateProgress(float(l-kbeg)/(kend-kbeg)); } if(this->GetAbortExecute()) break; } points->GetPoint(l,x); mLocator->FindClosestNPoints(mNumNeighbors,x,result); n = result->GetNumberOfIds(); sr0 = sr2 = r2max = 0.0; for(i=0; iGetId(i); points->GetPoint(id,x1); r2 = vtkMath::Distance2BetweenPoints(x,x1); v = (wAttrIn == -1) ? 1.0 : ptrIn[nc*id]; sr0 += v; sr2 += v*r2; if(r2 > r2max) r2max = r2; } if(n>0 && r2max>0.0) { ptrOut[nc*l] = 2.5*(sr0-sr2/r2max)/(12.566*n*r2max*sqrt(r2max)); } else { ptrOut[nc*l] = (wAttrIn == -1) ? 1.0 : ptrIn[nc*l]; } } result->Delete(); return 0; } ifrit-3.4.2/core/iparticledensityestimator.h0000644000175700010010000000476212167404416017625 0ustar HomeNone/*========================================================================= Program: Ionization FRont Interactive Tool (IFRIT) Language: C++ Copyright (c) 2002-2012 Nick Gnedin All rights reserved. This file may be distributed and/or modified under the terms of the GNU General Public License version 2 as published by the Free Software Foundation and appearing in the file LICENSE.GPL included in the packaging of this file. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHORS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. =========================================================================*/ // // Helper class for computing particle density in place (NOT a filter!!!) - there is no elegant way to add // an attribute without replicating the data in the memory. // It can be inherited to implement a faster density assignment scheme. // #ifndef IPARTICLEDENSITYESTIMATOR_H #define IPARTICLEDENSITYESTIMATOR_H #include #include "iparallelworker.h" class iParticleFileLoader; class vtkFloatArray; class vtkPointLocator; class vtkPoints; class vtkPolyData; class iParticleDensityEstimator : public vtkProcessObject, protected iParallelWorker { public: vtkTypeMacro(iParticleDensityEstimator,vtkProcessObject); static iParticleDensityEstimator* New(iParticleFileLoader *loader = 0); void SetNumNeighbors(int num); inline int GetNumNeighbors() const { return mNumNeighbors; } void ComputeDensity(vtkPoints *points, vtkFloatArray *scalars, int attIn, int attOut); protected: iParticleDensityEstimator(iParticleFileLoader *loader); virtual ~iParticleDensityEstimator(); virtual int ExecuteStep(int step, iParallel::ProcessorInfo &p); virtual void PrepareForStep(); int mNumNeighbors; vtkPolyData *mData; vtkPointLocator *mLocator; // // Work variables // int wAttrIn, wAttrOut; }; #endif // IPARTICLEDENSITYESTIMATOR_H ifrit-3.4.2/core/iparticledownsampleiterator.cpp0000755000175700010010000001340212167404433020465 0ustar HomeNone/*========================================================================= Program: Ionization FRont Interactive Tool (IFRIT) Language: C++ Copyright (c) 2002-2012 Nick Gnedin All rights reserved. This file may be distributed and/or modified under the terms of the GNU General Public License version 2 as published by the Free Software Foundation and appearing in the file LICENSE.GPL included in the packaging of this file. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHORS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. =========================================================================*/ #include "iparticledownsampleiterator.h" #include "imath.h" #include // // Templates // #include "iarraytemplate.h" // // Main class // iParticleDownsampleIterator::iParticleDownsampleIterator() { mMaskId = -1; mDownsampleMode = 0; wIdTot = -1L; wIdLoc = wIdGlob = -1; wMask = 0; } iParticleDownsampleIterator::~iParticleDownsampleIterator() { } void iParticleDownsampleIterator::SetDownsampleMode(int v) { if(v>=0 && v<=5 && v!=mDownsampleMode) { mDownsampleMode = v; } } vtkIdType iParticleDownsampleIterator::GetNumGlobalTotal() const { int i; vtkIdType n = 0L; for(i=0; iCreateOneMask(i,ntot[i],df[i]); } vtkIdType iParticleDownsampleIterator::CreateOneMask(int i, vtkIdType ntot, int df) { if(i < 0) { IERROR_HIGH("Mask id should be non-negative.") return 0; } if(i == 0) { mMaskId = 0; while(mMasks.Size() > 0) mMasks.RemoveLast(); } else { if(i != mMaskId+1) { IERROR_HIGH("iParticleDownsampleIterator::PrepareMask should be called sequentially."); return 0; } mMaskId++; } while(i > mMasks.MaxIndex()) mMasks.Add(Mask()); mMasks[i].DownsampleFactor = df; if(df < 2) { mMasks[i].Dim1D = 1; mMasks[i].Dim2D = 1; mMasks[i].NumSelected = (df == 1) ? ntot : 0; mMasks[i].RandomThreshold = (df == 1) ? 0.0 : 1.0; } else { switch(mDownsampleMode) { case 1: { vtkIdType n1 = (vtkIdType)(0.5+sqrt(double(ntot))); if(n1>1 && n1*n1>ntot) n1--; mMasks[i].Dim1D = n1; mMasks[i].Dim2D = 1; vtkIdType ns = (mMasks[i].Dim1D+df-1)/df; mMasks[i].NumSelected = ns*ns; mMasks[i].RandomThreshold = 1.0; break; } case 2: { vtkIdType n1 = (vtkIdType)(0.5+pow(double(ntot),1.0/3.0)); if(n1>1 && n1*n1*n1>ntot) n1--; mMasks[i].Dim1D = n1; mMasks[i].Dim2D = n1*n1; vtkIdType ns = (mMasks[i].Dim1D+df-1)/df; mMasks[i].NumSelected = ns*ns*ns; mMasks[i].RandomThreshold = 1.0; break; } default: { mMasks[i].Dim1D = 1; mMasks[i].Dim2D = 1; mMasks[i].NumSelected = (ntot+df-1)/df; mMasks[i].RandomThreshold = 1.0/df; } } } mMasks[i].NumTotal = ntot; mMasks[i].NumSkipped = mMasks[i].NumTotal - mMasks[i].NumSelected; if(i == 0) { mMasks[i].OffsetTotal = 0; mMasks[i].OffsetSelected = 0; } else { mMasks[i].OffsetTotal = mMasks[i-1].OffsetTotal + mMasks[i-1].NumTotal; mMasks[i].OffsetSelected = mMasks[i-1].OffsetSelected + mMasks[i-1].NumSelected; } mMasks[i].Skip = false; mMasks[i].Buffer = 0; mMasks[i].BufferWidth = mMasks[i].BufferIncrement = 0; return mMasks[i].NumSelected; } bool iParticleDownsampleIterator::AttachBuffer(int i, vtkDataArray *array, int offset) { if(i>=0 && i=0 && offsetGetNumberOfComponents()) { mMasks[i].Buffer = (char *)array->GetVoidPointer(offset); mMasks[i].BufferWidth = array->GetNumberOfComponents(); mMasks[i].BufferIncrement = mMasks[i].BufferWidth*array->GetDataTypeSize(); return true; } else return false; } void iParticleDownsampleIterator::SkipMask(int n, bool s) { if(n>=0 && nmMasks.MaxIndex()) m = 0; wMask = mMasks.Data() + m; wIdTot = wMask->OffsetTotal - 1; wIdLoc = -1; wIdGlob = wMask->OffsetSelected - 1; } void iParticleDownsampleIterator::Stop(int m) { #ifdef I_CHECK1 wIdTot++; wIdGlob++; if(m==-1 && wIdTot==wMask->OffsetTotal+wMask->NumTotal) { this->AdvanceCurrentMask(); } if(m<0 || m>mMasks.MaxIndex()) m = mMasks.MaxIndex(); if(wMask!=&mMasks[m] || wIdGlob!=wMask->NumSelected+wMask->OffsetSelected || wIdTot!=wMask->NumTotal+wMask->OffsetTotal) { IERROR_REPORT_BUG; } #endif wIdTot = -1L; wIdLoc = wIdGlob = -1; wMask = 0; } void iParticleDownsampleIterator::AdvanceCurrentMask() { // // Do nothing if requested to advance the last mask // if(wMask == &mMasks.Last()) return; wMask++; while(wMask->Skip || wMask->NumTotal==0) { wIdTot += wMask->NumTotal; wIdGlob += wMask->NumSelected; wIdLoc = 0; if(wMask != &mMasks.Last()) wMask++; else break; } } #ifdef I_CHECK2 void iParticleDownsampleIterator::ReportBug() { IERROR_REPORT_BUG; } #endif ifrit-3.4.2/core/iparticledownsampleiterator.h0000644000175700010010000001270612167404416020136 0ustar HomeNone/*========================================================================= Program: Ionization FRont Interactive Tool (IFRIT) Language: C++ Copyright (c) 2002-2012 Nick Gnedin All rights reserved. This file may be distributed and/or modified under the terms of the GNU General Public License version 2 as published by the Free Software Foundation and appearing in the file LICENSE.GPL included in the packaging of this file. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHORS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. =========================================================================*/ // // Helper class for reading a subset of particles // #ifndef IPARTICLEDOWNSAMPLEITERATOR_H #define IPARTICLEDOWNSAMPLEITERATOR_H #include "iarray.h" #include class vtkDataArray; class iParticleDownsampleIterator { public: iParticleDownsampleIterator(); virtual ~iParticleDownsampleIterator(); void SetDownsampleMode(int v); inline int GetDownsampleMode() const { return mDownsampleMode; } inline vtkIdType GetNumTotal(int i) const { if(i>=0 && i=0 && i=0 && i=0 && i=0 && iBuffer + wMask->BufferIncrement*wIdLoc; } protected: // // Helper types // struct Mask { bool Skip; vtkIdType NumTotal; vtkIdType NumSkipped; vtkIdType OffsetTotal; vtkIdType NumSelected; vtkIdType OffsetSelected; int DownsampleFactor; vtkIdType Dim1D, Dim2D; float RandomThreshold; char *Buffer; int BufferWidth, BufferIncrement; Mask(){ NumTotal = NumSkipped = OffsetTotal = 0; NumSelected = OffsetSelected = 0; DownsampleFactor = 1; Dim1D = Dim2D = 1; RandomThreshold = 0.0f; Buffer = 0; BufferWidth = BufferIncrement = 0; } }; private: void AdvanceCurrentMask(); #ifdef I_CHECK2 void ReportBug(); #endif // // Members // int mMaskId, mDownsampleMode; iArray mMasks; // // Work variables // vtkIdType wIdTot; vtkIdType wIdGlob, wIdLoc; const Mask *wMask; }; // // Inlined for efficiency // inline bool iParticleDownsampleIterator::IsSelected() { wIdTot++; if(wIdTot == wMask->OffsetTotal+wMask->NumTotal) { this->AdvanceCurrentMask(); // advance the current mask; skip skipped and empty masks too } vtkIdType idt = wIdTot - wMask->OffsetTotal; bool ret = false; if(wMask->DownsampleFactor < 2) { ret = (wMask->DownsampleFactor == 1); } else { switch(mDownsampleMode) { case 0: { if(idt%wMask->DownsampleFactor == 0) ret = true; break; } case 1: { vtkIdType i2 = idt/wMask->Dim1D; vtkIdType i1 = idt - wMask->Dim1D*i2; if(i1%wMask->DownsampleFactor==0 && i2%wMask->DownsampleFactor==0 && i1Dim1D && i2Dim1D) ret = true; break; } case 2: { vtkIdType i3 = idt/wMask->Dim2D; vtkIdType i2 = idt/wMask->Dim1D - wMask->Dim1D*i3; vtkIdType i1 = idt - wMask->Dim1D*(i2+wMask->Dim1D*i3); if(i1%wMask->DownsampleFactor==0 && i2%wMask->DownsampleFactor==0 && i3%wMask->DownsampleFactor==0 && i1Dim1D && i2Dim1D && i3Dim1D) ret = true; break; } case 3: { if((wIdLoc+1NumSelected) && (wIdLoc+wMask->NumSkipped<=idt || vtkMath::Random()RandomThreshold)) ret = true; break; } case 4: { if(idt < wMask->NumSelected) ret = true; break; } case 5: { if(idt >= wMask->NumSkipped) ret = true; break; } } } if(ret) { wIdGlob++; wIdLoc = wIdGlob - wMask->OffsetSelected; #ifdef I_CHECK2 if(wIdLoc >= wMask->NumSelected) this->ReportBug(); #endif } return ret; } #endif // IPARTICLEDOWNSAMPLEITERATOR_H ifrit-3.4.2/core/iparticlefileloader.cpp0000755000175700010010000005633412167404433016663 0ustar HomeNone/*========================================================================= Program: Ionization FRont Interactive Tool (IFRIT) Language: C++ Copyright (c) 2002-2012 Nick Gnedin All rights reserved. This file may be distributed and/or modified under the terms of the GNU General Public License version 2 as published by the Free Software Foundation and appearing in the file LICENSE.GPL included in the packaging of this file. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHORS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. =========================================================================*/ #include "iparticlefileloader.h" #include "ibuffer.h" #include "icommoneventobservers.h" #include "idatalimits.h" #include "idatasubject.h" #include "ierror.h" #include "ierrorstatus.h" #include "iparallel.h" #include "iparallelmanager.h" #include "iparallelworker.h" #include "iparticledensityestimator.h" #include "iviewmodule.h" #include #include #include #include #include #include #include // // Templates // #include "iarraytemplate.h" #include "ibuffertemplate.h" // // Helper classes for parallel execution & templates // class iParticleHelper : protected iParallelWorker { public: iParticleHelper(iParticleFileLoader *loader); void ShiftData(bool paf, int dim, vtkIdType n, bool per[3], float dr, float *pf, double *pd); void FindRange(int dim, vtkIdType n, float *pf, float *amin, float *amax); void AddIndexAsAttribute(int att, int nc, vtkIdType n, float *pf); template bool ReadFortranRecordWithMaskTemplate(iFile &F, int dest, int inNum, int outOffset, float updateStart, float updateDuration, T *scale, T *offset); template void AutoScalePositions(); protected: virtual int ExecuteStep(int step, iParallel::ProcessorInfo &p); iParticleFileLoader *mLoader; iBuffer mMin, mMax; bool *mPeriodic; float *mFarr; double *mDarr; int mDim, mCom, mNumProcs; bool mPaf; vtkIdType mTot; float mDr; }; // // Main class // iParticleFileLoader::iParticleFileLoader(iDataReader *r, int priority, bool useExtras) : iFileLoader(r,priority), mUseExtras(useExtras) { this->Define(); } iParticleFileLoader::iParticleFileLoader(iDataReaderExtension *ext, int priority, bool useExtras) : iFileLoader(ext,priority), mUseExtras(useExtras) { this->Define(); } void iParticleFileLoader::Define() { mHaveNormals = false; mHelper = new iParticleHelper(this); IERROR_ASSERT(mHelper); mDensityEstimator = iParticleDensityEstimator::New(this); IERROR_ASSERT(mDensityEstimator); mDensityEstimator->AddObserver(vtkCommand::StartEvent,this->GetObserver()); mDensityEstimator->AddObserver(vtkCommand::ProgressEvent,this->GetObserver()); mDensityEstimator->AddObserver(vtkCommand::EndEvent,this->GetObserver()); } iParticleFileLoader::~iParticleFileLoader() { int i; for(i=0; iNumStreams(); i++) { if(this->GetStream(i)->Data != 0) this->GetStream(i)->Data->Delete(); } delete mHelper; mDensityEstimator->Delete(); } void iParticleFileLoader::SetDownsampleMode(int v) { mIterator.SetDownsampleMode(v); } int iParticleFileLoader::GetDownsampleMode() const { return mIterator.GetDownsampleMode(); } void iParticleFileLoader::SetNumNeighbors(int num) { mDensityEstimator->SetNumNeighbors(num); } int iParticleFileLoader::GetNumNeighbors() const { return mDensityEstimator->GetNumNeighbors(); } void iParticleFileLoader::SetTypeIncluded(int type, bool s) { if(type>=0 && typeNumStreams()) { this->GetStream(type)->Included = s; } } void iParticleFileLoader::SetDownsampleFactor(int type, int value) { if(value > 0) { if(type>=0 && typeNumStreams()) { this->GetStream(type)->DownsampleFactor = value; } else if(type == -1) { int i; for(i=0; iNumStreams(); i++) this->GetStream(i)->DownsampleFactor = value; } } } void iParticleFileLoader::SetDensityAttribute(int type, int attr) { if(mUseExtras && type>=0 && typeNumStreams()) { this->GetStream(type)->Extras.DensityAttribute = (attr > -2) ? attr : -2; } } void iParticleFileLoader::SetOrderIsAttribute(int type, bool s) { if(mUseExtras && type>=0 && typeNumStreams()) { this->GetStream(type)->Extras.OrderIsAttribute = s; } } void iParticleFileLoader::AddExtras(ParticleStream *stream) { int natt = stream->NumAttributesInFile; // // If we save the order in file as an attribute, fill it in. // if(stream->Extras.OrderIsAttribute && nattNumAttributesInData) { mHelper->AddIndexAsAttribute(natt,stream->Scalars->GetNumberOfComponents(),stream->Scalars->GetNumberOfTuples(),stream->Scalars->GetPointer(0)); natt++; } // // Check if we need to add density // if(stream->Extras.DensityAttribute>-2 && nattNumAttributesInData && stream->Extras.DensityAttributeGetObserver()->SetMode(iProgressEventObserver::_Operating); mDensityEstimator->ComputeDensity(stream->Points,stream->Scalars,stream->Extras.DensityAttribute,natt); natt++; } // // Final check // if(natt != stream->NumAttributesInData) { IERROR_HIGH("iParticleFileLoader is configured icorrectly: unfilled attributes remained."); this->GetErrorStatus()->Set("Unable to read the data due to a bug."); } } void iParticleFileLoader::FinalizeBody() { int i; // // Apply extras // for(i=0; iNumStreams(); i++) this->AddExtras(this->GetStream(i)); for(i=0; iNumStreams(); i++) { this->GetStream(i)->Data->SetPoints(this->GetStream(i)->Points); this->GetStream(i)->Data->SetVerts(this->GetStream(i)->Verts); this->GetStream(i)->Data->GetPointData()->SetScalars(this->GetStream(i)->Scalars); this->AttachDataToStream(i,this->GetStream(i)->Data); } this->ReleaseStreams(); // // Attribute limits. // for(i=0; iNumStreams(); i++) if(!this->GetStream(i)->Subject->GetFixedLimits()) { vtkFloatArray *att = iRequiredCast(INFO,this->GetStream(i)->Data->GetPointData()->GetScalars()); if(att!=0 && att->GetNumberOfComponents()>0 && att->GetNumberOfTuples()>0 && att->GetNumberOfComponents()==this->GetStream(i)->Subject->GetLimits()->GetNumVars()) // just in case { iBuffer aMin, aMax; aMin.Extend(att->GetNumberOfComponents()); aMax.Extend(att->GetNumberOfComponents()); mHelper->FindRange(att->GetNumberOfComponents(),att->GetNumberOfTuples(),att->GetPointer(0),aMin,aMax); int j; for(j=0; jGetNumberOfComponents(); j++) { this->GetStream(i)->Subject->GetLimits()->SetMin(j,aMin[j]); this->GetStream(i)->Subject->GetLimits()->SetMax(j,aMax[j]); } } } for(i=0; iNumStreams(); i++) { this->FinalizePolyData(this->GetStream(i)->Data); } } void iParticleFileLoader::ShiftDataBody(vtkDataSet *data, double dx[3]) { int i; for(i=0; i<3; i++) if(fabs(dx[i]) > 1.0e-100) { this->ShiftPolyData(iRequiredCast(INFO,data),i,dx[i]); } } void iParticleFileLoader::FinalizePolyData(vtkPolyData *data) { if(data==0 || data->GetPoints()==0) return; int i; vtkIdType l, loff, ntot = data->GetNumberOfPoints(); // // Boundary condition // for(i=0; i<3; i++) this->SetDirectionPeriodic(i,this->IsBoxPeriodic()); if(this->IsBoxPeriodic()) { if(data->GetPoints()->GetDataType() == VTK_FLOAT) { float *xptrF = (float *)data->GetPoints()->GetVoidPointer(0); for(i=0; i<3; i++) if(this->IsDirectionPeriodic(i)) { for(l=0; lGetPoints()->GetDataType() == VTK_DOUBLE) { double *xptrD = (double *)data->GetPoints()->GetVoidPointer(0); for(i=0; i<3; i++) if(this->IsDirectionPeriodic(i)) { for(l=0; lGetErrorStatus()->Set("Internal bug: ivalid points data type."); } } if(mHaveNormals) { vtkFloatArray *newNormals; newNormals = vtkFloatArray::New(); IERROR_ASSERT(newNormals); newNormals->SetNumberOfComponents(3); // Allocates and Sets MaxId newNormals->SetNumberOfTuples(ntot); float *p = (float *)newNormals->GetVoidPointer(0); if(p != 0) { for(l=0; lGetPointData()->SetNormals(newNormals); } newNormals->Delete(); } // // Check for overflow // if(data->GetPointData()->GetScalars() != 0) { float *p = (float *)data->GetPointData()->GetScalars()->GetVoidPointer(0); int natt = data->GetPointData()->GetScalars()->GetNumberOfComponents(); if(p != 0) { for(l=0; l iMath::_LargeFloat) { p[natt*l+i] = iMath::_LargeFloat; mOverflow = true; } } } } } } void iParticleFileLoader::ShiftPolyData(vtkPolyData *data, int d, double dx) { if(data==0 || data->GetPoints()==0 || d<0 || d>2) return; vtkIdType n = data->GetPoints()->GetNumberOfPoints(); float *pf = (float *)data->GetPoints()->GetVoidPointer(0); double *pd = (double *)data->GetPoints()->GetVoidPointer(0); if(pf!=0 && pd!=0) { mHelper->ShiftData(data->GetPoints()->GetDataType()==VTK_FLOAT,d,n,mPeriodic,dx,pf,pd); data->Modified(); } } bool iParticleFileLoader::ReadPositions(iFile &F, int inNum, int outOffset, float updateStart, float updateDuration, float *scale, float *offset) { return mHelper->ReadFortranRecordWithMaskTemplate(F,0,inNum,outOffset,updateStart,updateDuration,scale,offset); } bool iParticleFileLoader::ReadPositions(iFile &F, int inNum, int outOffset, float updateStart, float updateDuration, double *scale, double *offset) { return mHelper->ReadFortranRecordWithMaskTemplate(F,0,inNum,outOffset,updateStart,updateDuration,scale,offset); } bool iParticleFileLoader::ReadAttributes(iFile &F, int inNum, int outOffset, float updateStart, float updateDuration, float *scale) { return mHelper->ReadFortranRecordWithMaskTemplate(F,1,inNum,outOffset,updateStart,updateDuration,scale,(float *)0); } bool iParticleFileLoader::ReadIntAttributes(iFile &F, int inNum, int outOffset, float updateStart, float updateDuration) { return mHelper->ReadFortranRecordWithMaskTemplate(F,1,inNum,outOffset,updateStart,updateDuration,(float *)0,(float *)0); } void iParticleFileLoader::ConfigureStreams(vtkIdType *ntot, int *natt, bool paf) { int n; ParticleStream *stream; for(n=0; nNumStreams(); n++) { stream = this->GetStream(n); if(stream->Data == 0) { stream->Data = vtkPolyData::New(); IERROR_ASSERT(stream->Data); } vtkIdType nsel = mIterator.CreateOneMask(n,ntot[n],stream->Included?stream->DownsampleFactor:0); // // Determine how many extra (derived) attributes we need. // int nattIn = natt[n]; if(stream->Extras.DensityAttribute>-2 && stream->Extras.DensityAttributeExtras.OrderIsAttribute) natt[n]++; // // Try to set the requested number of attributes. DataLimits will either expand to accommodate // all of them or limit the allowed number to the number of listed records. // stream->Subject->GetLimits()->AssignVars(natt[n]); natt[n] = stream->Subject->GetLimits()->GetNumVars(); if(nattIn > natt[n]) nattIn = natt[n]; // // Fill in stream info // stream->NumTotal = ntot[n]; stream->NumSelected = nsel; stream->NumAttributesInFile = nattIn; stream->NumAttributesInData = natt[n]; stream->InFile = true; // // Create data arrays // vtkPoints *oldPoints = stream->Data->GetPoints(); vtkCellArray *oldVerts = stream->Data->GetVerts(); vtkFloatArray *oldScalars = iRequiredCast(INFO,stream->Data->GetPointData()->GetScalars()); int type = paf ? VTK_FLOAT : VTK_DOUBLE; if(oldPoints==0 || oldPoints->GetNumberOfPoints()!=nsel || oldPoints->GetDataType()!=type) { stream->Data->SetPoints(0); stream->Points = vtkPoints::New(type); IERROR_ASSERT(stream->Points); // Allocates and Sets MaxId stream->Points->SetNumberOfPoints(nsel); } else { stream->Points = oldPoints; stream->Points->Register(0); } if(oldVerts==0 || oldVerts->GetNumberOfCells()!=nsel) { stream->Data->SetVerts(0); stream->Verts = vtkCellArray::New(); IERROR_ASSERT(stream->Verts); // This allocates but does not Set Max Id stream->Verts->Allocate(stream->Verts->EstimateSize(nsel,1)); vtkIdType l; for(l=0; lVerts->InsertNextCell(1); stream->Verts->InsertCellPoint(l); } } else { stream->Verts = oldVerts; stream->Verts->Register(0); } if(oldScalars==0 || oldScalars->GetNumberOfTuples()!=nsel || oldScalars->GetNumberOfComponents()!=natt[n]) { stream->Data->GetPointData()->SetScalars(0); if(natt[n] > 0) { stream->Scalars = vtkFloatArray::New(); IERROR_ASSERT(stream->Scalars); stream->Scalars->SetNumberOfComponents(natt[n]); stream->Scalars->SetNumberOfTuples(nsel); } else stream->Scalars = 0; } else { stream->Scalars = oldScalars; stream->Scalars->Register(0); } } } void iParticleFileLoader::ReleaseStreams() { int n; for(n=0; nNumStreams(); n++) { this->GetStream(n)->Points->Delete(); this->GetStream(n)->Points = 0; this->GetStream(n)->Verts->Delete(); this->GetStream(n)->Verts = 0; if(this->GetStream(n)->Scalars != 0) { this->GetStream(n)->Scalars->Delete(); this->GetStream(n)->Scalars = 0; } } } void iParticleFileLoader::SetErrorMessage(const iString &filename) { this->GetErrorStatus()->Set(filename); mObserver->Finished(); } void iParticleFileLoader::AutoScalePositions() { // // Scale positions automatically // vtkPoints *p = 0; int i; for(i=0; p==0 && iNumStreams(); i++) p = this->GetStream(i)->Points; if(p == 0) return; switch(p->GetDataType()) { case VTK_FLOAT: { mHelper->AutoScalePositions(); break; } case VTK_DOUBLE: { mHelper->AutoScalePositions(); break; } } } // // Helper class // iParticleHelper::iParticleHelper(iParticleFileLoader *loader) : iParallelWorker(loader->GetViewModule()->GetParallelManager()) { mLoader = loader; } void iParticleHelper::ShiftData(bool paf, int dim, vtkIdType n, bool per[3], float dr, float *pf, double *pd) { mPaf = paf; mDim = dim; mTot = n; mDr = dr; mFarr = pf; mDarr = pd; mPeriodic = per; this->ParallelExecute(1); } void iParticleHelper::FindRange(int dim, vtkIdType tot, float *pf, float *fMin, float *fMax) { mDim = dim; mTot = tot; mFarr = pf; mNumProcs = this->GetManager()->GetNumberOfProcessors(); mMin.Extend(mDim*mNumProcs); mMax.Extend(mDim*mNumProcs); this->ParallelExecute(2); int i, n; for(n=0; n mMin[n+dim*i]) fMin[n] = mMin[n+dim*i]; if(fMax[n] < mMax[n+dim*i]) fMax[n] = mMax[n+dim*i]; } } } void iParticleHelper::AddIndexAsAttribute(int dim, int com, vtkIdType tot, float *pf) { mDim = dim; mCom = com; mTot = tot; mFarr = pf; this->ParallelExecute(3); } int iParticleHelper::ExecuteStep(int step, iParallel::ProcessorInfo &p) { vtkIdType l, kstp, kbeg, kend; int d = mDim; int nc = mCom; iParallel::SplitRange(p,mTot,kbeg,kend,kstp); switch(step) { case 1: { float dr = mDr; if(mPaf) { float *x = mFarr + 3*kbeg; for(l=kbeg; lIsMaster(p)) mLoader->GetObserver()->SetProgress((d+(float)(l-kbeg)/(kend-kbeg))/3.0); if(mLoader->GetObserver()->IsAborted()) return 2; } x[d] += 2.0*dr; if(mPeriodic[d]) { if(x[d] > 1.0) x[d] -= 2.0; if(x[d] < -1.0) x[d] += 2.0; } x += 3; } } else { double *x = mDarr + 3*kbeg; for(l=kbeg; lIsMaster(p)) mLoader->GetObserver()->SetProgress((float)(l-kbeg)/(kend-kbeg)); if(mLoader->GetObserver()->IsAborted()) return 2; } x[d] += 2.0*dr; if(mPeriodic[d]) { if(x[d] > 1.0) x[d] -= 2.0; if(x[d] < -1.0) x[d] += 2.0; } x += 3; } } return 0; } case 2: { int j; float *f = mFarr + d*kbeg, *fmin = mMin + d*p.ThisProc, *fmax = mMax + d*p.ThisProc; for(j=0; j f[j]) fmin[j] = f[j]; if(fmax[j] < f[j]) fmax[j] = f[j]; } } return 0; } case 3: { float *f = mFarr + mDim; for(l=kbeg; lIsMaster(p)) mLoader->GetObserver()->SetProgress((float)(l-kbeg)/(kend-kbeg)); if(mLoader->GetObserver()->IsAborted()) return 2; } f[nc*l] = l; } return 0; } default: { return 1; } } } template bool iParticleHelper::ReadFortranRecordWithMaskTemplate(iFile &F, int dest, int inNum, int outOffset, float updateStart, float updateDuration, T *scale, T *offset) { iParticleDownsampleIterator &it(this->mLoader->mIterator); if(this->mLoader->NumStreams() == 0) { IERROR_HIGH("Streams must be configured prior to a call to iParticleFileLoader::ReadFortranRecordWithMask."); return false; } if(this->mLoader->NumStreams() != it.GetNumMasks()) { IERROR_HIGH("Masks must be created prior to a call to iParticleFileLoader::ReadFortranRecordWithMask."); return false; } // // Is component valid? // if(inNum<1 || outOffset<0) { IERROR_HIGH("Invalid call to iParticleFileLoader::ReadFortranRecordWithMask."); return false; } int j; vtkDataArray *arr; for(j=0; jmLoader->NumStreams(); j++) { if(this->mLoader->GetStream(j)->InFile) { switch(dest) { case 0: { arr = this->mLoader->GetStream(j)->Points->GetData(); break; } case 1: { arr = this->mLoader->GetStream(j)->Scalars; break; } default: { arr = 0; } } if((arr==0 && it.GetNumSelected(j)>0) || !it.AttachBuffer(j,arr,outOffset)) { IERROR_HIGH("Invalid call to iParticleFileLoader::ReadFortranRecordWithMask."); return false; } it.SkipMask(j,false); } else it.SkipMask(j,true); } // // Read the header // vtkIdType lrec1, lrec2; if(!this->mLoader->ReadFortranHeaderFooter(F,lrec1)) { this->mLoader->GetErrorStatus()->Set("Corrupted data."); return false; } // // Find # of components in the record // int nCompRec = lrec1/((vtkIdType)sizeof(T)*it.GetNumGlobalTotal()); if(lrec1 != nCompRec*sizeof(T)*it.GetNumGlobalTotal()) { this->mLoader->GetErrorStatus()->Set("Corrupted data."); return false; } // // Decide how to read // vtkIdType l, lpiece1, lpiece = it.GetNumGlobalTotal()/1000; if(lpiece < 1000) lpiece = 1000; int npieces = (it.GetNumGlobalTotal()+lpiece-1)/lpiece; // // Create tmp array // T *ptr, *ptmp; D *d = new D[lpiece*nCompRec]; if(d == 0) { this->mLoader->GetErrorStatus()->Set("Not enough memory to create the data."); return false; } // // parameters for the Progress Bar // updateDuration /= npieces; // // Read piece by piece // int i; it.Start(); for(j=0; jmLoader->ReadBlock(F,d,inNum*lpiece1,updateStart+j*updateDuration,updateDuration)) { this->mLoader->GetErrorStatus()->Set("Corrupted data."); delete [] d; return false; } if(this->mLoader->GetObserver()->IsAborted()) { this->mLoader->GetErrorStatus()->SetAbort(); delete [] d; return false; } for(l=0; lmLoader->ReadFortranHeaderFooter(F,lrec2) || lrec1!=lrec2) { this->mLoader->GetErrorStatus()->Set("Corrupted data."); return false; } // // Do we need to scale? // int nCompArr; vtkIdType nSizeArr; if(scale != 0) { if(offset != 0) { // // Scale as positions // for(j=0; jmLoader->GetObserver()->IsAborted()) { this->mLoader->GetErrorStatus()->SetAbort(); return false; } return true; } template void iParticleHelper::AutoScalePositions() { // // Scale positions automatically // int i, j; vtkIdType l, np; T min[3], max[3], r = 0.0, *ptr; // // Find min/max // for(j=0; jmLoader->NumStreams(); j++) if(this->mLoader->GetStream(j)->Points != 0) { ptr = (T *)this->mLoader->GetStream(j)->Points->GetVoidPointer(0); if(ptr == 0) continue; if(j == 0) { for(i=0; i<3; i++) { min[i] = ptr[i]; max[i] = ptr[i]; } } np = this->mLoader->GetStream(j)->Points->GetNumberOfPoints(); for(l=0; l max[i]) max[i] = ptr[3*l+i]; } } for(i=0; i<3; i++) { if(r < (max[i]-min[i])) r = max[i] - min[i]; } } if(!(r > 0.0)) return; r = 2.0/r; for(j=0; jmLoader->NumStreams(); j++) if(this->mLoader->GetStream(j)->Points != 0) { ptr = (T *)this->mLoader->GetStream(j)->Points->GetVoidPointer(0); if(ptr == 0) continue; np = this->mLoader->GetStream(j)->Points->GetNumberOfPoints(); for(l=0; l(iFileLoader::GetStream(i)); } // no bound checking for speed virtual void FinalizeBody(); virtual void ShiftDataBody(vtkDataSet *data, double dx[3]); virtual void AddExtras(ParticleStream *stream); // // helper functions // void FinalizePolyData(vtkPolyData *data); void ShiftPolyData(vtkPolyData *data, int d, double dx); bool ReadPositions(iFile &F, int inNum, int outOffset, float updateStart, float updateDuration, float *scale, float *offset); bool ReadPositions(iFile &F, int inNum, int outOffset, float updateStart, float updateDuration, double *scale, double *offset); bool ReadAttributes(iFile &F, int inNum, int outOffset, float updateStart, float updateDuration, float *scale = 0); bool ReadIntAttributes(iFile &F, int inNum, int outOffset, float updateStart, float updateDuration); void AutoScalePositions(); void ConfigureStreams(vtkIdType *ntot, int *natt, bool paf = true); void ReleaseStreams(); void SetErrorMessage(const iString &message); iParticleDownsampleIterator mIterator; // value, not the pointer, for efficiency (to remove one level of indirection in loops) iParticleDensityEstimator *mDensityEstimator; private: iParticleFileLoader(iDataReader *r, int priority = 300, bool useExtras = true); void Define(); // // Members // const bool mUseExtras; bool mHaveNormals; iParticleHelper *mHelper; }; inline bool iParticleFileLoader::GetTypeIncluded(int type) const { if(type>=0 && typeNumStreams()) { return this->GetStream(type)->Included; } else return false; } inline int iParticleFileLoader::GetDownsampleFactor(int type) const { if(type>=0 && typeNumStreams()) { return this->GetStream(type)->DownsampleFactor; } else return 1; } inline int iParticleFileLoader::GetDensityAttribute(int type) const { if(type>=0 && typeNumStreams()) { return this->GetStream(type)->Extras.DensityAttribute; } else return 1; } inline bool iParticleFileLoader::GetOrderIsAttribute(int type) const { if(type>=0 && typeNumStreams()) { return this->GetStream(type)->Extras.OrderIsAttribute; } else return false; } #endif ifrit-3.4.2/core/iparticlegroup.cpp0000755000175700010010000004720412167404434015706 0ustar HomeNone/*========================================================================= Program: Ionization FRont Interactive Tool (IFRIT) Language: C++ Copyright (c) 2002-2012 Nick Gnedin All rights reserved. This file may be distributed and/or modified under the terms of the GNU General Public License version 2 as published by the Free Software Foundation and appearing in the file LICENSE.GPL included in the packaging of this file. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHORS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. =========================================================================*/ #include "iparticlegroup.h" #include "iartifactcorrector.h" #include "icommondatadistributors.h" #include "icommoneventobservers.h" #include "icontrolmodule.h" #include "idatalimits.h" #include "idatasubject.h" #include "ierror.h" #include "ieventobserver.h" #include "ifunctionmapping.h" #include "ihistogrammaker.h" #include "ilookuptable.h" #include "ipiecewisefunction.h" #include "iparticleconnector.h" #include "iparticledataconverter.h" #include "iparticlegrouppipeline.h" #include "iparticlesviewsubject.h" #include "ipointglyph.h" #include "ireplicatedactor.h" #include "iviewmodule.h" #include "iviewsubjectparallelpipeline.h" #include #include #include #include #include // // Templates (needed for some compilers) // #include "iarraytemplate.h" using namespace iParameter; IVIEWSUBJECT_DEFINE_TYPE(iParticleGroup,ParticleGroup,pg); IOBJECT_DEFINE_KEY(iParticleGroup,AttributeToColor,ac,OffsetInt,1); IOBJECT_DEFINE_KEY(iParticleGroup,AttributeSizeDirect,ad,Bool,1); IOBJECT_DEFINE_KEY(iParticleGroup,AttributeSizeExtraFactor,ae,Float,1); IOBJECT_DEFINE_KEY(iParticleGroup,AttributeToSize,as,OffsetInt,1); IOBJECT_DEFINE_KEY(iParticleGroup,AttributeToConnect,atc,OffsetInt,1); IOBJECT_DEFINE_KEY(iParticleGroup,AttributeToSeparate,ats,OffsetInt,1); IOBJECT_DEFINE_KEY(iParticleGroup,AutoScaled,au,Bool,1); IOBJECT_DEFINE_KEY(iParticleGroup,StretchToColor,stc,Int,1); IOBJECT_DEFINE_KEY(iParticleGroup,LowerLimitToColor,ltc,Float,1); IOBJECT_DEFINE_KEY(iParticleGroup,UpperLimitToColor,utc,Float,1); IOBJECT_DEFINE_KEY(iParticleGroup,StretchToSize,sts,Int,1); IOBJECT_DEFINE_KEY(iParticleGroup,LowerLimitToSize,lts,Float,1); IOBJECT_DEFINE_KEY(iParticleGroup,UpperLimitToSize,uts,Float,1); IOBJECT_DEFINE_KEY(iParticleGroup,LineWidth,lw,Int,1); IOBJECT_DEFINE_KEY(iParticleGroup,FixedSize,s,Float,1); IOBJECT_DEFINE_KEY(iParticleGroup,SizeFunction,sf,Any,1); IOBJECT_DEFINE_KEY(iParticleGroup,Type,t,Int,1); // // Inherited keys // IVIEWSUBJECT_DEFINE_INHERITED_KEYS_COMMON(iParticleGroup); IVIEWSUBJECT_DEFINE_INHERITED_KEYS_SHADING(iParticleGroup); IVIEWSUBJECT_DEFINE_INHERITED_KEYS_REPLICATING(iParticleGroup); IVIEWSUBJECT_DEFINE_INHERITED_KEYS_COLOR(iParticleGroup,1); IVIEWSUBJECT_DEFINE_INHERITED_KEYS_OPACITY(iParticleGroup,1); IVIEWSUBJECT_DEFINE_INHERITED_KEYS_PALETTE(iParticleGroup,1); namespace iParticleGroup_Private { // // Helper classes // class SizeFunctionEventObserver : public iEventObserver { public: vtkTypeMacro(SizeFunctionEventObserver,iEventObserver); static SizeFunctionEventObserver* New(iPiecewiseFunction *fun = 0, iShell *s = 0) { IERROR_ASSERT(fun); IERROR_ASSERT(s); return new SizeFunctionEventObserver(fun,s); } void AttachPipeline(iViewSubjectPipeline *pipe) { mPipeline = pipe; } protected: SizeFunctionEventObserver(iPiecewiseFunction *fun, iShell *s) : iEventObserver(s) { mFunction = fun; IERROR_ASSERT(fun); mPipeline = 0; mFunction->AddObserver(vtkCommand::ModifiedEvent,this); } virtual void ExecuteBody(vtkObject *caller, unsigned long event, void *) { if(caller==mFunction && event==vtkCommand::ModifiedEvent && mPipeline!=0) mPipeline->UpdateContents(iParticleGroupPipeline::_SizeFunction); } private: iPiecewiseFunction *mFunction; iViewSubjectPipeline *mPipeline; }; class CameraEventObserver : public iEventObserver { public: vtkTypeMacro(CameraEventObserver,iEventObserver); static CameraEventObserver* New(iParticleGroup *parent = 0) { IERROR_ASSERT(parent); return new CameraEventObserver(parent); } void Activate(bool s) { if(s) { mReferenceSize = mParent->GetFixedSize(); mParallelScale = mCamera->GetParallelScale(); mDistance = mCamera->GetDistance(); } else { mReferenceSize = -1.0; } } protected: CameraEventObserver(iParticleGroup *parent) : iEventObserver(parent->GetViewModule()->GetControlModule()->GetShell()) { mParent = parent; mReferenceSize = -1.0; mParallelScale = mDistance = 0.0; mCamera = mParent->GetViewModule()->GetRenderer()->GetActiveCamera(); mCamera->AddObserver(vtkCommand::ModifiedEvent,this); mCamera->Register(this); } ~CameraEventObserver() { mCamera->RemoveObserver(this); mCamera->UnRegister(this); } virtual void ExecuteBody(vtkObject *caller, unsigned long event, void *) { if(mReferenceSize>0.0 && caller==mCamera && event==vtkCommand::ModifiedEvent) { if(mCamera->GetParallelProjection() != 0) { mParent->SetFixedSize(mReferenceSize*mCamera->GetParallelScale()/mParallelScale); } else { mParent->SetFixedSize(mReferenceSize*mCamera->GetDistance()/mDistance); } } } private: vtkCamera *mCamera; iParticleGroup *mParent; double mReferenceSize, mParallelScale, mDistance; }; // // Correct antialising artifact for opaque particles // class ArtifactCorrector : public iArtifactCorrector { public: vtkTypeMacro(ArtifactCorrector,iArtifactCorrector); static ArtifactCorrector* New(iParticleGroup *vo = 0) { IERROR_ASSERT(vo); return new ArtifactCorrector(vo); } protected: ArtifactCorrector(iParticleGroup *vo) : iArtifactCorrector(vo) { mOwner = vo; } virtual bool HasArtifacts(vtkRenderer *ren, vtkProperty *prop) { // // Activate for antialiased opaque verts // if(prop!=0 && ren->GetRenderWindow()!=0) { return (prop->GetOpacity()==1.0 && ren->GetRenderWindow()->GetPointSmoothing()!=0) || mOwner->GetAttributeToColor()>-1; } else return false; } iParticleGroup *mOwner; }; }; using namespace iParticleGroup_Private; iParticleGroup* iParticleGroup::New(iParticlesViewSubject *parent) { IERROR_ASSERT(parent); iParticleGroup *tmp = new iParticleGroup(parent); IERROR_ASSERT(tmp); tmp->Configure(); return tmp; } iParticleGroup::iParticleGroup(iParticlesViewSubject *parent) : iSolidViewSubject(parent->GetViewModule(),parent->GetDataType(),parent->GetSubjectName(),2,ViewSubject::Flag::SameColor|ViewSubject::Flag::SameOpacity|ViewSubject::Flag::SamePalette,0.999) { mSubjectId = ViewSubject::Id::Particles; mParent = parent; mParentIndex = -1; mAttSize = mAttColor = -1; mAttSizeDirect = mAutoScaled = false; mAttSizeExtraFactor = 1.0; mType = PointGlyphType::Point; mSize = 1.0; mStretchToColor = iDataStretch::Log; mLimitsToColor[0] = 0.1f; mLimitsToColor[1] = 10.0f; mLineWidth = 1; mSF = iPiecewiseFunction::New(); IERROR_ASSERT(mSF); mSF->SetMinMax(0.0,1.0); mSF->MovePoint(0,0.0,1.0); mSF->MovePoint(1,1.0,1.0); mConnector = iParticleConnector::New(this); IERROR_ASSERT(mConnector); mHistogramMaker = iHistogramMaker::New(this->GetViewModule()); IERROR_ASSERT(mHistogramMaker); mFunction = new iFunctionMapping(mSF,mHistogramMaker,0); IERROR_ASSERT(mFunction); mSizeFunctionEventObserver = SizeFunctionEventObserver::New(mSF,this->GetViewModule()->GetControlModule()->GetShell()); IERROR_ASSERT(mSizeFunctionEventObserver); mCameraEventObserver = CameraEventObserver::New(this); IERROR_ASSERT(mCameraEventObserver); iAbortRenderEventObserver *obsAbortRender = this->GetViewModule()->GetAbortRenderEventObserver(); mConnector->AddObserver(vtkCommand::ProgressEvent,obsAbortRender); mActors[0]->GetProperty()->SetPointSize(mSize); mActors[0]->GetProperty()->SetLineWidth(mLineWidth); mActors[1]->GetProperty()->SetPointSize(1); mActors[1]->GetProperty()->SetLineWidth(1); mActors[1]->VisibilityOff(); mActors[1]->PickableOff(); ArtifactCorrector *ac = ArtifactCorrector::New(this); IERROR_ASSERT(ac); mActors[0]->InstallArtifactCorrector(ac); ac->Delete(); this->SetColor(0,iColor(0,0,0)); } iParticleGroup::~iParticleGroup() { // must be deleted after the pipeline - do not remember why mSF->Register(this->Pipeline()); mSF->Delete(); mCameraEventObserver->Delete(); mSizeFunctionEventObserver->Delete(); mConnector->Delete(); mHistogramMaker->Delete(); delete mFunction; } void iParticleGroup::ConfigureBody() { // // Create pipeline (must be created after the object is fully created) // this->AddMainPipeline(1); mActors[0]->SetInput(mConnector->GetOutput()); mActors[1]->SetInput(this->Pipeline()->GetOutput(0)); this->Pipeline()->SetNthInput(0,mConnector->GetOutput()); this->SetStretchToColor(iDataStretch::Log); this->SetStretchToSize(iDataStretch::Log); } void iParticleGroup::FinishInitialization() { iRequiredCast(INFO,mSizeFunctionEventObserver)->AttachPipeline(this->Pipeline()); } void iParticleGroup::SetInput(vtkPolyData *input) { mConnector->SetInput(input); mHistogramMaker->SetInput(input,mAttSize); } void iParticleGroup::ResetPipeline() { } void iParticleGroup::SetLineWidth(int w) { if(w>0 && w<100) { mLineWidth = w; mActors[0]->GetProperty()->SetLineWidth(mLineWidth); this->ClearCache(); } } void iParticleGroup::SetType(int t) { mType = t; this->Pipeline()->UpdateContents(iParticleGroupPipeline::_Type); switch (mType) { case PointGlyphType::Point: case PointGlyphType::Tetrahydron: case PointGlyphType::Cluster: case PointGlyphType::Galaxy: { mShading = false; break; } default: { mShading = true; } } if(mType == PointGlyphType::Point) { mActors[0]->GetProperty()->SetPointSize(mSize); mActors[1]->VisibilityOff(); } else { mActors[0]->GetProperty()->SetPointSize(1.0); mActors[1]->SetVisibility(mActors[0]->GetVisibility()); } this->UpdateMaterialProperties(); this->ClearCache(); } void iParticleGroup::SetAttributeToColor(int a) { if(a>=0 && aGetLimits()->GetNumVars()) mAttColor = a; else mAttColor = -1; if(mAttColor >= 0) { mActors[0]->SetScalarVisibility(true); mActors[0]->ColorByArrayComponent(0,mAttColor); mActors[1]->SetScalarVisibility(true); mActors[1]->ColorByArrayComponent(0,mAttColor); if(!this->GetSubject()->GetFixedLimits()) { this->SetLowerLimitToColor(this->GetLimits()->GetMin(mAttColor)); this->SetUpperLimitToColor(this->GetLimits()->GetMax(mAttColor)); } } else { mActors[0]->SetScalarVisibility(false); mActors[1]->SetScalarVisibility(false); } this->UpdateColorLookupTable(); this->ClearCache(); } void iParticleGroup::SetAttributeToSize(int a) { if(a>=0 && aGetLimits()->GetNumVars()) { mAttSize = a; } else mAttSize = -1; this->Pipeline()->UpdateContents(iParticleGroupPipeline::_AttToSize); mFunction->AttachToLimits(this->GetLimits(),mAttSize); mHistogramMaker->SetInputComponent(mAttSize); this->ClearCache(); } void iParticleGroup::SetAttributeSizeDirect(bool s) { mAttSizeDirect = s; this->Pipeline()->UpdateContents(iParticleGroupPipeline::_AttToSize); this->ClearCache(); } void iParticleGroup::SetAttributeSizeExtraFactor(float f) { if(f > 0.0) { mAttSizeExtraFactor = f; this->Pipeline()->UpdateContents(iParticleGroupPipeline::_AttToSize); this->ClearCache(); } } void iParticleGroup::SetFixedSize(float s) { if(s>0.0 && s<1000.1) { mSize = s; if(mType == PointGlyphType::Point) mActors[0]->GetProperty()->SetPointSize(mSize); this->Pipeline()->UpdateContents(iParticleGroupPipeline::_FixedSize); this->ClearCache(); } } void iParticleGroup::SetAutoScaled(bool s) { if(s != mAutoScaled) { mAutoScaled = s; iRequiredCast(INFO,mCameraEventObserver)->Activate(s); this->ClearCache(); } } void iParticleGroup::SetStretchToColor(int s) { mStretchToColor = s; this->UpdateColorLookupTable(); this->ClearCache(); } void iParticleGroup::SetLowerLimitToColor(float s) { if(mAttColor >= 0) { this->GetLimits()->UpdateLowerLimit(s,mAttColor,mLimitsToColor[0],mLimitsToColor[1]); this->UpdateColorLookupTable(); this->ClearCache(); } } void iParticleGroup::SetUpperLimitToColor(float s) { if(mAttColor >= 0) { this->GetLimits()->UpdateUpperLimit(s,mAttColor,mLimitsToColor[0],mLimitsToColor[1]); this->UpdateColorLookupTable(); this->ClearCache(); } } void iParticleGroup::UpdateColorLookupTable() { if(mAttColor >= 0) { mActors[0]->SetScalarRange(mLimitsToColor[0],mLimitsToColor[1]); mActors[0]->GetLookupTable()->SetStretch(mStretchToColor); mActors[1]->SetScalarRange(mLimitsToColor[0],mLimitsToColor[1]); mActors[1]->GetLookupTable()->SetStretch(mStretchToColor); this->ClearCache(); } } void iParticleGroup::SetStretchToSize(int s) { if(mAttSize>=0 && mAttSizeGetLimits()->GetNumVars()) { this->GetLimits()->SetStretch(mAttSize,s); this->Pipeline()->UpdateContents(iParticleGroupPipeline::_AttToSize); this->ClearCache(); } } int iParticleGroup::GetStretchToSize() const { if(mAttSize>=0 && mAttSizeGetLimits()->GetNumVars()) { return this->GetLimits()->GetStretch(mAttSize); } else { return iDataStretch::Linear; } } void iParticleGroup::SetLowerLimitToSize(float s) { if(mAttSize>=0 && mAttSizeGetLimits()->GetNumVars()) { this->GetLimits()->SetLowerLimit(mAttSize,s); this->Pipeline()->UpdateContents(iParticleGroupPipeline::_AttToSize); this->ClearCache(); } } float iParticleGroup::GetLowerLimitToSize() const { if(mAttSize>=0 && mAttSizeGetLimits()->GetNumVars()) { return this->GetLimits()->GetLowerLimit(mAttSize); } else { return iMath::_FloatMin; } } void iParticleGroup::SetUpperLimitToSize(float s) { if(mAttSize>=0 && mAttSizeGetLimits()->GetNumVars()) { this->GetLimits()->SetUpperLimit(mAttSize,s); this->Pipeline()->UpdateContents(iParticleGroupPipeline::_AttToSize); this->ClearCache(); } } float iParticleGroup::GetUpperLimitToSize() const { if(mAttSize>=0 && mAttSizeGetLimits()->GetNumVars()) { return this->GetLimits()->GetUpperLimit(mAttSize); } else { return iMath::_FloatMax; } } void iParticleGroup::ShowBody(bool show) { if(show) { this->SetStretchToColor(mStretchToColor); mActors[0]->VisibilityOn(); if(mType != PointGlyphType::Point) mActors[1]->VisibilityOn(); } else { mActors[0]->VisibilityOff(); mActors[1]->VisibilityOff(); } } float iParticleGroup::GetExtraMemorySize() const { return mConnector->GetMemorySize(); } // // Two functions used in saving/restoring the state and in creating new instances with - ask the parent to help // void iParticleGroup::SolidViewSubjectPackStateBody(iString &s) const { this->PackValue(s,KeyType(),mType); this->PackValue(s,KeyAttributeToColor(),mAttColor); this->PackValue(s,KeyAttributeToSize(),mAttSize); this->PackValue(s,KeyFixedSize(),mSize); this->PackValue(s,KeyStretchToColor(),mStretchToColor); this->PackValue(s,KeyLowerLimitToColor(),mLimitsToColor[0]); this->PackValue(s,KeyUpperLimitToColor(),mLimitsToColor[1]); this->PackValue(s,KeyStretchToSize(),this->GetStretchToSize()); this->PackValue(s,KeyLowerLimitToSize(),this->GetLowerLimitToSize()); this->PackValue(s,KeyUpperLimitToSize(),this->GetUpperLimitToSize()); this->PackValue(s,KeyAttributeSizeDirect(),mAttSizeDirect); this->PackValue(s,KeyAttributeSizeExtraFactor(),mAttSizeExtraFactor); this->PackValue(s,KeyLineWidth(),mLineWidth); this->PackValue(s,KeyAutoScaled(),mAutoScaled); this->PackValue(s,KeyAttributeToConnect(),this->GetAttributeToConnect()); this->PackValue(s,KeyAttributeToSeparate(),this->GetAttributeToSeparate()); this->PackValuePiecewiseFunction(s,KeySizeFunction(),mSF); } void iParticleGroup::SolidViewSubjectUnPackStateBody(const iString &s) { int i; bool b; float f; if(this->UnPackValue(s,KeyType(),i)) this->SetType(i); if(this->UnPackValue(s,KeyAttributeToColor(),i)) this->SetAttributeToColor(i); if(this->UnPackValue(s,KeyAttributeToSize(),i)) this->SetAttributeToSize(i); if(this->UnPackValue(s,KeyFixedSize(),f)) this->SetFixedSize(f); if(this->UnPackValue(s,KeyStretchToColor(),i)) this->SetStretchToColor(i); if(this->UnPackValue(s,KeyLowerLimitToColor(),f)) this->SetLowerLimitToColor(f); if(this->UnPackValue(s,KeyUpperLimitToColor(),f)) this->SetUpperLimitToColor(f); if(this->UnPackValue(s,KeyStretchToSize(),i)) this->SetStretchToSize(i); if(this->UnPackValue(s,KeyLowerLimitToSize(),f)) this->SetLowerLimitToSize(f); if(this->UnPackValue(s,KeyUpperLimitToSize(),f)) this->SetUpperLimitToSize(f); if(this->UnPackValue(s,KeyAttributeSizeDirect(),b)) this->SetAttributeSizeDirect(b); if(this->UnPackValue(s,KeyAttributeSizeExtraFactor(),f)) this->SetAttributeSizeExtraFactor(f); if(this->UnPackValue(s,KeyLineWidth(),i)) this->SetLineWidth(i); if(this->UnPackValue(s,KeyAutoScaled(),b)) this->SetAutoScaled(b); if(this->UnPackValue(s,KeyAttributeToConnect(),i)) this->SetAttributeToConnect(i); if(this->UnPackValue(s,KeyAttributeToSeparate(),i)) this->SetAttributeToSeparate(i); if(this->UnPackValuePiecewiseFunction(s,KeySizeFunction(),mSF)) this->ClearCache(); // this unpacks into the appropriate function automatically. } void iParticleGroup::SetAttributeToConnect(int a) { mConnector->SetAttributeToConnect(a); this->ClearCache(); } int iParticleGroup::GetAttributeToConnect() const { return mConnector->GetAttributeToConnect(); } void iParticleGroup::SetAttributeToSeparate(int a) { mConnector->SetAttributeToSeparate(a); this->ClearCache(); } int iParticleGroup::GetAttributeToSeparate() const { return mConnector->GetAttributeToSeparate(); } void iParticleGroup::ShowColorBarsBody(bool) { } bool iParticleGroup::CanBeShown() const { return true; } iFunctionMapping* iParticleGroup::GetSizeFunction() const { mCacheInvalid = true; return mFunction; } void iParticleGroup::ViewSubjectSyncWithData(const iDataSyncRequest &r) { if(this->IsThereData()) { mHistogramMaker->SetInput(mConnector->GetOutput(),-1); } else { mHistogramMaker->SetInput(0,-1); } if(mAttColor > this->GetLimits()->GetNumVars()) this->SetAttributeToColor(-1); if(mAttSize > this->GetLimits()->GetNumVars()) this->SetAttributeToSize(-1); if(r.Var()>0 && r.Var()==mAttColor) { this->GetLimits()->BlockNotifications(true); this->SetLowerLimitToColor(mLimitsToColor[0]); this->SetUpperLimitToColor(mLimitsToColor[1]); this->GetLimits()->BlockNotifications(false); } if(r.Var()>0 && r.Var()==mAttSize) { this->Pipeline()->UpdateContents(iParticleGroupPipeline::_AttToSize); } this->UpdateColorLookupTable(); mFunction->AttachToLimits(this->GetLimits(),mAttSize); } iViewSubjectPipeline* iParticleGroup::CreatePipeline(int) { return new iParticleGroupPipeline(this); } void iParticleGroup::ConfigureMainPipeline(iViewSubjectPipeline *p, int) { iViewSubjectParallelPipeline *pp = iRequiredCast(INFO,p); pp->GetDataManager()->AddDistributor(new iPolyDataDistributor(pp->GetDataManager())); pp->GetDataManager()->AddCollector(new iPolyDataCollector(pp->GetDataManager(),0)); } ifrit-3.4.2/core/iparticlegroup.h0000755000175700010010000001237612167404416015355 0ustar HomeNone/*========================================================================= Program: Ionization FRont Interactive Tool (IFRIT) Language: C++ Copyright (c) 2002-2012 Nick Gnedin All rights reserved. This file may be distributed and/or modified under the terms of the GNU General Public License version 2 as published by the Free Software Foundation and appearing in the file LICENSE.GPL included in the packaging of this file. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHORS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. =========================================================================*/ #ifndef IPARTICLEGROUP_H #define IPARTICLEGROUP_H #include "isolidviewsubject.h" class iEventObserver; class iFunctionMapping; class iHistogramMaker; class iParticleConnector; class iParticlesViewSubject; class iPiecewiseFunction; class vtkPolyData; class iParticleGroup : public iSolidViewSubject { friend class iParticleGroupFamily; friend class iParticlesViewSubject; public: vtkTypeMacro(iParticleGroup,iSolidViewSubject); static iParticleGroup* New(iParticlesViewSubject *parent = 0); // needed for creating a special iParticleGroupFamily by iParticlesViewSubject static const iObjectType& Type(); IOBJECT_DECLARE_GETSET1(Type,int); //void SetType(int t); //inline int GetType() const { return mType; } IOBJECT_DECLARE_GETSET(AttributeToColor,mAttColor,int); //void SetAttributeToColor(int a); //inline int GetAttributeToColor() const { return mAttColor; } IOBJECT_DECLARE_GETSET(AttributeToSize,mAttSize,int); //void SetAttributeToSize(int a); //inline int GetAttributeToSize() const { return mAttSize; } IOBJECT_DECLARE_GETSET(FixedSize,mSize,float); //void SetFixedSize(float s); //inline float GetFixedSize() const { return mSize; } IOBJECT_DECLARE_GETSET1(StretchToColor,int); //void SetStretchToColor(int s); //inline int GetStretchToColor() const { return mStretchToColor; } IOBJECT_DECLARE_GETSET(LowerLimitToColor,mLimitsToColor[0],float); //void SetLowerLimitToColor(float s); //inline float GetLowerLimitToColor() const { return mLimitsToColor[0]; } IOBJECT_DECLARE_GETSET(UpperLimitToColor,mLimitsToColor[1],float); //void SetUpperLimitToColor(float s); //inline float GetUpperLimitToColor() const { return mLimitsToColor[1]; } IOBJECT_DECLARE_GETSET2(StretchToSize,int); //void SetStretchToSize(int s); //int GetStretchToSize() const; IOBJECT_DECLARE_GETSET2(LowerLimitToSize,float); //void SetLowerLimitToSize(float s); //float GetLowerLimitToSize() const; IOBJECT_DECLARE_GETSET2(UpperLimitToSize,float); //void SetUpperLimitToSize(float s); //float GetUpperLimitToSize() const; IOBJECT_DECLARE_GETSET(AttributeSizeDirect,mAttSizeDirect,bool); //void SetAttributeSizeDirect(bool s); //inline bool GetAttributeSizeDirect() const { return mAttSizeDirect; } IOBJECT_DECLARE_GETSET(AttributeSizeExtraFactor,mAttSizeExtraFactor,float); //void SetAttributeSizeExtraFactor(float f); //inline float GetAttributeSizeExtraFactor() const { return mAttSizeExtraFactor; } IOBJECT_DECLARE_GETSET1(LineWidth,int); //void SetLineWidth(int s); //inline int GetLineWidth() const { return mLineWidth; } IOBJECT_DECLARE_GETSET1(AutoScaled,bool); //void SetAutoScaled(bool s); //inline bool GetAutoScaled() const { return mAutoScaled; } IOBJECT_DECLARE_GETSET2(AttributeToConnect,int); //void SetAttributeToConnect(int a); //int GetAttributeToConnect() const; IOBJECT_DECLARE_GETSET2(AttributeToSeparate,int); //void SetAttributeToSeparate(int a); //int GetAttributeToSeparate() const; IOBJECT_DECLARE_GET2(SizeFunction,iFunctionMapping * ); //inline iFunctionMapping* GetSizeFunction() const; virtual void UpdateColorLookupTable(); void SetInput(vtkPolyData *input); // // Inherited members // virtual iViewSubjectPipeline* CreatePipeline(int id); ISOLIDVIEWSUBJECT_DECLARE_INHERITED_KEYS; ISOLIDVIEWSUBJECT_DECLARE_INHERITED_MEMBERS; protected: iParticleGroup(iParticlesViewSubject *parent); virtual ~iParticleGroup(); virtual void ConfigureBody(); virtual void ConfigureMainPipeline(iViewSubjectPipeline *p, int id); virtual void FinishInitialization(); virtual float GetExtraMemorySize() const; private: iParticlesViewSubject *mParent; int mParentIndex; int mAttColor, mAttSize; bool mAttSizeDirect, mAutoScaled; float mAttSizeExtraFactor; int mType; iPiecewiseFunction *mSF; iFunctionMapping *mFunction; float mSize; int mStretchToColor, mLineWidth; float mLimitsToColor[2]; // // VTK members // iParticleConnector *mConnector; iHistogramMaker *mHistogramMaker; iEventObserver *mSizeFunctionEventObserver, *mCameraEventObserver; }; #endif // IPARTICLEGROUP_H ifrit-3.4.2/core/iparticlegrouppipeline.cpp0000755000175700010010000000666212167404434017437 0ustar HomeNone/*========================================================================= Program: Ionization FRont Interactive Tool (IFRIT) Language: C++ Copyright (c) 2002-2012 Nick Gnedin All rights reserved. This file may be distributed and/or modified under the terms of the GNU General Public License version 2 as published by the Free Software Foundation and appearing in the file LICENSE.GPL included in the packaging of this file. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHORS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. =========================================================================*/ #include "iparticlegrouppipeline.h" #include "ierror.h" #include "iparticledataconverter.h" #include "iparticlegroup.h" #include "ireplicatedpolydata.h" // // Templates // #include "iarraytemplate.h" #include "igenericfiltertemplate.h" #include "iviewsubjectpipelinetemplate.h" // // iParticleGroupPipeline class // iParticleGroupPipeline::iParticleGroupPipeline(iParticleGroup *s) : iViewSubjectPipeline(s,1) { mParent = s; // // Do VTK stuff // mDataConverter = this->CreateFilter(); mDataReplicated = this->CreateFilter(); mDataReplicated->SetInput(mDataConverter->GetOutput()); this->UpdateContents(_All); } iParticleGroupPipeline::~iParticleGroupPipeline() { } void iParticleGroupPipeline::ProduceOutput() { vtkPolyData *output = this->GetOutput(); vtkPolyData *input = vtkPolyData::SafeDownCast(this->GetInput()); if(input == 0) { IERROR_FATAL("iParticleGroupPipeline is configured incorrectly."); return; } if(mDataConverter->GetInput() != input) { mDataConverter->SetInput(input); } // // Update the pipeline // mDataReplicated->Update(); output->ShallowCopy(mDataReplicated->GetOutput()); } float iParticleGroupPipeline::GetContentsMemorySize() const { float s = 0.0; s += mDataConverter->GetMemorySize(); s += mDataReplicated->GetMemorySize(); return s; } void iParticleGroupPipeline::UpdateContents(int n, int) { if(n==_All || n==_AttToSize) this->UpdateAttToSize(); if(n==_All || n==_FixedSize) this->UpdateFixedSize(); if(n==_All || n==_Replicas) this->UpdateReplicas(); if(n==_All || n==_SizeFunction) this->UpdateSizeFunction(); if(n==_All || n==_Type) this->UpdateType(); } void iParticleGroupPipeline::UpdateAttToSize() { mDataConverter->Modified(); this->Modified(); } void iParticleGroupPipeline::UpdateType() { mDataConverter->SetType(mParent->GetType()); this->Modified(); } void iParticleGroupPipeline::UpdateFixedSize() { mDataConverter->SetSize(mParent->GetFixedSize()); this->Modified(); } void iParticleGroupPipeline::UpdateReplicas() { mDataReplicated->Modified(); this->Modified(); } void iParticleGroupPipeline::UpdateSizeFunction() { mDataConverter->Modified(); this->Modified(); } ifrit-3.4.2/core/iparticlegrouppipeline.h0000755000175700010010000000440612167404416017076 0ustar HomeNone/*========================================================================= Program: Ionization FRont Interactive Tool (IFRIT) Language: C++ Copyright (c) 2002-2012 Nick Gnedin All rights reserved. This file may be distributed and/or modified under the terms of the GNU General Public License version 2 as published by the Free Software Foundation and appearing in the file LICENSE.GPL included in the packaging of this file. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHORS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. =========================================================================*/ #ifndef IPARTICLEGROUPPIPELINE_H #define IPARTICLEGROUPPIPELINE_H #include "iviewsubjectpipeline.h" class iParticleDataConverter; class iParticleGroup; class iReplicatedPolyData; class vtkPolyData; class iParticleGroupPipeline : public iViewSubjectPipeline { friend class iParticleGroup; public: enum { _AttToSize = iViewSubjectPipeline::__Last, _FixedSize, _SizeFunction, _Type, __Last }; vtkTypeMacro(iParticleGroupPipeline,iViewSubjectPipeline); virtual void UpdateContents(int n, int info = 0); protected: iParticleGroupPipeline(iParticleGroup *s); virtual ~iParticleGroupPipeline(); virtual void ProduceOutput(); virtual float GetContentsMemorySize() const; // // Pipeline operation // virtual void UpdateAttToSize(); virtual void UpdateFixedSize(); virtual void UpdateReplicas(); virtual void UpdateSizeFunction(); virtual void UpdateType(); iParticleGroup *mParent; iParticleDataConverter *mDataConverter; iReplicatedPolyData *mDataReplicated; }; #endif // IPARTICLEGROUPPIPELINE_H ifrit-3.4.2/core/iparticleprobefilter.cpp0000755000175700010010000000523712167404434017067 0ustar HomeNone/*========================================================================= Program: Ionization FRont Interactive Tool (IFRIT) Language: C++ Copyright (c) 2002-2012 Nick Gnedin All rights reserved. This file may be distributed and/or modified under the terms of the GNU General Public License version 2 as published by the Free Software Foundation and appearing in the file LICENSE.GPL included in the packaging of this file. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHORS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. =========================================================================*/ #include "iparticleprobefilter.h" #include "ierror.h" #include "iviewsubject.h" #include #include // // Templates // #include "igenericfiltertemplate.h" iParticleProbeFilter::iParticleProbeFilter(iViewSubject *vo) : iProbeFilter(vo) { } void iParticleProbeFilter::ProduceOutput() { vtkDataObject *input = this->GetInput(); vtkDataSet *output = this->GetOutput(); vtkDataObject *source = this->GetSource(); output->ShallowCopy(input); if(source->IsA("vtkDataSet") && input->IsA("vtkPointSet") && output->IsA("vtkPointSet")) { vtkDataArray *atts = vtkDataSet::SafeDownCast(source)->GetPointData()->GetScalars(); if(atts!=0 && atts->GetSize()>0) { vtkFloatArray *outScalars = vtkFloatArray::New(); IERROR_ASSERT(outScalars); outScalars->SetNumberOfComponents(atts->GetNumberOfComponents()); vtkPointLocator *locator = vtkPointLocator::New(); IERROR_ASSERT(locator); locator->SetDataSet(vtkDataSet::SafeDownCast(source)); locator->BuildLocator(); vtkPoints *pts = vtkPointSet::SafeDownCast(input)->GetPoints(); vtkIdType i, l, n = pts->GetNumberOfPoints(); for(i=0; iFindClosestPoint(pts->GetPoint(i)); if(l != -1) outScalars->InsertNextTuple(atts->GetTuple(l)); else outScalars->InsertNextTuple(atts->GetTuple(0)); } output->GetPointData()->SetScalars(outScalars); outScalars->Delete(); locator->Delete(); } } } ifrit-3.4.2/core/iparticleprobefilter.h0000644000175700010010000000302012167404416016515 0ustar HomeNone/*========================================================================= Program: Ionization FRont Interactive Tool (IFRIT) Language: C++ Copyright (c) 2002-2012 Nick Gnedin All rights reserved. This file may be distributed and/or modified under the terms of the GNU General Public License version 2 as published by the Free Software Foundation and appearing in the file LICENSE.GPL included in the packaging of this file. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHORS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. =========================================================================*/ #ifndef IPARTICLEPROBEFILTER_H #define IPARTICLEPROBEFILTER_H #include "iprobefilter.h" class iParticleProbeFilter : public iProbeFilter { IGENERICFILTER_DECLARE(iParticleProbeFilter,iProbeFilter); protected: virtual void ProduceOutput(); }; #endif // IPARTICLEPROBEFILTER_H ifrit-3.4.2/core/iparticlesplitter.cpp0000755000175700010010000003531212167404434016415 0ustar HomeNone/*========================================================================= Program: Ionization FRont Interactive Tool (IFRIT) Language: C++ Copyright (c) 2002-2012 Nick Gnedin All rights reserved. This file may be distributed and/or modified under the terms of the GNU General Public License version 2 as published by the Free Software Foundation and appearing in the file LICENSE.GPL included in the packaging of this file. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHORS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. =========================================================================*/ #include "iparticlesplitter.h" #include "idatalimits.h" #include "idatastretch.h" #include "ierror.h" #include "ihistogrammaker.h" #include "irangecollection.h" #include "irangemapping.h" #include "iviewmodule.h" #include "iviewsubject.h" #include #include #include #include #include #include #include // // Templates (needed for some compilers) // #include "iarraytemplate.h" #include "igenericfiltertemplate.h" float iParticleSplitter::mAttRange = iMath::_LargeFloat; namespace iParticleSplitter_Private { // // QuickFind // #define ARR(i) Atts[ncom*(i)+attSort] bool Find(vtkIdType n, int ncom, int attSort, float *Atts, vtkIdType iStart, float aval, vtkIdType &iLo, vtkIdType &iHi) { vtkIdType i1 = iStart; vtkIdType i2 = n - 1; vtkIdType ic; if(aval < ARR(i1)) { iLo = i1; iHi = i1; return true; } if(aval > ARR(i2)) { iLo = i2; iHi = i2; return true; } while(i2-i1 > 1) { ic = (i1+i2)/2; if(aval >= ARR(ic)) i1 = ic; if(aval <= ARR(ic)) i2 = ic; } iLo = i1; iHi = i2; return true; } // // QuickSort // #define SAVE(CELL,i1) { for(ii=0; ii<3; ii++) poi##CELL[ii] = Points[3*(i1)+ii]; for(ii=0; ii void SortWorker(iParticleSplitter *me, vtkIdType l, vtkIdType r, int ncom, int attSort, T *Points, float *Atts, float *Nrms, T *poi1, float *att1, float *nrm1) { const int M = 8; vtkIdType i, j; float v; int ii; if(me->GetAbortExecute()) return; if ((r-l)>M) { // // Use quicksort // i = (r+l)/2; if (ARR(l)>ARR(i)) SWAP(l,i); // Tri-Median Method! if (ARR(l)>ARR(r)) SWAP(l,r); if (ARR(i)>ARR(r)) SWAP(i,r); j = r-1; SWAP(i,j); i = l; v = ARR(j); for(;;) { do i++; while(ARR(i) < v); // no ++i/--j in macro expansion! do j--; while(ARR(j) > v); if (jl && ARR(j-1)>v) { MOVE(j,j-1); j--; } RESTORE(j,1); } } } // // Do our own quick sort for efficiency reason (based on a Java code by Denis Ahrens) // template void Sort(iParticleSplitter *me, vtkIdType n, int ncom, int attSort, T *Points, float *Atts, float* Nrms) { T poi1[3]; float nrm1[3]; float *att1; att1 = new float[ncom]; IERROR_ASSERT(att1); SortWorker(me,0,n-1,ncom,attSort,Points,Atts,Nrms,poi1,att1,nrm1); delete [] att1; } }; using namespace iParticleSplitter_Private; iParticleSplitter::iParticleSplitter(iViewSubject *vo) : iGenericPolyDataToPolyDataFilter(vo,1,true,true) { mRangeSet = mOwnsData = false; mSavedPoints = 0; mSavedVerts = 0; mSavedNorms = 0; mSavedAtts = 0; // // Splitter functionality // mAtt = -1; mSorted = false; mRanges = new iRangeCollection; IERROR_ASSERT(mRanges); mHistogramMaker = iHistogramMaker::New(this->GetViewSubject()->GetViewModule()); IERROR_ASSERT(mHistogramMaker); mMapping = new iRangeMapping(mRanges,mHistogramMaker,this); IERROR_ASSERT(mRanges); mRanges->SetGlobalRange(-mAttRange,mAttRange); mRanges->SetRange(0,-mAttRange,mAttRange); mSortingMTime = 0; } iParticleSplitter::~iParticleSplitter() { mHistogramMaker->Delete(); delete mRanges; delete mMapping; if(mOwnsData) { mSavedPoints->Delete(); mSavedVerts->Delete(); mSavedNorms->Delete(); mSavedAtts->Delete(); } } int iParticleSplitter::GetNumberOfPieces() const { return mRanges->GetN(); } float iParticleSplitter::GetMemorySize() const { float s = 0.0; if(mOwnsData) { s += mSavedPoints->GetActualMemorySize(); s += mSavedVerts->GetActualMemorySize(); s += mSavedNorms->GetActualMemorySize(); s += mSavedAtts->GetActualMemorySize(); } return s; } iRangeMapping* iParticleSplitter::GetSplitRanges() { this->Modified(); return mMapping; } bool iParticleSplitter::CreateGroup() { if(mAtt == -1) return false; // // Create a new piece // vtkPolyData *newOutput; newOutput = vtkPolyData::New(); if(newOutput == 0) { return false; } this->AddOutput(newOutput); newOutput->Delete(); mRanges->AddRange(); this->Modified(); return true; } bool iParticleSplitter::DeleteGroup(int n) { if(mRanges->RemoveRange(n)) { int i; for(i=n; iGetN(); i++) { this->SetNthOutput(i,this->GetOutput(i+1)); } this->SetNumberOfOutputs(mRanges->GetN()); return true; } else return false; } void iParticleSplitter::SetSplitRangesStretch(int s) { mRanges->SetStretch(s); this->Modified(); } int iParticleSplitter::GetSplitRangesStretch() const { return mRanges->GetStretch(); } void iParticleSplitter::SetSplitRangesTiled(bool s) { mRanges->SetTiled(s); this->Modified(); } bool iParticleSplitter::GetSplitRangesTiled() const { return mRanges->GetTiled(); } void iParticleSplitter::SetSplitRangesMinMax(float amin, float amax) { mRanges->SetGlobalRange(amin,amax); this->Modified(); } void iParticleSplitter::GetSplitRangesMinMax(float &amin, float &amax) const { amin = mRanges->GetGlobalMin(); amax = mRanges->GetGlobalMax(); } void iParticleSplitter::SetSplitRangeLimits(int n, float amin, float amax) { mRanges->SetRange(n,amin,amax); this->Modified(); } void iParticleSplitter::GetSplitRangeLimits(int n, float &amin, float &amax) const { mRanges->GetRange(n,amin,amax); } void iParticleSplitter::TakeOverData(bool s) { if(mOwnsData == s) return; mOwnsData = s; if(mOwnsData) { mSavedPoints = vtkPoints::New(); IERROR_ASSERT(mSavedPoints); mSavedVerts = vtkCellArray::New(); IERROR_ASSERT(mSavedVerts); mSavedNorms = vtkFloatArray::New(); IERROR_ASSERT(mSavedNorms); mSavedAtts = vtkFloatArray::New(); IERROR_ASSERT(mSavedAtts); } else { mSavedPoints->Delete(); mSavedPoints = 0; mSavedVerts->Delete(); mSavedVerts = 0; mSavedNorms->Delete(); mSavedNorms = 0; mSavedAtts->Delete(); mSavedAtts = 0; } this->Modified(); } void iParticleSplitter::SetAttributeToSplit(int a) { // // Reset to a single piece if the attribute changes // if(a!=mAtt && a>=-1 && aGetLimits()->GetNumVars()) { mRanges->SetGlobalRange(-mAttRange,mAttRange); mRanges->SetRange(0,-mAttRange,mAttRange); mAtt = a; mSorted = false; if(a == -1) { mRangeSet = true; mHistogramMaker->SetInput(0,0); } else { mRangeSet = false; mHistogramMaker->SetInput(this->GetInput(),mAtt); this->UpdateRange(); } this->Modified(); } } void iParticleSplitter::UpdateRange() { if(mRangeSet) return; mRangeSet = false; // // Single piece mode // if(mAtt == -1) { mRangeSet = true; return; } vtkPolyData *input = this->GetInput(); if(input == 0) return; vtkFloatArray *inatt = vtkFloatArray::SafeDownCast(input->GetPointData()->GetScalars()); if(inatt == 0) return; float *data = inatt->GetPointer(0); if(data == 0) return; int ncom = inatt->GetNumberOfComponents(); vtkIdType ntup = inatt->GetNumberOfTuples(); if(mAtt >= ncom) return; vtkIdType l; float d; // // Find attribute limits // data += mAtt; // the first component is the number in file float attMin, attMax; attMin = attMax = *data; for(l=1; l attMax) attMax = d; } // // Spread limits a little bit so that even the limiting values are inside the interval // if(attMin < attMax) { // // Find second lower and upper values // float attMin2, attMax2; attMin2 = attMax; attMax2 = attMin; for(l=0; lattMin && dattMax2) attMax2 = d; } attMin -= 0.01*(attMin2-attMin); attMax += 0.01*(attMax-attMax2); } else { if(fabs(attMin) > 1.0) d = 0.0001*fabs(attMin); else d = 0.0001; attMin -= d; attMax += d; } mRanges->SetGlobalRange(attMin,attMax); this->Modified(); mRangeSet = true; } void iParticleSplitter::ProduceOutput() { vtkPolyData *input = this->GetInput(); vtkPolyData *output = this->GetOutput(); output->Initialize(); // // Do it again in case the attribute was Set before the data were loaded, like in // restoring from a state file. // if(!mRangeSet) this->UpdateRange(); // // If updateRange did not Set the range, then the data are still not available, so exit without // doing anything // if(!mRangeSet) return; vtkPoints *newPoints, *oldPoints; vtkCellArray *newVerts, *oldVerts; vtkFloatArray *newNorms, *oldNorms; vtkFloatArray *newAtts, *oldAtts; if(mAtt==-1 || mAtt>=this->GetLimits()->GetNumVars()) { output->ShallowCopy(input); return; } if(mOwnsData) { oldPoints = mSavedPoints; oldVerts = mSavedVerts; oldAtts = mSavedAtts; oldPoints->SetDataType(input->GetPoints()->GetDataType()); oldPoints->DeepCopy(input->GetPoints()); oldVerts->DeepCopy(input->GetVerts()); if(input->GetPointData()->GetNormals() != 0) { oldNorms = mSavedNorms; oldNorms->DeepCopy(input->GetPointData()->GetNormals()); } else { oldNorms = 0; } oldAtts->DeepCopy(input->GetPointData()->GetScalars()); } else { oldPoints = input->GetPoints(); oldVerts = input->GetVerts(); if(input->GetPointData()->GetNormals() != 0) { oldNorms = vtkFloatArray::SafeDownCast(input->GetPointData()->GetNormals()); } else { oldNorms = 0; } oldAtts = vtkFloatArray::SafeDownCast(input->GetPointData()->GetScalars()); } float *pPointsF = 0; double *pPointsD = 0; bool pointsAreFloat; switch(oldPoints->GetDataType()) { case VTK_FLOAT: { pointsAreFloat = true; pPointsF = (float *)oldPoints->GetVoidPointer(0); break; } case VTK_DOUBLE: { pointsAreFloat = false; pPointsD = (double *)oldPoints->GetVoidPointer(0); break; } default: { output->ShallowCopy(input); vtkErrorMacro("Incorrect Points type"); return; } } vtkIdType *pVerts = (vtkIdType *)oldVerts->GetPointer(); float *pNorms = 0; if(oldNorms != 0) pNorms = (float *)oldNorms->GetPointer(0); float *pAtts = (float *)oldAtts->GetPointer(0); int ncom = oldAtts->GetNumberOfComponents(); vtkIdType ntup = oldAtts->GetNumberOfTuples(); if(!mSorted || mSortingMTimeGetMTime()) { mSorted = true; mSortingMTime = input->GetMTime(); if(pointsAreFloat) { Sort(this,ntup,ncom,mAtt,pPointsF,pAtts,pNorms); } else { Sort(this,ntup,ncom,mAtt,pPointsD,pAtts,pNorms); } #ifdef I_CHECK2 for(vtkIdType l=0; l pAtts[mAtt+ncom*(l+1)]) { IERROR_LOW("Sorted incorrectly."); break; } #endif } int n, nmax = mRanges->GetN(); vtkIdType iLo, iHi; vtkIdType iStart, iTotal; vtkFloatArray *fArray; vtkDoubleArray *dArray; vtkIdTypeArray *jArray; for(n=0; nGetMin(n),iLo,iHi)) { vtkErrorMacro("Error #1 in iGroupSplitter"); iLo = iHi = 0; } iStart = iHi; if(!Find(ntup,ncom,mAtt,pAtts,iLo,mRanges->GetMax(n),iLo,iHi)) { vtkErrorMacro("Error #2 in iGroupSplitter"); iLo = iHi = ntup - 1; } iTotal = iLo - iStart + 1; if(iTotal<0 || iStart<0 || iLo>=ntup) { vtkErrorMacro("Error #3 in iGroupSplitter"); } else { output = this->GetOutput(n); output->Initialize(); if(iTotal > 0) { newPoints = vtkPoints::New(oldPoints->GetDataType()); IERROR_ASSERT(newPoints); if(pointsAreFloat) { fArray = vtkFloatArray::New(); IERROR_ASSERT(fArray); fArray->SetNumberOfComponents(3); fArray->SetArray(pPointsF+3*iStart,3*iTotal,1); newPoints->SetData(fArray); fArray->Delete(); } else { dArray = vtkDoubleArray::New(); IERROR_ASSERT(dArray); dArray->SetNumberOfComponents(3); dArray->SetArray(pPointsD+3*iStart,3*iTotal,1); newPoints->SetData(dArray); dArray->Delete(); } output->SetPoints(newPoints); newPoints->Delete(); newAtts = vtkFloatArray::New(); IERROR_ASSERT(newAtts); newAtts->SetNumberOfComponents(ncom); newAtts->SetArray(pAtts+ncom*iStart,ncom*iTotal,1); output->GetPointData()->SetScalars(newAtts); newAtts->Delete(); if(oldNorms != 0) { newNorms = vtkFloatArray::New(); IERROR_ASSERT(newNorms); newNorms->SetNumberOfComponents(3); newNorms->SetArray(pNorms+3*iStart,3*iTotal,1); output->GetPointData()->SetNormals(newNorms); newNorms->Delete(); } newVerts = vtkCellArray::New(); IERROR_ASSERT(newVerts); jArray = vtkIdTypeArray::New(); IERROR_ASSERT(jArray); jArray->SetNumberOfComponents(1); jArray->SetArray(pVerts,2*iTotal,1); newVerts->SetCells(iTotal,jArray); jArray->Delete(); output->SetVerts(newVerts); newVerts->Delete(); } } } } void iParticleSplitter::SyncWithData(const iDataSyncRequest &r) { if(r.Var()==-1 || r.Var()==mAtt) { this->Modified(); mRangeSet = false; } } ifrit-3.4.2/core/iparticlesplitter.h0000755000175700010010000000561512167404416016065 0ustar HomeNone/*========================================================================= Program: Ionization FRont Interactive Tool (IFRIT) Language: C++ Copyright (c) 2002-2012 Nick Gnedin All rights reserved. This file may be distributed and/or modified under the terms of the GNU General Public License version 2 as published by the Free Software Foundation and appearing in the file LICENSE.GPL included in the packaging of this file. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHORS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. =========================================================================*/ #ifndef IPARTICLESPLITTER_H #define IPARTICLESPLITTER_H #include "igenericfilter.h" #include class iHistogramMaker; class iRangeCollection; class iRangeMapping; class vtkPoints; class vtkCellArray; class vtkFloatArray; class vtkFloatArray; class iParticleSplitter : public iGenericPolyDataToPolyDataFilter { IGENERICFILTER_DECLARE(iParticleSplitter,vtkPolyDataToPolyDataFilter); public: int GetNumberOfPieces() const; void SetAttributeToSplit(int a); inline int GetAttributeToSplit() const { return mAtt; } void SetSplitRangesStretch(int s); int GetSplitRangesStretch() const; void SetSplitRangesTiled(bool s); bool GetSplitRangesTiled() const; void SetSplitRangesMinMax(float amin, float amax); void GetSplitRangesMinMax(float &amin, float &amax) const; void SetSplitRangeLimits(int n, float amin, float amax); void GetSplitRangeLimits(int n, float &amin, float &amax) const; void ResetRange(){ mRangeSet = false; } bool CreateGroup(); bool DeleteGroup(int n); iRangeMapping* GetSplitRanges(); // for direct access void TakeOverData(bool); float GetMemorySize() const; protected: virtual ~iParticleSplitter(); virtual void SyncWithData(const iDataSyncRequest &r); virtual void ProduceOutput(); private: void UpdateRange(); bool mRangeSet, mOwnsData; int mAtt; static float mAttRange; bool mSorted; iRangeCollection *mRanges; iRangeMapping *mMapping; iHistogramMaker *mHistogramMaker; vtkPoints *mSavedPoints; vtkCellArray *mSavedVerts; vtkFloatArray *mSavedNorms; vtkFloatArray *mSavedAtts; unsigned long mSortingMTime; }; #endif // IPARTICLESPLITTER_H ifrit-3.4.2/core/iparticlesviewsubject.cpp0000755000175700010010000006006712167404434017271 0ustar HomeNone/*========================================================================= Program: Ionization FRont Interactive Tool (IFRIT) Language: C++ Copyright (c) 2002-2012 Nick Gnedin All rights reserved. This file may be distributed and/or modified under the terms of the GNU General Public License version 2 as published by the Free Software Foundation and appearing in the file LICENSE.GPL included in the packaging of this file. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHORS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. =========================================================================*/ #include "iparticlesviewsubject.h" #include "iactor.h" #include "ibuffer.h" #include "ierror.h" #include "ifunctionmapping.h" #include "imath.h" #include "iparticleconnector.h" #include "iparticlegroup.h" #include "iparticlesplitter.h" #include // // Templates // #include "iarraytemplate.h" #include "ibuffertemplate.h" #include "iviewfamilytemplate.h" const int iParticlesViewSubject::CurrentId = iMath::_LargeInt; bool iParticlesViewSubject::mUseFullState = true; using namespace iParameter; class iParticleGroupFamily : public iViewFamily { friend class iParticlesViewSubject; protected: iParticleGroupFamily(iParticlesViewSubject *p) : iViewFamily(p) { mParent = p; mMemlist[0]->mParentIndex = 0; } virtual int CreateMember() { int ret = iViewFamily::CreateMember(); if(ret >= 0) { mMemlist[ret]->mParentIndex = ret; } return ret; } virtual bool DeleteMember(int i) { bool ret = iViewFamily::DeleteMember(i); if(ret) { int j; for(j=i; jmParentIndex = j; } return ret; } private: iParticlesViewSubject *mParent; }; // // Main class // IVIEWSUBJECT_DEFINE_TYPE(iParticlesViewSubject,Particles,p); IOBJECT_DEFINE_KEY(iParticlesViewSubject,AttributeToSplit,a,OffsetInt,1); IOBJECT_DEFINE_KEY(iParticlesViewSubject,AttributeToColor,ac,OffsetInt,0); IOBJECT_DEFINE_KEY(iParticlesViewSubject,AttributeSizeDirect,ad,Bool,0); IOBJECT_DEFINE_KEY(iParticlesViewSubject,AttributeSizeExtraFactor,ae,Float,0); IOBJECT_DEFINE_KEY(iParticlesViewSubject,AttributeToSize,as,OffsetInt,0); IOBJECT_DEFINE_KEY(iParticlesViewSubject,AttributeToConnect,atc,OffsetInt,0); IOBJECT_DEFINE_KEY(iParticlesViewSubject,AttributeToSeparate,ats,OffsetInt,0); IOBJECT_DEFINE_KEY(iParticlesViewSubject,AutoScaled,au,Bool,0); IOBJECT_DEFINE_KEY(iParticlesViewSubject,Color,c,Color,0); IOBJECT_DEFINE_KEY(iParticlesViewSubject,CurrentGroup,cg,OffsetInt,1); IOBJECT_DEFINE_KEY(iParticlesViewSubject,StretchToColor,stc,Int,0); IOBJECT_DEFINE_KEY(iParticlesViewSubject,LowerLimitToColor,ltc,Float,0); IOBJECT_DEFINE_KEY(iParticlesViewSubject,UpperLimitToColor,utc,Float,0); IOBJECT_DEFINE_KEY(iParticlesViewSubject,StretchToSize,sts,Int,0); IOBJECT_DEFINE_KEY(iParticlesViewSubject,LowerLimitToSize,lts,Float,0); IOBJECT_DEFINE_KEY(iParticlesViewSubject,UpperLimitToSize,uts,Float,0); IOBJECT_DEFINE_KEY(iParticlesViewSubject,LineWidth,lw,Int,0); IOBJECT_DEFINE_KEY(iParticlesViewSubject,MaxGroup,mg,OffsetInt,1); IOBJECT_DEFINE_KEY(iParticlesViewSubject,Opacity,o,Float,0); IOBJECT_DEFINE_KEY(iParticlesViewSubject,Palette,p,Int,0); IOBJECT_DEFINE_KEY(iParticlesViewSubject,SplitRangeLowerLimit,rl,Float,0); IOBJECT_DEFINE_KEY(iParticlesViewSubject,SplitRangesMax,rmax,Float,1); IOBJECT_DEFINE_KEY(iParticlesViewSubject,SplitRangesMin,rmin,Float,1); IOBJECT_DEFINE_KEY(iParticlesViewSubject,SplitRangesStretch,rs,Int,1); IOBJECT_DEFINE_KEY(iParticlesViewSubject,SplitRangesTiled,rt,Bool,1); IOBJECT_DEFINE_KEY(iParticlesViewSubject,SplitRangeUpperLimit,ru,Float,0); IOBJECT_DEFINE_KEY(iParticlesViewSubject,FixedSize,s,Float,0); IOBJECT_DEFINE_KEY(iParticlesViewSubject,SizeFunction,sf,Any,0); IOBJECT_DEFINE_KEY(iParticlesViewSubject,Type,t,Int,0); IOBJECT_DEFINE_KEY(iParticlesViewSubject,SplitRanges,-r,Any,1); // // Inherited keys (define them explicitly since they are now multi-component // IOBJECT_DEFINE_INHERITED_KEY(iViewSubject,iParticlesViewSubject,ClipPlane,cp,Bool,1); IOBJECT_DEFINE_INHERITED_KEY(iViewSubject,iParticlesViewSubject,Ambient,ma,Float,0); IOBJECT_DEFINE_INHERITED_KEY(iViewSubject,iParticlesViewSubject,Diffuse,md,Float,0); IOBJECT_DEFINE_INHERITED_KEY(iViewSubject,iParticlesViewSubject,Specular,ms,Float,0); IOBJECT_DEFINE_INHERITED_KEY(iViewSubject,iParticlesViewSubject,SpecularPower,mp,Float,0); IOBJECT_DEFINE_INHERITED_KEY(iViewSubject,iParticlesViewSubject,Visible,vis,Bool,1); IOBJECT_DEFINE_INHERITED_KEY(iViewSubject,iParticlesViewSubject,DataPresent,dp,Bool,1); IOBJECT_DEFINE_INHERITED_KEY(iViewSubject,iParticlesViewSubject,Ready,r,Bool,1); IOBJECT_DEFINE_INHERITED_KEY(iViewSubject,iParticlesViewSubject,Shading,mw,Bool,0); IVIEWSUBJECT_DEFINE_INHERITED_KEYS_REPLICATING(iParticlesViewSubject); iParticlesViewSubject::iParticlesViewSubject(iViewModule *vm, const iDataType &type, const iString &name, const iColor &color, bool shaded) : iViewSubject(vm,type,name,0U) { mSubjectId = ViewSubject::Id::Particles; mGroups = new iParticleGroupFamily(this); IERROR_ASSERT(mGroups); mSplitter = iParticleSplitter::New(this); IERROR_ASSERT(mSplitter); if(color.IsValid()) mGroups->GetMember(0)->SetColor(0,color); mGroups->GetMember(0)->SetShading(shaded); } iParticlesViewSubject::~iParticlesViewSubject() { delete mGroups; mSplitter->Delete(); } void iParticlesViewSubject::ConfigureBody() { // // Attach the first group // mGroups->GetMember(0)->SetInput(mSplitter->GetOutput()); } void iParticlesViewSubject::BecomeClone(iParticlesViewSubject *v) { mSplitter->TakeOverData(v != 0); this->ClearCache(); } void iParticlesViewSubject::UpdateReplicas() { int i; for(i=0; i<=mGroups->GetMaxMemberIndex(); i++) { mGroups->GetMember(i)->ReplicateAs(this); } } void iParticlesViewSubject::ShowBody(bool s) { mGroups->Show(s); } void iParticlesViewSubject::Reset() { mGroups->Reset(); this->SyncWithData(this->RequestAll()); this->ClearCache(); } void iParticlesViewSubject::ShowClipPlane(bool s) { int i; mClipPlaneOn = s; for(i=0; i<=mGroups->GetMaxMemberIndex(); i++) mGroups->GetMember(i)->ShowClipPlane(s); this->ClearCache(); } void iParticlesViewSubject::ShowColorBars(bool s) { int i; for(i=0; i<=mGroups->GetMaxMemberIndex(); i++) mGroups->GetMember(i)->ShowColorBars(s); this->ClearCache(); } void iParticlesViewSubject::PackStateBody(iString &s) const { static iBuffer fv1, fv2; int i, n = mGroups->GetMaxMemberIndex() + 1; float f1, f2; this->PackValue(s,KeyMaxGroup(),mGroups->GetMaxMemberIndex()); // arrays start with 1 this->PackValue(s,KeyCurrentGroup(),mGroups->GetCurrentMemberIndex()); // arrays start with 1 this->PackValue(s,KeyClipPlane(),mClipPlaneOn); this->PackValue(s,KeyNumReplicas(),mNumReplicas,6); this->PackValue(s,KeyVisible(),this->IsVisible()); this->PackValue(s,KeyDataPresent(),this->IsThereData()); this->PackValue(s,KeyReady(),this->IsReady()); this->PackValue(s,KeyAttributeToSplit(),mSplitter->GetAttributeToSplit()); this->PackValue(s,KeySplitRangesStretch(),mSplitter->GetSplitRangesStretch()); this->PackValue(s,KeySplitRangesTiled(),mSplitter->GetSplitRangesTiled()); mSplitter->GetSplitRangesMinMax(f1,f2); this->PackValue(s,KeySplitRangesMin(),f1); this->PackValue(s,KeySplitRangesMax(),f2); for(i=0; iGetSplitRangeLimits(i,fv1[i],fv2[i]); } this->PackValue(s,KeySplitRangeLowerLimit(),fv1,n); this->PackValue(s,KeySplitRangeUpperLimit(),fv2,n); if(mUseFullState) this->PackGroupStateBody(s,0,mGroups->GetMaxMemberIndex()); } void iParticlesViewSubject::UnPackStateBody(const iString &s0) { static iString rep1 = iObjectKey::LeftBracket() + iObjectKey::RightBracket(); static iString rep2 = iObjectKey::LeftBracket() + "0" + iObjectKey::RightBracket(); static iString rep3 = iObjectKey::LeftBracket() + iString::FromNumber(1+CurrentId) + iObjectKey::RightBracket(); static iBuffer fv1, fv2; int i, n, v, d[6]; bool b; // // Unpack splitter attribute first, so that groups are created correctly // if(this->UnPackValue(s0,KeyAttributeToSplit(),i)) this->SetAttributeToSplit(i); // // Make the size of the group family consistent // if(this->UnPackValue(s0,KeyMaxGroup(),v)) { // // Delete extra groups // while(v < mGroups->GetMaxMemberIndex()) this->DeleteGroup(mGroups->GetMaxMemberIndex()); // // Create missing groups // while(v > mGroups->GetMaxMemberIndex()) this->CreateGroup(); this->ClearCache(); } n = mGroups->GetMaxMemberIndex() + 1; if(this->UnPackValue(s0,KeyCurrentGroup(),v)) { mGroups->SetCurrentMemberIndex(v); // arrays start with 1 this->ClearCache(); } // // Special syntax: replace [] or [0] with []. // iString sub, s = s0; sub = iObjectKey::LeftBracket() + iString::FromNumber(1+mGroups->GetCurrentMemberIndex()) + iObjectKey::RightBracket(); // arrays start with 1 s.Replace(rep1,sub); s.Replace(rep2,sub); s.Replace(rep3,sub); if(this->UnPackValue(s,KeyClipPlane(),b)) this->ShowClipPlane(b); for(i=0; i<6; i++) d[i] = mNumReplicas[i]; if(this->UnPackValue(s,KeyNumReplicas(),d,6)) this->SetNumReplicas(d); if(this->UnPackValue(s,KeySplitRangesStretch(),i)) { mSplitter->SetSplitRangesStretch(i); this->ClearCache(); } if(this->UnPackValue(s,KeySplitRangesTiled(),b)) { mSplitter->SetSplitRangesTiled(b); this->ClearCache(); } float f1, f2; if(this->UnPackValue(s,KeySplitRangesMin(),f1) && this->UnPackValue(s,KeySplitRangesMax(),f2)) { mSplitter->SetSplitRangesMinMax(f1,f2); this->ClearCache(); } for(i=0; iGetSplitRangeLimits(i,fv1[i],fv2[i]); } if(this->UnPackValue(s,KeySplitRangeLowerLimit(),fv1,n) && this->UnPackValue(s,KeySplitRangeUpperLimit(),fv2,n)) for(i=0; iSetSplitRangeLimits(i,fv1[i],fv2[i]); this->ClearCache(); } if(mUseFullState) this->UnPackGroupStateBody(s,0,mGroups->GetMaxMemberIndex()); } void iParticlesViewSubject::PackCompleteState(iString &s) const { bool u = mUseFullState; mUseFullState = true; mCacheInvalid = true; this->PackState(s); mUseFullState = u; } void iParticlesViewSubject::UnPackCompleteState(const iString &s) { bool u = mUseFullState; mUseFullState = true; this->UnPackState(s); mUseFullState = u; } void iParticlesViewSubject::PackGroupStateBody(iString &s, int first, int last) const { static iBuffer iv; static iBuffer bv; static iBuffer fv; static iBuffer dv; static iBuffer cv; static iBuffer pv; int i, n; if(last > mGroups->GetMaxMemberIndex()) last = mGroups->GetMaxMemberIndex(); n = last - first + 1; if(n < 1) return; for(i=first; i<=last; i++) iv[i] = mGroups->GetMember(i)->GetType(); this->PackValue(s,KeyType(),iv+first,n); for(i=first; i<=last; i++) iv[i] = mGroups->GetMember(i)->GetPaletteId(0); this->PackValue(s,KeyPalette(),iv+first,n); for(i=first; i<=last; i++) cv[i] = mGroups->GetMember(i)->GetColor(0); this->PackValue(s,KeyColor(),cv+first,n); for(i=first; i<=last; i++) iv[i] = mGroups->GetMember(i)->GetAttributeToColor(); this->PackValue(s,KeyAttributeToColor(),iv+first,n); for(i=first; i<=last; i++) iv[i] = mGroups->GetMember(i)->GetAttributeToSize(); this->PackValue(s,KeyAttributeToSize(),iv+first,n); for(i=first; i<=last; i++) fv[i] = mGroups->GetMember(i)->GetOpacity(0); this->PackValue(s,KeyOpacity(),fv+first,n); for(i=first; i<=last; i++) fv[i] = mGroups->GetMember(i)->GetFixedSize(); this->PackValue(s,KeyFixedSize(),fv+first,n); for(i=first; i<=last; i++) iv[i] = mGroups->GetMember(i)->GetStretchToColor(); this->PackValue(s,KeyStretchToColor(),iv+first,n); for(i=first; i<=last; i++) fv[i] = mGroups->GetMember(i)->GetLowerLimitToColor(); this->PackValue(s,KeyLowerLimitToColor(),fv+first,n); for(i=first; i<=last; i++) fv[i] = mGroups->GetMember(i)->GetUpperLimitToColor(); this->PackValue(s,KeyUpperLimitToColor(),fv+first,n); for(i=first; i<=last; i++) iv[i] = mGroups->GetMember(i)->GetStretchToSize(); this->PackValue(s,KeyStretchToSize(),iv+first,n); for(i=first; i<=last; i++) fv[i] = mGroups->GetMember(i)->GetLowerLimitToSize(); this->PackValue(s,KeyLowerLimitToSize(),fv+first,n); for(i=first; i<=last; i++) fv[i] = mGroups->GetMember(i)->GetUpperLimitToSize(); this->PackValue(s,KeyUpperLimitToSize(),fv+first,n); for(i=first; i<=last; i++) bv[i] = mGroups->GetMember(i)->GetAttributeSizeDirect(); this->PackValue(s,KeyAttributeSizeDirect(),bv+first,n); for(i=first; i<=last; i++) fv[i] = mGroups->GetMember(i)->GetAttributeSizeExtraFactor(); this->PackValue(s,KeyAttributeSizeExtraFactor(),fv+first,n); for(i=first; i<=last; i++) iv[i] = mGroups->GetMember(i)->GetLineWidth(); this->PackValue(s,KeyLineWidth(),iv+first,n); for(i=first; i<=last; i++) bv[i] = mGroups->GetMember(i)->GetAutoScaled(); this->PackValue(s,KeyAutoScaled(),bv+first,n); for(i=first; i<=last; i++) iv[i] = mGroups->GetMember(i)->GetAttributeToConnect(); this->PackValue(s,KeyAttributeToConnect(),iv+first,n); for(i=first; i<=last; i++) iv[i] = mGroups->GetMember(i)->GetAttributeToSeparate(); this->PackValue(s,KeyAttributeToSeparate(),iv+first,n); for(i=first; i<=last; i++) pv[i] = mGroups->GetMember(i)->GetSizeFunction()->GetFunction(); this->PackValuePiecewiseFunction(s,KeySizeFunction(),pv+first,n); for(i=first; i<=last; i++) bv[i] = mGroups->GetMember(i)->GetShading(); this->PackValue(s,KeyShading(),bv+first,n); for(i=first; i<=last; i++) fv[i] = mGroups->GetMember(i)->GetAmbient(); this->PackValue(s,KeyAmbient(),fv+first,n); for(i=first; i<=last; i++) fv[i] = mGroups->GetMember(i)->GetDiffuse(); this->PackValue(s,KeyDiffuse(),fv+first,n); for(i=first; i<=last; i++) fv[i] = mGroups->GetMember(i)->GetSpecular(); this->PackValue(s,KeySpecular(),fv+first,n); for(i=first; i<=last; i++) fv[i] = mGroups->GetMember(i)->GetSpecularPower(); this->PackValue(s,KeySpecularPower(),fv+first,n); } void iParticlesViewSubject::UnPackGroupStateBody(const iString &s, int first, int last) { static iBuffer iv; static iBuffer bv; static iBuffer fv; static iBuffer dv; static iBuffer cv; static iBuffer pv; int i, n; if(last > mGroups->GetMaxMemberIndex()) last = mGroups->GetMaxMemberIndex(); n = last - first + 1; if(n < 1) return; for(i=first; i<=last; i++) iv[i] = mGroups->GetMember(i)->GetType(); if(this->UnPackValue(s,KeyType(),iv+first,n)) { for(i=first; i<=last; i++) mGroups->GetMember(i)->SetType(iv[i]); this->ClearCache(); } for(i=first; i<=last; i++) iv[i] = mGroups->GetMember(i)->GetPaletteId(0); if(this->UnPackValue(s,KeyPalette(),iv+first,n)) { for(i=first; i<=last; i++) mGroups->GetMember(i)->SetPaletteId(0,iv[i]); this->ClearCache(); } for(i=first; i<=last; i++) cv[i] = mGroups->GetMember(i)->GetColor(0); if(this->UnPackValue(s,KeyColor(),cv+first,n)) { for(i=first; i<=last; i++) mGroups->GetMember(i)->SetColor(0,cv[i]); this->ClearCache(); } for(i=first; i<=last; i++) iv[i] = mGroups->GetMember(i)->GetAttributeToColor(); if(this->UnPackValue(s,KeyAttributeToColor(),iv+first,n)) { for(i=first; i<=last; i++) mGroups->GetMember(i)->SetAttributeToColor(iv[i]); this->ClearCache(); } for(i=first; i<=last; i++) iv[i] = mGroups->GetMember(i)->GetAttributeToSize(); if(this->UnPackValue(s,KeyAttributeToSize(),iv+first,n)) { for(i=first; i<=last; i++) mGroups->GetMember(i)->SetAttributeToSize(iv[i]); this->ClearCache(); } for(i=first; i<=last; i++) fv[i] = mGroups->GetMember(i)->GetOpacity(0); if(this->UnPackValue(s,KeyOpacity(),fv+first,n)) { for(i=first; i<=last; i++) mGroups->GetMember(i)->SetOpacity(0,fv[i]); this->ClearCache(); } for(i=first; i<=last; i++) fv[i] = mGroups->GetMember(i)->GetFixedSize(); if(this->UnPackValue(s,KeyFixedSize(),fv+first,n)) { for(i=first; i<=last; i++) mGroups->GetMember(i)->SetFixedSize(fv[i]); this->ClearCache(); } for(i=first; i<=last; i++) iv[i] = mGroups->GetMember(i)->GetStretchToColor(); if(this->UnPackValue(s,KeyStretchToColor(),iv+first,n)) { for(i=first; i<=last; i++) mGroups->GetMember(i)->SetStretchToColor(iv[i]); this->ClearCache(); } for(i=first; i<=last; i++) fv[i] = mGroups->GetMember(i)->GetLowerLimitToColor(); if(this->UnPackValue(s,KeyLowerLimitToColor(),fv+first,n)) { for(i=first; i<=last; i++) mGroups->GetMember(i)->SetLowerLimitToColor(fv[i]); this->ClearCache(); } for(i=first; i<=last; i++) fv[i] = mGroups->GetMember(i)->GetUpperLimitToColor(); if(this->UnPackValue(s,KeyUpperLimitToColor(),fv+first,n)) { for(i=first; i<=last; i++) mGroups->GetMember(i)->SetUpperLimitToColor(fv[i]); this->ClearCache(); } for(i=first; i<=last; i++) iv[i] = mGroups->GetMember(i)->GetStretchToSize(); if(this->UnPackValue(s,KeyStretchToSize(),iv+first,n)) { for(i=first; i<=last; i++) mGroups->GetMember(i)->SetStretchToSize(iv[i]); this->ClearCache(); } for(i=first; i<=last; i++) fv[i] = mGroups->GetMember(i)->GetLowerLimitToSize(); if(this->UnPackValue(s,KeyLowerLimitToSize(),fv+first,n)) { for(i=first; i<=last; i++) mGroups->GetMember(i)->SetLowerLimitToSize(fv[i]); this->ClearCache(); } for(i=first; i<=last; i++) fv[i] = mGroups->GetMember(i)->GetUpperLimitToSize(); if(this->UnPackValue(s,KeyUpperLimitToSize(),fv+first,n)) { for(i=first; i<=last; i++) mGroups->GetMember(i)->SetUpperLimitToSize(fv[i]); this->ClearCache(); } for(i=first; i<=last; i++) bv[i] = mGroups->GetMember(i)->GetAttributeSizeDirect(); if(this->UnPackValue(s,KeyAttributeSizeDirect(),bv+first,n)) { for(i=first; i<=last; i++) mGroups->GetMember(i)->SetAttributeSizeDirect(bv[i]); this->ClearCache(); } for(i=first; i<=last; i++) fv[i] = mGroups->GetMember(i)->GetAttributeSizeExtraFactor(); if(this->UnPackValue(s,KeyAttributeSizeExtraFactor(),fv+first,n)) { for(i=first; i<=last; i++) mGroups->GetMember(i)->SetAttributeSizeExtraFactor(fv[i]); this->ClearCache(); } for(i=first; i<=last; i++) iv[i] = mGroups->GetMember(i)->GetLineWidth(); if(this->UnPackValue(s,KeyLineWidth(),iv+first,n)) { for(i=first; i<=last; i++) mGroups->GetMember(i)->SetLineWidth(iv[i]); this->ClearCache(); } for(i=first; i<=last; i++) bv[i] = mGroups->GetMember(i)->GetAutoScaled(); if(this->UnPackValue(s,KeyAutoScaled(),bv+first,n)) { for(i=first; i<=last; i++) mGroups->GetMember(i)->SetAutoScaled(bv[i]); this->ClearCache(); } for(i=first; i<=last; i++) iv[i] = mGroups->GetMember(i)->GetAttributeToConnect(); if(this->UnPackValue(s,KeyAttributeToConnect(),iv+first,n)) { for(i=first; i<=last; i++) mGroups->GetMember(i)->SetAttributeToConnect(iv[i]); this->ClearCache(); } for(i=first; i<=last; i++) iv[i] = mGroups->GetMember(i)->GetAttributeToSeparate(); if(this->UnPackValue(s,KeyAttributeToSeparate(),iv+first,n)) { for(i=first; i<=last; i++) mGroups->GetMember(i)->SetAttributeToSeparate(iv[i]); this->ClearCache(); } for(i=first; i<=last; i++) pv[i] = mGroups->GetMember(i)->GetSizeFunction()->GetFunction(); if(this->UnPackValuePiecewiseFunction(s,KeySizeFunction(),pv+first,n)) this->ClearCache(); // this unpacks into the appropriate function automatically. for(i=first; i<=last; i++) bv[i] = mGroups->GetMember(i)->GetShading(); if(this->UnPackValue(s,KeyShading(),bv+first,n)) { for(i=first; i<=last; i++) mGroups->GetMember(i)->SetShading(bv[i]); this->ClearCache(); } for(i=first; i<=last; i++) fv[i] = mGroups->GetMember(i)->GetAmbient(); if(this->UnPackValue(s,KeyAmbient(),fv+first,n)) { for(i=first; i<=last; i++) mGroups->GetMember(i)->SetAmbient(fv[i]); this->ClearCache(); } for(i=first; i<=last; i++) fv[i] = mGroups->GetMember(i)->GetDiffuse(); if(this->UnPackValue(s,KeyDiffuse(),fv+first,n)) { for(i=first; i<=last; i++) mGroups->GetMember(i)->SetDiffuse(fv[i]); this->ClearCache(); } for(i=first; i<=last; i++) fv[i] = mGroups->GetMember(i)->GetSpecular(); if(this->UnPackValue(s,KeySpecular(),fv+first,n)) { for(i=first; i<=last; i++) mGroups->GetMember(i)->SetSpecular(fv[i]); this->ClearCache(); } for(i=first; i<=last; i++) fv[i] = mGroups->GetMember(i)->GetSpecularPower(); if(this->UnPackValue(s,KeySpecularPower(),fv+first,n)) { for(i=first; i<=last; i++) mGroups->GetMember(i)->SetSpecularPower(fv[i]); this->ClearCache(); } } float iParticlesViewSubject::GetMemorySize() const { return mGroups->GetMemorySize() + mSplitter->GetMemorySize(); } bool iParticlesViewSubject::IsVisible() const { return mGroups->IsVisible(); } int iParticlesViewSubject::GetMaxGroupIndex() const { return mGroups->GetMaxMemberIndex(); } int iParticlesViewSubject::GetCurrentGroupIndex() const { return mGroups->GetCurrentMemberIndex(); } iParticleGroup* iParticlesViewSubject::GetCurrentGroup() const { return mGroups->GetCurrentMember(); } iParticleGroup* iParticlesViewSubject::GetGroup(int i) const { return mGroups->GetMember(i); } iRangeMapping* iParticlesViewSubject::GetSplitRanges() { return mSplitter->GetSplitRanges(); } void iParticlesViewSubject::SetCurrentGroupIndex(int i) { mGroups->SetCurrentMemberIndex(i); } int iParticlesViewSubject::CreateGroup() { if(!mSplitter->CreateGroup()) return -1; vtkPolyData *newOutput = mSplitter->GetOutput(mSplitter->GetNumberOfOutputs()-1); // // Create a new piece // int oldGroup = mGroups->GetCurrentMemberIndex(); int newGroup = mGroups->CreateMember(); if(newGroup == -1) { mSplitter->DeleteGroup(mSplitter->GetNumberOfOutputs()-1); return -1; } // // Set the correct piece number // mGroups->GetMember(newGroup)->CopyState(mGroups->GetMember(oldGroup)); mGroups->GetMember(newGroup)->SetInput(newOutput); mGroups->GetMember(newGroup)->Show(mGroups->GetMember(oldGroup)->IsVisible()); mGroups->SetCurrentMemberIndex(newGroup); this->ClearCache(); return newGroup; } bool iParticlesViewSubject::DeleteGroup(int n) { if(mSplitter->DeleteGroup(n)) { this->ClearCache(); if(mGroups->DeleteMember(n)) { // // Need to update inputs // int i; for(i=n; i<=mGroups->GetMaxMemberIndex(); i++) mGroups->GetMember(i)->SetInput(mSplitter->GetOutput(i)); return true; } else return false; } else return false; } void iParticlesViewSubject::UpdateColorLookupTable() { int i; for(i=0; i<=mGroups->GetMaxMemberIndex(); i++) mGroups->GetMember(i)->UpdateColorLookupTable(); } void iParticlesViewSubject::UpdateMaterialProperties() { int i; for(i=0; i<=mGroups->GetMaxMemberIndex(); i++) mGroups->GetMember(i)->UpdateMaterialProperties(); } void iParticlesViewSubject::SetAttributeToSplit(int a) { int oldAtt = mSplitter->GetAttributeToSplit(); mSplitter->SetAttributeToSplit(a); if(oldAtt != mSplitter->GetAttributeToSplit()) { while(mGroups->GetMaxMemberIndex() > 0) this->DeleteGroup(mGroups->GetMaxMemberIndex()); mGroups->GetMember(0)->UpdateLookupTables(); } this->ClearCache(); } int iParticlesViewSubject::GetAttributeToSplit() const { return mSplitter->GetAttributeToSplit(); } void iParticlesViewSubject::ViewSubjectPackStateBody(iString &) const { #ifdef I_CHECK1 IERROR_LOW("This function should never be called."); #endif } void iParticlesViewSubject::ViewSubjectUnPackStateBody(const iString &) { #ifdef I_CHECK1 IERROR_LOW("This function should never be called."); #endif } bool iParticlesViewSubject::CanBeShown() const { return (vtkPolyData::SafeDownCast(this->GetData()) != 0); } void iParticlesViewSubject::ViewSubjectSyncWithData(const iDataSyncRequest &r) { int i; mSplitter->SetInput(vtkPolyData::SafeDownCast(this->GetData())); for(i=0; i<=mGroups->GetMaxMemberIndex(); i++) { mGroups->GetMember(i)->ViewSubjectSyncWithData(r); } } ifrit-3.4.2/core/iparticlesviewsubject.h0000755000175700010010000001230512167404417016727 0ustar HomeNone/*========================================================================= Program: Ionization FRont Interactive Tool (IFRIT) Language: C++ Copyright (c) 2002-2012 Nick Gnedin All rights reserved. This file may be distributed and/or modified under the terms of the GNU General Public License version 2 as published by the Free Software Foundation and appearing in the file LICENSE.GPL included in the packaging of this file. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHORS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. =========================================================================*/ #ifndef IPARTICLESVIEWSUBJECT_H #define IPARTICLESVIEWSUBJECT_H #include "iviewsubject.h" class iParticleGroup; class iParticleGroupFamily; class iParticleSplitter; class iRangeMapping; class iParticlesViewSubject : public iViewSubject { friend class iAbstractExtension; friend class iObjectFactory; friend class iParticleGroup; public: vtkTypeMacro(iParticlesViewSubject,iViewSubject); static const iObjectType& Type(); static const int CurrentId; virtual void BecomeClone(iParticlesViewSubject *other); static const iObjectKey& KeyMaxGroup(); int GetMaxGroupIndex() const; static const iObjectKey& KeyCurrentGroup(); void SetCurrentGroupIndex(int i); int GetCurrentGroupIndex() const; iParticleGroup* GetCurrentGroup() const; iParticleGroup* GetGroup(int i) const; // // Decorator functions // inline iParticleGroup* GetCurrentMember() const { return this->GetCurrentGroup(); } inline iParticleGroup* GetMember(int i) const { return this->GetGroup(i); } inline int GetMaxMemberIndex() const { return this->GetMaxGroupIndex(); } virtual void UpdateColorLookupTable(); virtual void UpdateMaterialProperties(); virtual void Reset(); virtual void ShowClipPlane(bool s); virtual void ShowColorBars(bool s); virtual float GetMemorySize() const; virtual bool IsVisible() const; virtual const iObjectType& RealType(); // // Decorator keys // static const iObjectKey& KeyType(); static const iObjectKey& KeyPalette(); static const iObjectKey& KeyColor(); static const iObjectKey& KeyAttributeToColor(); static const iObjectKey& KeyAttributeToSize(); static const iObjectKey& KeyOpacity(); static const iObjectKey& KeyFixedSize(); static const iObjectKey& KeyStretchToColor(); static const iObjectKey& KeyLowerLimitToColor(); static const iObjectKey& KeyUpperLimitToColor(); static const iObjectKey& KeyStretchToSize(); static const iObjectKey& KeyLowerLimitToSize(); static const iObjectKey& KeyUpperLimitToSize(); static const iObjectKey& KeyAttributeSizeDirect(); static const iObjectKey& KeyAttributeSizeExtraFactor(); static const iObjectKey& KeyLineWidth(); static const iObjectKey& KeyAutoScaled(); static const iObjectKey& KeyAttributeToConnect(); static const iObjectKey& KeyAttributeToSeparate(); static const iObjectKey& KeySizeFunction(); IVIEWSUBJECT_DECLARE_INHERITED_KEYS; // // Splitter functionality (decorator) // IOBJECT_DECLARE_GETSET2(AttributeToSplit,int); //void SetAttributeToSplit(int a); //int GetAttributeToSplit() const; static const iObjectKey& KeySplitRangesStretch(); static const iObjectKey& KeySplitRangesTiled(); static const iObjectKey& KeySplitRangesMin(); static const iObjectKey& KeySplitRangesMax(); static const iObjectKey& KeySplitRangeLowerLimit(); static const iObjectKey& KeySplitRangeUpperLimit(); virtual int CreateGroup(); virtual bool DeleteGroup(int n); static const iObjectKey& KeySplitRanges(); iRangeMapping* GetSplitRanges(); // for direct access virtual void PackCompleteState(iString &s) const; virtual void UnPackCompleteState(const iString &s); static void UseFullState(bool s){ mUseFullState = s; } virtual bool CanBeShown() const; protected: iParticlesViewSubject(iViewModule *vm, const iDataType &type, const iString &name, const iColor &color = iColor::Invalid(), bool shaded = false); virtual ~iParticlesViewSubject(); virtual void ConfigureBody(); virtual void UpdateReplicas(); virtual void ShowBody(bool s); virtual void ViewSubjectSyncWithData(const iDataSyncRequest &r); virtual void PackGroupStateBody(iString &s, int first, int last) const; virtual void UnPackGroupStateBody(const iString &s, int first, int last); virtual void PackStateBody(iString &s) const; \ virtual void UnPackStateBody(const iString &s); \ virtual void ViewSubjectPackStateBody(iString &s) const; virtual void ViewSubjectUnPackStateBody(const iString &s); static bool mUseFullState; iParticleGroupFamily *mGroups; iParticleSplitter *mSplitter; }; #endif // IPARTICLESVIEWSUBJECT_H ifrit-3.4.2/core/ipicker.cpp0000755000175700010010000002666412167404434014312 0ustar HomeNone/*========================================================================= Program: Ionization FRont Interactive Tool (IFRIT) Language: C++ Copyright (c) 2002-2012 Nick Gnedin All rights reserved. This file may be distributed and/or modified under the terms of the GNU General Public License version 2 as published by the Free Software Foundation and appearing in the file LICENSE.GPL included in the packaging of this file. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHORS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. =========================================================================*/ #include "ipicker.h" #include "iactor.h" #include "icommoneventobservers.h" #include "idata.h" #include "idataformatter.h" #include "idatahelper.h" #include "idatalimits.h" #include "idatareader.h" #include "idatasubject.h" #include "ierror.h" #include "iobjectfactory.h" #include "iprobefilter.h" #include "iviewmodule.h" #include "iviewsubject.h" #include "iviewsubjectobserver.h" #include #include #include #include #include #include #include #include #include #include #include #include #include // // templates // #include "iarraytemplate.h" // // Picker must be an object so that it can be created by the ObjectFactory // IOBJECT_DEFINE_TYPE(iPicker,Picker,pi,iObjectType::_Helper); // helper type IOBJECT_DEFINE_KEY(iPicker,Accuracy,a,Float,1); IOBJECT_DEFINE_KEY(iPicker,PickMethod,m,Int,1); IOBJECT_DEFINE_KEY(iPicker,PointSize,ps,Float,1); namespace iPicker_Private { const int NumPickMethods = 3; class CellPicker : public vtkCellPicker { public: static CellPicker* New() { return new CellPicker; } virtual vtkAssemblyPath* GetPath() { return 0; // we do not highlight the picked prop } }; class PointPicker : public vtkPointPicker { public: static PointPicker* New() { return new PointPicker; } virtual vtkAssemblyPath* GetPath() { return 0; // we do not highlight the picked prop } }; class ObjectPicker : public vtkPropPicker { public: static ObjectPicker* New() { return new ObjectPicker; } virtual vtkAssemblyPath* GetPath() { return 0; // we do not highlight the picked prop } }; class PickHandler : public vtkPicker { public: static PickHandler* New(iPicker *parent) { return new PickHandler(parent); } virtual vtkAssemblyPath* GetPath() { return 0; // we do not highlight the picked prop } virtual int Pick(double x, double y, double z, vtkRenderer *ren) { int pm = mParent->GetPickMethod(); if(pm>=0 && pmSetTolerance(this->GetTolerance()); this->InvokeEvent(vtkCommand::StartPickEvent,0); int ret = mDevices[pm]->Pick(x,y,z,ren); mDevices[pm]->GetPickPosition(this->PickPosition); this->SetPath(mDevices[pm]->vtkAbstractPropPicker::GetPath()); mParent->UpdateReport(); this->InvokeEvent(vtkCommand::EndPickEvent,0); return ret; } else { vtkErrorMacro("Invalid pick method."); return 0; } } virtual void Modified() { int i; for(i=0; iModified(); this->vtkAbstractPropPicker::Modified(); } private: PickHandler(iPicker *parent) { mParent = parent; IERROR_ASSERT(parent); // // Pickers // mDevices[0] = CellPicker::New(); IERROR_ASSERT(mDevices[0]); mDevices[1] = PointPicker::New(); IERROR_ASSERT(mDevices[1]); mDevices[2] = ObjectPicker::New(); IERROR_ASSERT(mDevices[2]); // // Observer // mObserver = iPickEventObserver::New(mParent->GetViewModule()); IERROR_ASSERT(mObserver); this->AddObserver(vtkCommand::StartPickEvent,mObserver); this->AddObserver(vtkCommand::EndPickEvent,mObserver); int i; for(i=0; iAddObserver(vtkCommand::AbortCheckEvent,mParent->GetViewModule()->GetAbortRenderEventObserver()); } } ~PickHandler() { int i; for(i=0; iDelete(); mObserver->Delete(); } iPicker *mParent; iPickEventObserver *mObserver; vtkAbstractPropPicker *mDevices[NumPickMethods]; }; }; using namespace iParameter; using namespace iPicker_Private; iPicker* iPicker::New(iViewModule *vm) { IERROR_ASSERT(vm); iPicker *tmp = new iPicker(vm); IERROR_ASSERT(tmp); iObjectFactory::InstallExtensions(tmp); return tmp; } iPicker::iPicker(iViewModule *vm) : iExtendableObject("Picker"), mViewModule(vm), mDataFormatter(vm), mPos(vm) { mSubjectName = ""; mSubjectId = ViewSubject::Id::Undefined; mDataTypePointer = 0; mPickMethod = PickMethod::Object; // // Handler // mHandler = PickHandler::New(this); IERROR_ASSERT(mHandler); this->SetAccuracy(0.02f); // // Graphical representation // mPointActor = iActor::New(); IERROR_ASSERT(mPointActor); mPointSource = vtkSphereSource::New(); IERROR_ASSERT(mPointSource); mPointSize = 0.1; this->SetPointSize(mPointSize); mPointSource->SetRadius(0.5); mPointActor->GetProperty()->SetColor(0.9,0.9,0.9); mPointActor->VisibilityOff(); mPointActor->PickableOff(); this->GetViewModule()->AddObject(mPointActor); // // PolyData inout for a probe filter // mProbeInput = vtkPolyData::New(); IERROR_ASSERT(mProbeInput); vtkCellArray *v = vtkCellArray::New(); IERROR_ASSERT(v); v->InsertNextCell(1); v->InsertCellPoint(0); mProbeInput->SetVerts(v); v->Delete(); vtkPoints *p = vtkPoints::New(VTK_DOUBLE); IERROR_ASSERT(p); p->SetNumberOfPoints(1); p->SetPoint(0,0.0,0.0,0.0); mProbeInput->SetPoints(p); p->Delete(); } iPicker::~iPicker() { mHandler->Delete(); this->GetViewModule()->RemoveObject(mPointActor); mPointActor->Delete(); mPointSource->Delete(); mProbeInput->Delete(); } void iPicker::Modified() { mHandler->Modified(); this->ClearCache(); } void iPicker::UpdateReport() { mSubjectName = "Unknown"; mPos = mHandler->GetPickPosition(); this->SetPointSize(mPointSize); mPointActor->SetPosition(mPos); mDataFormatter->ClearReport(); this->UpdateReportBody(); // this can replace mPointObject via its extensions mPointActor->SetInput(mPointSource->GetOutput()); mPointActor->SetScaled(true); mPointActor->SetPosition(mPos); // // Check if extensions want to modify the point actor // if(mDataTypePointer != 0) { int i; for(i=0; i(INFO,mExtensions[i])->IsUsingData(*mDataTypePointer)) { iRequiredCast(INFO,mExtensions[i])->ModifyActor(*mDataTypePointer,mPointActor); // the last installed extension prevails } } this->ShowPickedPoint(mDataTypePointer != 0); } void iPicker::UpdateReportBody() { int j; iString s1, s2; // // Get the object info // vtkProp *obj = mHandler->GetViewProp(); if(obj == 0) { mSubjectName = ""; mPointActor->VisibilityOff(); return; } iViewSubjectObserver *obs = iRequiredCast(INFO,obj->GetCommand(1)); if(obs != 0) { mSubjectId = obs->GetSubjectId(); mSubjectName = obs->GetSubjectName(); mDataTypePointer = &obs->GetDataType(); } else { mSubjectId = ViewSubject::Id::Undefined; mSubjectName = "Unknown"; mDataTypePointer = 0; } // // Get the data info // if(mDataTypePointer == 0) return; iDataSubject *subject = this->GetViewModule()->GetReader()->GetSubject(*mDataTypePointer); iDataLimits *lim = subject->GetLimits(); // // Use the ProbeFilter to find attribute values // mProbeInput->GetPoints()->SetPoint(0,mPos); iProbeFilter *probe = subject->CreateProbeFilter(obs->GetSubject()); probe->SetInput(mProbeInput); probe->SetSource(subject->GetData()); probe->Update(); vtkPolyData *out = probe->GetPolyDataOutput(); if(out==0 || out->GetPointData()==0) { IERROR_LOW("Unable to probe data for the picked object"); return; } // // Ask extensions to provide extra information // int i; for(i=0; i(INFO,mExtensions[i])->IsUsingData(*mDataTypePointer)) { iRequiredCast(INFO,mExtensions[i])->AddInfo(*mDataTypePointer); } iDataHelper h(out); vtkDataArray *d = 0; int nvar = 0; if(h.IsThereScalarData()) { d = out->GetPointData()->GetScalars(); nvar = lim->GetNumVars(); if(d==0 || nvar<1 || d->GetNumberOfComponents()!=nvar || !d->IsA("vtkFloatArray")) { IERROR_LOW("Unable to probe data for the picked object"); return; } float *v = (float *)d->GetVoidPointer(0); // // Make the correction for the surface // if(mSubjectId == ViewSubject::Id::Surface) { j = obs->GetIsoSurfaceData().Var; if(j>=0 && jGetIsoSurfaceData().Level; } mDataFormatter->FormatScalarData(lim,nvar,v); } if(h.IsThereVectorData()) { d = out->GetPointData()->GetVectors(); nvar = 3; if(d==0 || nvar<1 || d->GetNumberOfComponents()!=nvar || !d->IsA("vtkFloatArray")) { IERROR_LOW("Unable to probe data for the picked object"); return; } float *v = (float *)d->GetVoidPointer(0); mDataFormatter->FormatVectorData(lim,-1,v); } if(h.IsThereTensorData()) { d = out->GetPointData()->GetTensors(); nvar = 9; if(d==0 || nvar<1 || d->GetNumberOfComponents()!=nvar || !d->IsA("vtkFloatArray")) { IERROR_LOW("Unable to probe data for the picked object"); return; } float *v = (float *)d->GetVoidPointer(0); mDataFormatter->FormatTensorData(lim,-1,v); } probe->Delete(); } void iPicker::SetPointSize(float s) { if(s > 0.0) { mPointSize = s; mPointActor->SetScaled(true); mPointActor->SetBasicScale(mPointSize); this->Modified(); } } void iPicker::ShowPickedPoint(bool s) { if(!mSubjectName.IsEmpty() && s) { mPointActor->VisibilityOn(); } if(!s) { mPointActor->VisibilityOff(); } this->GetViewModule()->Render(); } // // Two functions used in saving/restoring the state and in creating new instances with // void iPicker::ExtendableObjectPackStateBody(iString &s) const { this->PackValue(s,KeyPickMethod(),mPickMethod); this->PackValue(s,KeyPointSize(),mPointSize); this->PackValue(s,KeyAccuracy(),float(mHandler->GetTolerance())); } void iPicker::ExtendableObjectUnPackStateBody(const iString &s) { int i; float f; if(this->UnPackValue(s,KeyPickMethod(),i)) this->SetPickMethod(i); if(this->UnPackValue(s,KeyPointSize(),f)) this->SetPointSize(f); if(this->UnPackValue(s,KeyAccuracy(),f)) this->SetAccuracy(f); } void iPicker::SetPickMethod(int s) { if(s>=0 && sClearCache(); } } void iPicker::SetAccuracy(float s) { if(s > 0.0f) { mHandler->SetTolerance(s); this->ClearCache(); } } // // Extension class // IOBJECTEXTENSION_DEFINE_ABSTRACT(iPicker); void iPickerExtension::Define() { } ifrit-3.4.2/core/ipicker.h0000755000175700010010000000610112167404417013740 0ustar HomeNone/*========================================================================= Program: Ionization FRont Interactive Tool (IFRIT) Language: C++ Copyright (c) 2002-2012 Nick Gnedin All rights reserved. This file may be distributed and/or modified under the terms of the GNU General Public License version 2 as published by the Free Software Foundation and appearing in the file LICENSE.GPL included in the packaging of this file. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHORS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. =========================================================================*/ #ifndef IPICKER_H #define IPICKER_H #include "iextendableobject.h" #include "iposition.h" class iActor; class iDataFormatter; class iDataType; class vtkPicker; class vtkPolyData; class vtkSphereSource; namespace iParameter { namespace PickMethod { // // Picker parameters // const int Cell = 0; const int Point = 1; const int Object = 2; }; }; class iPicker : public iExtendableObject { IPOINTER_AS_PART(ViewModule); IPOINTER_AS_USER(DataFormatter); public: vtkTypeMacro(iPicker,iExtendableObject); static iPicker* New(iViewModule *vm = 0); static const iObjectType& Type(); IOBJECT_DECLARE_GETSET2(Accuracy,float); IOBJECT_DECLARE_GETSET1(PickMethod,int); IOBJECT_DECLARE_GETSET1(PointSize,float); inline const iPosition& GetPosition() const { return mPos; } inline const iString& GetObjectName() const { return mSubjectName; } void ShowPickedPoint(bool s); inline vtkPicker* GetHandler() const { return mHandler; } void UpdateReport(); virtual void Modified(); protected: iPicker(iViewModule *vm); virtual ~iPicker(); virtual void ExtendableObjectPackStateBody(iString &) const; virtual void ExtendableObjectUnPackStateBody(const iString &); virtual void UpdateReportBody(); private: iPosition mPos; iString mSubjectName; int mSubjectId, mPickMethod; const iDataType *mDataTypePointer; vtkPolyData *mProbeInput; // // Actual workers // vtkPicker *mHandler; // // Graphical representation // iActor *mPointActor; vtkSphereSource *mPointSource; float mPointSize, mAccuracy; }; class iPickerExtension : public iObjectExtension { IOBJECTEXTENSION_DECLARE_ABSTRACT(iPicker); public: virtual bool IsUsingData(const iDataType &type) const = 0; virtual void ModifyActor(const iDataType &type, iActor *actor) = 0; virtual void AddInfo(const iDataType &type) = 0; }; #endif // IPICKER_H ifrit-3.4.2/core/ipiecewisefunction.cpp0000755000175700010010000001146612167404434016552 0ustar HomeNone/*========================================================================= Program: Ionization FRont Interactive Tool (IFRIT) Language: C++ Copyright (c) 2002-2012 Nick Gnedin All rights reserved. This file may be distributed and/or modified under the terms of the GNU General Public License version 2 as published by the Free Software Foundation and appearing in the file LICENSE.GPL included in the packaging of this file. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHORS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. =========================================================================*/ #include "ipiecewisefunction.h" #include "ierror.h" #include "imath.h" #include // // Templates // #include "iarraytemplate.h" class iPiecewiseFunctionHelper : public vtkPiecewiseFunction { public: iPiecewiseFunctionHelper(iPiecewiseFunction *p) { mParent = p; } virtual void Update() { int i; this->RemoveAllPoints(); for(i=0; imArr.Size(); i++) this->AddPoint(255*mParent->mArr[i].X,mParent->mArr[i].Y); vtkPiecewiseFunction::Update(); } void ParentChanged() { this->Update(); // Very inefficient, but needed to work around a VTK 5.0.0 bug mParent->Modified(); } private: iPiecewiseFunction *mParent; }; // // iPiecewiseFunction class // iPiecewiseFunction* iPiecewiseFunction::New(float ymin, float ymax) { return new iPiecewiseFunction(ymin,ymax,10); } iPiecewiseFunction::iPiecewiseFunction(float ymin, float ymax, int inc) : mArr(inc) { mYmin = ymin; mYmax = ymax; mArr.Add(Point(0.0,ymin)); mArr.Add(Point(1.0,ymax)); mHelper = new iPiecewiseFunctionHelper(this); IERROR_ASSERT(mHelper); mHelper->ParentChanged(); } iPiecewiseFunction::~iPiecewiseFunction() { mHelper->Delete(); } vtkPiecewiseFunction* iPiecewiseFunction::GetVTKFunction() const { return mHelper; } void iPiecewiseFunction::Copy(const iPiecewiseFunction *f) { if(this==f || f==0) return; int i; for(i=0; imArr.Size(); i++) mArr[i] = f->mArr[i]; while(mArr.Size() < f->mArr.Size()) mArr.Add(f->mArr[mArr.Size()]); while(mArr.Size() > f->mArr.Size()) mArr.RemoveLast(); mHelper->ParentChanged(); } void iPiecewiseFunction::SetMinMax(float ymin, float ymax) { mYmin = ymin; mYmax = ymax; for(int i=0; i mYmax) ? mYmax : mArr[i].Y; mArr[i].Y = (mArr[i].Y < mYmin) ? mYmin : mArr[i].Y; } mHelper->ParentChanged(); } void iPiecewiseFunction::AddPoint(int n) { n++; if(n < 1) n = 1; if(n > mArr.MaxIndex()) n = mArr.MaxIndex(); mArr.Add(Point(0.5*(mArr[n-1].X+mArr[n].X),0.5*(mArr[n-1].Y+mArr[n].Y))); mHelper->ParentChanged(); } void iPiecewiseFunction::AddPoint(float x, float y) { if(x>mArr[0].X && xParentChanged(); } } void iPiecewiseFunction::RemovePoint(int n) { if(n>0 && n2) { mArr.iArray::Remove(n); mHelper->ParentChanged(); } } void iPiecewiseFunction::MovePoint(int n, float x, float y) { if(n>0 && n xr) ? xr : x; y = (y < mYmin) ? mYmin : y; y = (y > mYmax) ? mYmax : y; mArr[n] = Point(x,y); } else if(n==0 || n==mArr.MaxIndex()) { y = (y < mYmin) ? mYmin : y; y = (y > mYmax) ? mYmax : y; mArr[n].Y = y; } mHelper->ParentChanged(); } int iPiecewiseFunction::FindPoint(float x, float y, float &dmin) const { int i, imin; float d, dx, dy; dmin = iMath::_LargeFloat; imin = -1; for(i=0; i mArr.Last().X) return mArr.Last().Y; for(i=1; i 2) mArr.RemoveLast(); mArr[0] = Point(0.0,mYmin); mArr[1] = Point(1.0,mYmax); mHelper->ParentChanged(); } ifrit-3.4.2/core/ipiecewisefunction.h0000755000175700010010000000527612167404417016222 0ustar HomeNone/*========================================================================= Program: Ionization FRont Interactive Tool (IFRIT) Language: C++ Copyright (c) 2002-2012 Nick Gnedin All rights reserved. This file may be distributed and/or modified under the terms of the GNU General Public License version 2 as published by the Free Software Foundation and appearing in the file LICENSE.GPL included in the packaging of this file. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHORS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. =========================================================================*/ #ifndef IPIECEWISEFUNCTION_H #define IPIECEWISEFUNCTION_H #include #include "iarray.h" class iPiecewiseFunctionHelper; class iPiecewiseFunctionUser; class vtkObject; class vtkPiecewiseFunction; class iPiecewiseFunction : public vtkObject { friend class iPiecewiseFunctionHelper; public: vtkTypeMacro(iPiecewiseFunction,vtkObject); static iPiecewiseFunction* New(float ymin = 0.0f, float ymax = 1.0f); inline int N() const { return mArr.Size(); } inline float X(int i) const { return mArr[i].X; } inline float Y(int i) const { return mArr[i].Y; } inline float Min() const { return mYmin; } inline float Max() const { return mYmax; } void SetMinMax(float ymin, float ymax); void AddPoint(int n); void AddPoint(float x, float y); void RemovePoint(int n); void MovePoint(int n, float x, float y); int FindPoint(float x, float y, float &d) const; float GetValue(float x) const; void Copy(const iPiecewiseFunction *f); void Reset(); vtkPiecewiseFunction* GetVTKFunction() const; protected: iPiecewiseFunction(float ymin, float ymax, int inc); virtual ~iPiecewiseFunction(); struct Point { float X; float Y; Point(){ X = Y = 0.0; } Point(float x, float y){ X = x; Y = y; } bool operator==(const Point &p) const { return (X == p.X); } bool operator<(const Point &p) const { return (X < p.X); } }; iOrderedArray mArr; float mYmin, mYmax; iPiecewiseFunctionHelper *mHelper; }; #endif // IPIECEWISEFUNCTION_H ifrit-3.4.2/core/ipointer.cpp0000755000175700010010000000261512167404434014503 0ustar HomeNone/*========================================================================= Program: Ionization FRont Interactive Tool (IFRIT) Language: C++ Copyright (c) 2002-2012 Nick Gnedin All rights reserved. This file may be distributed and/or modified under the terms of the GNU General Public License version 2 as published by the Free Software Foundation and appearing in the file LICENSE.GPL included in the packaging of this file. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHORS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. =========================================================================*/ #include "ipointer.h" #include "ierror.h" namespace iPointer { // // helper function // void Validate(void *ptr) { IERROR_ASSERT(ptr); } }; ifrit-3.4.2/core/ipointer.h0000644000175700010010000000735512167404417014154 0ustar HomeNone/*========================================================================= Program: Ionization FRont Interactive Tool (IFRIT) Language: C++ Copyright (c) 2002-2012 Nick Gnedin All rights reserved. This file may be distributed and/or modified under the terms of the GNU General Public License version 2 as published by the Free Software Foundation and appearing in the file LICENSE.GPL included in the packaging of this file. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHORS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. =========================================================================*/ #ifndef IPOINTER_H #define IPOINTER_H // // various simple but useful pointer types // namespace iPointer { // // helper function // void Validate(void *ptr); // // Small common functionality // template class TrivialBase { public: // // Cast to the holder's type // inline operator T*() const { return this->mPtr; } // // Dereference the pointer and return a reference to the contained object. // inline T& operator*() const { return *this->mPtr; } // // Provides normal pointer target member access using operator ->. // inline T* operator->() const { return this->mPtr; } protected: TrivialBase(T* ptr) { this->mPtr = ptr; } T* mPtr; private: // // Not implemented // TrivialBase(); // cannot have an automatic default constructor - otherwise the compiler will not require explicit instantination TrivialBase& operator=(TrivialBase&); }; // // Simple non-assignable, non-transferable auto-ptr // template class AutoDeleted : public TrivialBase { public: template AutoDeleted(P parent) : TrivialBase(T::New(parent)) { Validate(this->mPtr); } AutoDeleted() : TrivialBase(T::New()) { Validate(this->mPtr); } ~AutoDeleted() { this->mPtr->Delete(); } private: // // Not implemented // //AutoDeleted(); // cannot have an automatic default constructor - otherwise the compiler will not require explicit instantination AutoDeleted& operator=(AutoDeleted&); }; // // A pointer that cannot have a NULL value // template class AlwaysValid : public TrivialBase { public: AlwaysValid(T *ptr) : TrivialBase(ptr) { Validate(this->mPtr); } private: // // Not implemented // AlwaysValid(); AlwaysValid& operator=(AlwaysValid&); }; // // A pointer ordered by GetId() call of the argument class // template class Ordered : public TrivialBase { public: Ordered(T *ptr) : TrivialBase(ptr) { } // // Allow assignment operator // void operator=(const Ordered &p) { this->mPtr = p.mPtr; } bool operator==(const Ordered &other) const { return (this->mPtr==0 ? other.mPtr==0 : (other.mPtr!=0 && this->mPtr->GetId()==other.mPtr->GetId())); } bool operator<(const Ordered &other) const { return (this->mPtr==0 ? other.mPtr!=0 : (other.mPtr!=0 && this->mPtr->GetId()GetId())); } private: // // Not implemented // Ordered(); }; }; #endif // IPOINTER_H ifrit-3.4.2/core/ipointermacro.h0000755000175700010010000000363612167404417015177 0ustar HomeNone/*========================================================================= Program: Ionization FRont Interactive Tool (IFRIT) Language: C++ Copyright (c) 2002-2012 Nick Gnedin All rights reserved. This file may be distributed and/or modified under the terms of the GNU General Public License version 2 as published by the Free Software Foundation and appearing in the file LICENSE.GPL included in the packaging of this file. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHORS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. =========================================================================*/ #ifndef IPOINTERMACRO_H #define IPOINTERMACRO_H #include "ipointer.h" #define IPOINTER_AS_PART(_name_) \ public: \ inline i##_name_* Get##_name_() const { return m##_name_; } \ private: \ iPointer::AlwaysValid const m##_name_ #define IPOINTER_AS_USER(_name_) \ public: \ inline i##_name_* Get##_name_() const { return m##_name_; } \ private: \ iPointer::AutoDeleted const m##_name_ #define IPOINTER_AS_USER_WITH_FEEDBACK(_name_) \ public: \ inline i##_name_* Get##_name_() const { return m##_name_; } \ protected: \ void On##_name_##Change(); \ private: \ iPointer::AutoDeleted const m##_name_ #endif // IPOINTERMACRO_H ifrit-3.4.2/core/ipointglyph.cpp0000755000175700010010000002745312167404434015227 0ustar HomeNone/*========================================================================= Program: Ionization FRont Interactive Tool (IFRIT) Language: C++ Copyright (c) 2002-2012 Nick Gnedin All rights reserved. This file may be distributed and/or modified under the terms of the GNU General Public License version 2 as published by the Free Software Foundation and appearing in the file LICENSE.GPL included in the packaging of this file. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHORS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. =========================================================================*/ #include "ipointglyph.h" #include "ierror.h" #include #include #include #include #include #include #include #include #include #include #include #include #include #include // // Templates // #include "igenericfiltertemplate.h" namespace iPointGlyph_Private { struct PointType { int Type; // for consistency checking bool IsOriented; char *Name; }; const PointType type[] = { { 0, false, "Point" }, { 1, false, "Sphere" }, { 2, true, "Tetrahydron" }, { 3, false, "Cube" }, { 4, false, "Octahedron" }, { 5, false, "Icosahedron" }, { 6, false, "Dodecahedron" }, { 7, true, "Cone" }, { 8, true, "Cylinder" }, { 9, true, "Arrow" }, { 10, false, "Cluster" }, { 11, true, "Galaxy" } }; }; using namespace iParameter; using namespace iPointGlyph_Private; iPointGlyph* iPointGlyph::New(iViewSubject *vo) { return new iPointGlyph(vo); } iPointGlyph::iPointGlyph(iViewSubject *vo) : iGenericSource(vo,false) { int i; mType = PointGlyphType::Point; for(i=0; iCreateData(3); } iPointGlyph::~iPointGlyph() { int i; for(i=0; iDelete(); } } void iPointGlyph::CreateData(int res) { int i; vtkIdType l, n; double x[3], r; vtkPoints *p, *op; vtkFloatArray *fa; vtkDataArray *da; bool done[PointGlyphType::SIZE]; for(i=0; i 100) res = 100; // // Sphere // vtkSphereSource *ss = vtkSphereSource::New(); IERROR_ASSERT(ss); ss->SetThetaResolution(12*res); ss->SetPhiResolution(6*res); ss->SetRadius(0.5); ss->LatLongTessellationOn(); ss->SetOutput(mData[PointGlyphType::Sphere]); ss->Update(); ss->Delete(); done[PointGlyphType::Sphere] = true; // // Platonic solids // vtkPlatonicSolidSource *ps = vtkPlatonicSolidSource::New(); IERROR_ASSERT(ps); vtkPolyDataNormals *pn = vtkPolyDataNormals::New(); IERROR_ASSERT(pn); pn->AutoOrientNormalsOn(); pn->ConsistencyOn(); pn->ComputePointNormalsOff(); pn->SetInput(ps->GetOutput()); pn->SetOutput(mData[PointGlyphType::Tetrahydron]); pn->ComputeCellNormalsOn(); pn->FlipNormalsOn(); ps->SetSolidTypeToTetrahedron(); pn->Update(); mData[PointGlyphType::Tetrahydron]->GetCellData()->Initialize(); // clears the cell colors that are set by vtkPlatonicSolidSource this->ScaleData(mData[PointGlyphType::Tetrahydron],0.5); done[PointGlyphType::Tetrahydron] = true; pn->SetOutput(mData[PointGlyphType::Cube]); pn->ComputeCellNormalsOff(); pn->FlipNormalsOff(); ps->SetSolidTypeToCube(); pn->Update(); mData[PointGlyphType::Cube]->GetCellData()->Initialize(); // clears the cell colors that are set by vtkPlatonicSolidSource this->ScaleData(mData[PointGlyphType::Cube],0.5); done[PointGlyphType::Cube] = true; pn->SetOutput(mData[PointGlyphType::Octahedron]); pn->ComputeCellNormalsOn(); pn->FlipNormalsOff(); ps->SetSolidTypeToOctahedron(); pn->Update(); mData[PointGlyphType::Octahedron]->GetCellData()->Initialize(); // clears the cell colors that are set by vtkPlatonicSolidSource this->ScaleData(mData[PointGlyphType::Octahedron],0.5); done[PointGlyphType::Octahedron] = true; pn->SetOutput(mData[PointGlyphType::Icosahedron]); pn->ComputeCellNormalsOn(); pn->FlipNormalsOff(); ps->SetSolidTypeToIcosahedron(); pn->Update(); mData[PointGlyphType::Icosahedron]->GetCellData()->Initialize(); // clears the cell colors that are set by vtkPlatonicSolidSource this->ScaleData(mData[PointGlyphType::Icosahedron],0.5); done[PointGlyphType::Icosahedron] = true; pn->SetOutput(mData[PointGlyphType::Dodecahedron]); pn->ComputeCellNormalsOn(); pn->FlipNormalsOff(); ps->SetSolidTypeToDodecahedron(); pn->Update(); mData[PointGlyphType::Dodecahedron]->GetCellData()->Initialize(); // clears the cell colors that are set by vtkPlatonicSolidSource this->ScaleData(mData[PointGlyphType::Dodecahedron],0.5); done[PointGlyphType::Dodecahedron] = true; pn->Delete(); ps->Delete(); // // Cone // vtkConeSource *cs = vtkConeSource::New(); IERROR_ASSERT(cs); cs->SetResolution(6*res); cs->SetOutput(mData[PointGlyphType::Cone]); cs->Update(); cs->Delete(); this->ScaleData(mData[PointGlyphType::Cone],0.8); this->SwapAxes(mData[PointGlyphType::Cone],0,2); this->ShiftData(mData[PointGlyphType::Cone],2,0.1); done[PointGlyphType::Cone] = true; // // Cylinder // vtkCylinderSource *ts = vtkCylinderSource::New(); IERROR_ASSERT(ts); ts->SetResolution(6*res); ts->SetOutput(mData[PointGlyphType::Cylinder]); ts->Update(); ts->Delete(); this->ScaleData(mData[PointGlyphType::Cylinder],0.7); this->SwapAxes(mData[PointGlyphType::Cylinder],1,2); done[PointGlyphType::Cylinder] = true; // // Arrow // vtkArrowSource *as = vtkArrowSource::New(); IERROR_ASSERT(as); as->SetTipResolution(6*res); as->SetShaftResolution(6*res); as->SetTipRadius(0.5); as->SetShaftRadius(0.2); as->SetOutput(mData[PointGlyphType::Arrow]); as->Update(); as->Delete(); this->ScaleData(mData[PointGlyphType::Arrow],0.93); this->SwapAxes(mData[PointGlyphType::Arrow],0,2); this->ShiftData(mData[PointGlyphType::Arrow],2,-0.45); done[PointGlyphType::Arrow] = true; // // Point // vtkPointSource *cc; cc = vtkPointSource::New(); IERROR_ASSERT(cc); cc->SetNumberOfPoints(1); cc->SetCenter(0.0,0.0,0.0); cc->SetRadius(1.0); cc->SetOutput(mData[PointGlyphType::Point]); cc->Update(); cc->Delete(); p = mData[PointGlyphType::Point]->GetPoints(); p->SetPoint(0,0.0,0.0,0.0); done[PointGlyphType::Point] = true; // // Cluster // cc = vtkPointSource::New(); IERROR_ASSERT(cc); cc->SetNumberOfPoints(30*res); cc->SetCenter(0.0,0.0,0.0); cc->SetRadius(1.0); cc->SetOutput(mData[PointGlyphType::Cluster]); cc->Update(); cc->Delete(); // // Rearrange points radially to have a centrally concentrated cluster // p = mData[PointGlyphType::Cluster]->GetPoints(); n = p->GetNumberOfPoints(); for(l=0; lGetPoint(l,x); r = x[0]*x[0] + x[1]*x[1] + x[2]*x[2]; r = 0.5*pow(2*r/(1.0+r),2.0); x[0] *= r; x[1] *= r; x[2] *= r; p->SetPoint(l,x); } done[PointGlyphType::Cluster] = true; // // Galaxy // cc = vtkPointSource::New(); IERROR_ASSERT(cc); cc->SetNumberOfPoints(30*res); cc->SetCenter(0.0,0.0,0.0); cc->SetRadius(1.0); cc->SetOutput(mData[PointGlyphType::Galaxy]); cc->Update(); cc->Delete(); // // Rearrange points to have a spiral galaxy in z=0 plane. // double r1, phi; p = mData[PointGlyphType::Galaxy]->GetPoints(); n = p->GetNumberOfPoints(); for(l=0; lGetPoint(l,x); r = x[0]*x[0] + x[1]*x[1] + x[2]*x[2]; r = 0.5*(0.2*(1-r)+2*r)/(1.0+r); x[0] *= r; x[1] *= r; x[2] /= (5.0+20.0*r); if(l > 0.7*n) { r1 = sqrt(x[0]*x[0]+x[1]*x[1]); phi = atan2(x[1],x[0]); if(phi > vtkMath::Pi()) phi -= 2*vtkMath::Pi(); if(phi > 0.0) phi = 0.5*vtkMath::Pi(); else phi = -0.5*vtkMath::Pi(); x[0] = r1*cos(phi-5.0*r1); x[1] = r1*sin(phi-5.0*r1); } p->SetPoint(l,x); } done[PointGlyphType::Galaxy] = true; // // Test that all are done // for(i=0; iGetPoints(); if(op->GetDataType() != VTK_FLOAT) { n = op->GetNumberOfPoints(); p = vtkPoints::New(VTK_FLOAT); if(p == 0) break; p->SetNumberOfPoints(n); for(l=0; lSetPoint(l,op->GetPoint(l)); } mData[i]->SetPoints(p); p->Delete(); } } // // Make all normals float // for(i=0; iGetPointData()->GetNormals(); if(da!=0 && da->GetDataType()!=VTK_FLOAT) { n = da->GetNumberOfTuples(); fa = vtkFloatArray::New(); if(fa == 0) break; fa->SetNumberOfComponents(3); fa->SetNumberOfTuples(n); for(l=0; lSetTuple(l,da->GetTuple(l)); } mData[i]->GetPointData()->SetNormals(fa); fa->Delete(); } da = mData[i]->GetCellData()->GetNormals(); if(da!=0 && da->GetDataType()!=VTK_FLOAT) { n = da->GetNumberOfTuples(); fa = vtkFloatArray::New(); if(fa == 0) break; fa->SetNumberOfComponents(3); fa->SetNumberOfTuples(n); for(l=0; lSetTuple(l,da->GetTuple(l)); } mData[i]->GetCellData()->SetNormals(fa); fa->Delete(); } } } void iPointGlyph::ScaleData(vtkPolyData *d, double fac) { double x[3]; vtkPoints *p = d->GetPoints(); vtkIdType l, n = p->GetNumberOfPoints(); // // Scale data // for(l=0; lGetPoint(l,x); x[0] *= fac; x[1] *= fac; x[2] *= fac; p->SetPoint(l,x); } } void iPointGlyph::SwapAxes(vtkPolyData *d, int a1, int a2) { double r, x[3]; vtkPoints *p = d->GetPoints(); vtkIdType l, n = p->GetNumberOfPoints(); // // Swap points // for(l=0; lGetPoint(l,x); r = x[a1]; x[a1] = -x[a2]; x[a2] = r; p->SetPoint(l,x); } // // Don't forget to rotate normals too (if they exist) // vtkDataArray *da = d->GetPointData()->GetNormals(); if(da != 0) { n = da->GetNumberOfTuples(); for(l=0; lGetTuple(l,x); r = x[0]; x[0] = -x[2]; x[2] = r; da->SetTuple(l,x); } } da = d->GetCellData()->GetNormals(); if(da != 0) { n = da->GetNumberOfTuples(); for(l=0; lGetTuple(l,x); r = x[0]; x[0] = -x[2]; x[2] = r; da->SetTuple(l,x); } } } void iPointGlyph::ShiftData(vtkPolyData *d, int a, double dx) { double x[3]; vtkPoints *p = d->GetPoints(); vtkIdType l, n = p->GetNumberOfPoints(); // // Shift the data // for(l=0; lGetPoint(l,x); x[a] += dx; p->SetPoint(l,x); } } bool iPointGlyph::GetOriented() const { return iPointGlyph::GetOriented(mType); } const char* iPointGlyph::GetName() const { return iPointGlyph::GetName(mType); } bool iPointGlyph::GetOriented(int t) { if(t>=0 && t=0 && t=0 && tModified(); } } void iPointGlyph::ProduceOutput() { this->GetOutput()->ShallowCopy(mData[mType]); } ifrit-3.4.2/core/ipointglyph.h0000755000175700010010000000476712167404417014700 0ustar HomeNone/*========================================================================= Program: Ionization FRont Interactive Tool (IFRIT) Language: C++ Copyright (c) 2002-2012 Nick Gnedin All rights reserved. This file may be distributed and/or modified under the terms of the GNU General Public License version 2 as published by the Free Software Foundation and appearing in the file LICENSE.GPL included in the packaging of this file. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHORS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. =========================================================================*/ // // A representation for a single particle // #ifndef IPOINTGLYPH_H #define IPOINTGLYPH_H #include "igenericfilter.h" #include namespace iParameter { namespace PointGlyphType { const int Point = 0; const int Sphere = 1; const int Tetrahydron = 2; const int Cube = 3; const int Octahedron = 4; const int Icosahedron = 5; const int Dodecahedron = 6; const int Cone = 7; const int Cylinder = 8; const int Arrow = 9; const int Cluster = 10; const int Galaxy = 11; const int SIZE = 12; }; }; class iPointGlyph: public iGenericSource { public: static iPointGlyph* New(iViewSubject *vo); inline int GetType() const { return mType; } void SetType(int m); bool GetOriented() const; const char* GetName() const; static bool GetOriented(int t); static const char* GetName(int t); protected: iPointGlyph(iViewSubject *vo); virtual ~iPointGlyph(); virtual void ProduceOutput(); private: void CreateData(int res); void ScaleData(vtkPolyData *d, double fac); void SwapAxes(vtkPolyData *d, int a1, int a2); void ShiftData(vtkPolyData *d, int a, double dx); int mType; vtkPolyData *mData[iParameter::PointGlyphType::SIZE]; }; #endif // IPOINTGLYPH_H ifrit-3.4.2/core/iposition.cpp0000755000175700010010000000645112167404434014671 0ustar HomeNone/*========================================================================= Program: Ionization FRont Interactive Tool (IFRIT) Language: C++ Copyright (c) 2002-2012 Nick Gnedin All rights reserved. This file may be distributed and/or modified under the terms of the GNU General Public License version 2 as published by the Free Software Foundation and appearing in the file LICENSE.GPL included in the packaging of this file. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHORS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. =========================================================================*/ #include "iposition.h" #include "ierror.h" #include "iviewmodule.h" // // iPosition functions // iPosition::iPosition(iViewModule *vm) : mViewModule(vm) { IERROR_ASSERT(vm); mX[0] = mX[1] = mX[2] = 0.0; mBoxX[0] = mBoxX[1] = mBoxX[2] = 0.0; } iPosition::~iPosition() { } void iPosition::UpdateBoxPosition() const { int i; if(this->GetViewModule()->GetOpenGLCoordinates()) { for(i=0; i<3; i++) mBoxX[i] = mX[i]; // so small, no need to use iTune } else { float boxSize = this->GetViewModule()->GetBoxSize(); for(i=0; i<3; i++) mBoxX[i] = 0.5*(1.0+mX[i])*boxSize; } } void iPosition::UpdateOpenGLPosition() { int i; if(this->GetViewModule()->GetOpenGLCoordinates()) { for(i=0; i<3; i++) mX[i] = mBoxX[i]; } else { float boxSize = this->GetViewModule()->GetBoxSize(); for(i=0; i<3; i++) mX[i] = -1.0 + 2.0*mBoxX[i]/boxSize; } } void iPosition::PeriodicWrap() { int i; // // If x is in between -1 and 1, do nothing - this way x=1 remains 1, and not wrapped into x=-1 // for(i=0; i<3; i++) if(mX[i]<-1.0 || mX[i]>1.0) mX[i] -= 2.0*floor(0.5*(1.0+mX[i])); } void iPosition::CutToBounds() { int i; for(i=0; i<3; i++) { if(mX[i] < -1.0) mX[i] = -1.0; if(mX[i] > 1.0) mX[i] = 1.0; } } // // iDistance functions // iDistance::iDistance(iViewModule *vm, bool isSize) : mViewModule(vm), mIsSize(isSize) { IERROR_ASSERT(vm) if(isSize) mX = 1.0; else mX = 0.0; } iDistance::~iDistance() { } void iDistance::UpdateBoxDistance() const { if(this->GetViewModule()->GetOpenGLCoordinates()) { mBoxX = mX; } else { double offset = 1.0; if(mIsSize) offset = 0.0; mBoxX = 0.5*(offset+mX)*this->GetViewModule()->GetBoxSize(); } } void iDistance::UpdateOpenGLDistance() { if(this->GetViewModule()->GetOpenGLCoordinates()) { mX = mBoxX; } else { double offset = 1.0; if(mIsSize) offset = 0.0; mX = -offset + 2.0*mBoxX/this->GetViewModule()->GetBoxSize(); } } void iDistance::PeriodicWrap() { if(!mIsSize) mX -= 2.0*floor(0.5*(1.0+mX)); } void iDistance::CutToBounds() { if(mX < -1.0) mX = -1.0; if(mX > 1.0) mX = 1.0; } ifrit-3.4.2/core/iposition.h0000755000175700010010000001106012167404417014327 0ustar HomeNone/*========================================================================= Program: Ionization FRont Interactive Tool (IFRIT) Language: C++ Copyright (c) 2002-2012 Nick Gnedin All rights reserved. This file may be distributed and/or modified under the terms of the GNU General Public License version 2 as published by the Free Software Foundation and appearing in the file LICENSE.GPL included in the packaging of this file. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHORS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. =========================================================================*/ // // A double-valued position // #ifndef IPOSITION_H #define IPOSITION_H #include "ipointermacro.h" class iViewModule; class iPosition { friend class iView; IPOINTER_AS_PART(ViewModule); public: iPosition(iViewModule *vm); ~iPosition(); void SetBoxPosition(const double *x); void SetBoxPosition(double x1, double x2, double x3); void SetBoxPosition(int i, double x); inline const double* BoxPosition() const { this->UpdateBoxPosition(); return mBoxX; } inline double BoxPosition(int i) const { this->UpdateBoxPosition(); return mBoxX[i]; } inline const double* OpenGLPosition() const { return mX; } inline double OpenGLPosition(int i) const { return mX[i]; } iPosition& operator=(iPosition&); iPosition& operator=(double *); const iPosition& operator=(const double *); inline operator double*() { return mX; } inline operator const double*() const { return mX; } inline double operator[](int i) const { return mX[i]; } inline double& operator[](int i) { return mX[i]; } void PeriodicWrap(); void CutToBounds(); private: void UpdateOpenGLPosition(); void UpdateBoxPosition() const; mutable double mBoxX[3]; double mX[3]; iPosition(const iPosition&); // not implemented }; class iDistance { friend class iView; IPOINTER_AS_PART(ViewModule); public: iDistance(iViewModule *vm, bool size); ~iDistance(); void SetBoxDistance(double x); inline double BoxDistance() const { this->UpdateBoxDistance(); return mBoxX; } inline double OpenGLDistance() const { return mX; } iDistance& operator=(iDistance&); iDistance& operator=(double); inline bool operator<(const iDistance &p) const { return mX < p.mX; } inline bool operator>(const iDistance &p) const { return mX > p.mX; } inline bool operator<(double x) const { return mX < x; } inline bool operator>(double x) const { return mX > x; } inline operator double() const { return mX; } void PeriodicWrap(); void CutToBounds(); private: void UpdateOpenGLDistance(); void UpdateBoxDistance() const; const bool mIsSize; mutable double mBoxX; double mX; iDistance(const iDistance&); // not implemented }; // // iPosition functions // inline void iPosition::SetBoxPosition(const double *x) { int i; for(i=0; i<3; i++) mBoxX[i] = x[i]; this->UpdateOpenGLPosition(); } inline void iPosition::SetBoxPosition(double x1, double x2, double x3) { mBoxX[0] = x1; mBoxX[1] = x2; mBoxX[2] = x3; this->UpdateOpenGLPosition(); } inline void iPosition::SetBoxPosition(int i, double x) { if(i>=0 && i<3) { mBoxX[i] = x; this->UpdateOpenGLPosition(); } } inline iPosition& iPosition::operator=(iPosition &p) { int i; for(i=0; i<3; i++) mX[i] = p.mX[i]; return *this; } inline iPosition& iPosition::operator=(double *x) { int i; for(i=0; i<3; i++) mX[i] = x[i]; return *this; } inline const iPosition& iPosition::operator=(const double *x) { int i; for(i=0; i<3; i++) mX[i] = x[i]; return *this; } // // iDistance functions // inline void iDistance::SetBoxDistance(double x) { if(!mIsSize || x>0.0) { mBoxX = x; this->UpdateOpenGLDistance(); } } inline iDistance& iDistance::operator=(iDistance &p) { if(!mIsSize || p.mX>0.0) mX = p.mX; // assignment does not overwrite the Relative flag return *this; } inline iDistance& iDistance::operator=(double x) { if(!mIsSize || x>0.0) mX = x; return *this; } #endif // IPOSITION_H ifrit-3.4.2/core/ipostscriptwriter.cpp0000644000175700010010000001750612167404434016474 0ustar HomeNone/*========================================================================= Program: Ionization FRont Interactive Tool (IFRIT) Language: C++ Copyright (c) 2002-2012 Nick Gnedin All rights reserved. This file may be distributed and/or modified under the terms of the GNU General Public License version 2 as published by the Free Software Foundation and appearing in the file LICENSE.GPL included in the packaging of this file. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHORS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. =========================================================================*/ #include "ipostscriptwriter.h" #include #include #define VTK_MARGIN 0.95 iPostScriptWriter::Paper iPostScriptWriter::mPaper[NFORMATS]; iPostScriptWriter::iPostScriptWriter() { int i = 0; if(i < NFORMATS) { mPaper[i].Width = 33.0556; mPaper[i].Height = 46.7778; mPaper[i].Name = "A0"; i++; } if(i < NFORMATS) { mPaper[i].Width = 23.3889; mPaper[i].Height = 33.0556; mPaper[i].Name = "A1"; i++; } if(i < NFORMATS) { mPaper[i].Width = 16.5278; mPaper[i].Height = 23.3889; mPaper[i].Name = "A2"; i++; } if(i < NFORMATS) { mPaper[i].Width = 11.6944; mPaper[i].Height = 16.5278; mPaper[i].Name = "A3"; i++; } if(i < NFORMATS) { mPaper[i].Width = 8.26389; mPaper[i].Height = 11.6944; mPaper[i].Name = "A4"; i++; } if(i < NFORMATS) { mPaper[i].Width = 5.84772; mPaper[i].Height = 8.26389; mPaper[i].Name = "A5"; i++; } if(i < NFORMATS) { mPaper[i].Width = 4.12500; mPaper[i].Height = 5.84772; mPaper[i].Name = "A6"; i++; } if(i < NFORMATS) { mPaper[i].Width = 2.91667; mPaper[i].Height = 4.12500; mPaper[i].Name = "A7"; i++; } if(i < NFORMATS) { mPaper[i].Width = 2.05556; mPaper[i].Height = 2.91667; mPaper[i].Name = "A8"; i++; } if(i < NFORMATS) { mPaper[i].Width = 8.5 ; mPaper[i].Height = 11.0 ; mPaper[i].Name = "Letter"; i++; } if(i < NFORMATS) { mPaper[i].Width = 11.0 ; mPaper[i].Height = 17.0 ; mPaper[i].Name = "11x17"; i++; } mFormat = 9; mOrient = 0; } iPostScriptWriter::~iPostScriptWriter() { } void iPostScriptWriter::SetPaperFormat(int f) { if(f>=0 && f=0 && o<=1) mOrient = o; } void iPostScriptWriter::WriteFileHeader(ofstream *file, vtkImageData *cache) { // // Copied from vtkPostScriptWriter.cxx with addition of options to specify paper size and orientation. // int min1, max1, min2, max2, min3, max3; int bpp; int cols, rows, scols, srows; float scale = 1; int pagewid = (int)(mPaper[mFormat].Width*72); int pagehgt = (int)(mPaper[mFormat].Height*72); // Find the length of the rows to write. cache->GetWholeExtent(min1, max1, min2, max2, min3, max3); bpp = cache->GetNumberOfScalarComponents(); cols = max1 - min1 + 1; rows = max2 - min2 + 1; if(mOrient == 1) { // // Landscape orientation // int q = cols; cols = rows; rows = q; } // // Fit to width // scale = (float)pagewid/cols; scols = (int)(scale*cols*VTK_MARGIN); srows = (int)(scale*rows*VTK_MARGIN); // // If too high, fit to height // if(srows > pagehgt*VTK_MARGIN) { scale = scale*(pagehgt*VTK_MARGIN/srows); scols = (int)(scale*cols*VTK_MARGIN); srows = (int)(scale*rows*VTK_MARGIN); } float llx = (pagewid-scols) / 2; float lly = (pagehgt-srows) / 2; // spit out the PostScript header *file << "%!PS-Adobe-2.0 EPSF-2.0\n"; *file << "%%Creator: IFrIT\n"; *file << "%%Title: " << this->InternalFileName << endl; *file << "%%Pages: 1\n"; *file << "%%BoundingBox: " << (int) llx << " " << (int) lly << " " << (int) ( llx + scols + 0.5 ) << " " << (int) ( lly + srows + 0.5 ) << endl; *file << "%%EndComments\n"; *file << "/readstring {\n"; *file << " currentfile exch readhexstring pop\n"; *file << "} bind def\n"; if ( bpp == 3) { *file << "/rpicstr " << cols << " string def\n"; *file << "/gpicstr " << cols << " string def\n"; *file << "/bpicstr " << cols << " string def\n"; } else if (bpp == 1) { *file << "/picstr " << cols << " string def\n"; } else { vtkWarningMacro( " vtkPostScriptWriter only supports 1 and 3 component images"); } *file << "%%EndProlog\n"; *file << "%%Page: 1 1\n"; *file << "gsave\n"; *file << llx << " " << lly << " translate\n"; *file << scols << " " << srows << " scale\n"; *file << cols << " " << rows << " 8\n"; *file << "[ " << cols << " 0 0 " << -rows << " 0 " << rows << " ]\n"; if (bpp == 3) { *file << "{ rpicstr readstring }\n"; *file << "{ gpicstr readstring }\n"; *file << "{ bpicstr readstring }\n"; *file << "true 3\n"; *file << "colorimage\n"; } else { *file << "{ picstr readstring }\n"; *file << "image\n"; } } void iPostScriptWriter::WriteFile(ofstream *file, vtkImageData *data, int extent[6]) { // // Copied from vtkPostScriptWriter.cxx with addition of options to specify paper size and orientation. // int idxC, idx0, idx1, idx2; unsigned char *ptr; unsigned long count = 0; unsigned long tarGet; float progress = this->Progress; float area; int *wExtent; static int itemsperline = 0; char* hexits = (char *) "0123456789abcdef"; // Make sure we actually have data. if ( !data->GetPointData()->GetScalars()) { vtkErrorMacro(<< "Could not Get data from input."); return; } // take into consideration the scalar type switch (data->GetScalarType()) { case VTK_UNSIGNED_CHAR: break; default: vtkErrorMacro("PostScriptWriter only accepts unsigned char scalars!"); return; } int i0 = 0, i1 = 1, i2 = 2, i3 = 3; if(mOrient == 1) { i0 = 2; i1 = 3; i2 = 0; i3 = 1; } wExtent = this->GetInput()->GetWholeExtent(); area = ((extent[5] - extent[4] + 1)*(extent[3] - extent[2] + 1)* (extent[1] - extent[0] + 1)) / ((wExtent[5] -wExtent[4] + 1)*(wExtent[3] -wExtent[2] + 1)* (wExtent[1] -wExtent[0] + 1)); int numComponents = data->GetNumberOfScalarComponents(); // ignore alpha int maxComponent = numComponents; if (numComponents == 2) { maxComponent = 1; } if (numComponents == 4) { maxComponent = 3; } tarGet = (unsigned long)((extent[5]-extent[4]+1)* (extent[i3]-extent[i2]+1)/(50.0*area)); tarGet++; int ptrOffset = numComponents; int idx1run; if(mOrient == 1) { ptrOffset = numComponents*(extent[1]-extent[0]+1); } for (idx2 = extent[4]; idx2 <= extent[5]; ++idx2) { for (idx1run = extent[i3]; idx1run >= extent[i2]; idx1run--) { // // Orientation // idx1 = idx1run; if(mOrient == 1) { idx1 = extent[i3] + extent[i2] - idx1run; } if (!(count%tarGet)) { this->UpdateProgress(progress + count/(50.0*tarGet)); } count++; // write out components one at a time because for (idxC = 0; idxC < maxComponent; idxC++) { // // Orientation // if(mOrient == 1) { ptr = (unsigned char *)data->GetScalarPointer(idx1,extent[2],idx2); } else { ptr = (unsigned char *)data->GetScalarPointer(extent[0],idx1,idx2); } ptr += idxC; for ( idx0 = extent[i0]; idx0 <= extent[i1]; idx0++ ) { if ( itemsperline == 30 ) { *file << endl; itemsperline = 0; } *file << hexits[*ptr >> 4] << hexits[*ptr & 15]; ptr += ptrOffset; } } } } } ifrit-3.4.2/core/ipostscriptwriter.h0000644000175700010010000000434712167404417016141 0ustar HomeNone/*========================================================================= Program: Ionization FRont Interactive Tool (IFRIT) Language: C++ Copyright (c) 2002-2012 Nick Gnedin All rights reserved. This file may be distributed and/or modified under the terms of the GNU General Public License version 2 as published by the Free Software Foundation and appearing in the file LICENSE.GPL included in the packaging of this file. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHORS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. =========================================================================*/ // // vtkPostScriptWriter with different paper formats // #ifndef IPOSTSCRIPTWRITER_H #define IPOSTSCRIPTWRITER_H #define NFORMATS 11 #include class iPostScriptWriter : public vtkPostScriptWriter { public: vtkTypeMacro(iPostScriptWriter,vtkPostScriptWriter); static iPostScriptWriter* New(){ return new iPostScriptWriter; } virtual void SetPaperFormat(int f); inline int GetPaperFormat(){ return mFormat; } virtual void SetOrientation(int o); inline int GetOrientation(){ return mOrient; } static char* GetPaperFormatName(int n){ if(n>=0 && n #include #include #include // // Templates (needed for some compilers) // #include "igenericfiltertemplate.h" iProbeFilter::iProbeFilter(iViewSubject *vo) : iGenericFilter(vo,1,true,true) { } void iProbeFilter::ProduceOutput() { vtkDataObject *input = this->GetInput(); vtkDataSet *output = this->GetOutput(); vtkDataObject *source = this->GetSource(); if(source->IsA("vtkImageData") && input->IsA("vtkPointSet") && output->IsA("vtkPointSet")) { this->ProduceOutputForImageData(vtkPointSet::SafeDownCast(input),vtkPointSet::SafeDownCast(output),vtkImageData::SafeDownCast(source)); } else { output->ShallowCopy(input); // Probe does not copy normals... this->vtkProbeFilter::Probe(vtkDataSet::SafeDownCast(input),vtkDataSet::SafeDownCast(source),output); } } void iProbeFilter::ProduceOutputForImageData(vtkPointSet *input, vtkPointSet *output, vtkImageData *source) { output->ShallowCopy(input); vtkPoints *inpts = input->GetPoints(); if(inpts == 0) return; vtkIdType numPts = inpts->GetNumberOfPoints(); if(!this->ScalarsInit(source->GetPointData(),numPts)) return; int j, dims[3], ijk1[3], ijk2[3]; double org[3], spa[3]; source->GetDimensions(dims); source->GetSpacing(spa); source->GetOrigin(org); vtkIdType l, loff, loff111, loff112, loff121, loff122, loff211, loff212, loff221, loff222; double x[3]; double d1[3], d2[3]; bool per[3]; this->GetLimits()->GetPeriodicities(per); // // Loop over all input points, interpolating source data // for(l=0; lUpdateProgress((float)l/numPts); if(this->GetAbortExecute()) break; } // Get the xyz coordinate of the point in the input dataset inpts->GetPoint(l,x); // Find the cell that contains xyz and get it iDataHelper::CIC(per,dims,org,spa,x,ijk1,ijk2,d1,d2); loff111 = wScalarDimIn*(ijk1[0]+dims[0]*(ijk1[1]+(vtkIdType)dims[1]*ijk1[2])); loff112 = wScalarDimIn*(ijk1[0]+dims[0]*(ijk1[1]+(vtkIdType)dims[1]*ijk2[2])); loff121 = wScalarDimIn*(ijk1[0]+dims[0]*(ijk2[1]+(vtkIdType)dims[1]*ijk1[2])); loff122 = wScalarDimIn*(ijk1[0]+dims[0]*(ijk2[1]+(vtkIdType)dims[1]*ijk2[2])); loff211 = wScalarDimIn*(ijk2[0]+dims[0]*(ijk1[1]+(vtkIdType)dims[1]*ijk1[2])); loff212 = wScalarDimIn*(ijk2[0]+dims[0]*(ijk1[1]+(vtkIdType)dims[1]*ijk2[2])); loff221 = wScalarDimIn*(ijk2[0]+dims[0]*(ijk2[1]+(vtkIdType)dims[1]*ijk1[2])); loff222 = wScalarDimIn*(ijk2[0]+dims[0]*(ijk2[1]+(vtkIdType)dims[1]*ijk2[2])); loff = l*wScalarDimOut; for(j=0; jScalarsDone(output->GetPointData()); } ifrit-3.4.2/core/iprobefilter.h0000644000175700010010000000364512167404417015007 0ustar HomeNone/*========================================================================= Program: Ionization FRont Interactive Tool (IFRIT) Language: C++ Copyright (c) 2002-2012 Nick Gnedin All rights reserved. This file may be distributed and/or modified under the terms of the GNU General Public License version 2 as published by the Free Software Foundation and appearing in the file LICENSE.GPL included in the packaging of this file. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHORS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. =========================================================================*/ // // Optimized version of vtkProbeFilter for vtkPolyData input and vtkImageData source; // Also, vtkProbeFilter does not pass through normals of the input (for a good reason!). // This filter adds passing normals. // #ifndef IPROBEFILTER_H #define IPROBEFILTER_H #include "igenericfilter.h" #include class vtkImageData; class vtkPointSet; class iProbeFilter : public iGenericFilter { IGENERICFILTER_DECLARE(iProbeFilter,vtkProbeFilter); protected: virtual void ProduceOutput(); private: void ProduceOutputForImageData(vtkPointSet *input, vtkPointSet *output, vtkImageData *source); }; #endif // IPROBEFILTER_H ifrit-3.4.2/core/irangecollection.cpp0000755000175700010010000001056612167404434016177 0ustar HomeNone/*========================================================================= Program: Ionization FRont Interactive Tool (IFRIT) Language: C++ Copyright (c) 2002-2012 Nick Gnedin All rights reserved. This file may be distributed and/or modified under the terms of the GNU General Public License version 2 as published by the Free Software Foundation and appearing in the file LICENSE.GPL included in the packaging of this file. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHORS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. =========================================================================*/ #include "irangecollection.h" #include "ierror.h" #include "imath.h" // // Templates // #include "iarraytemplate.h" // // iRangeCollection class // iRangeCollection::iRangeCollection(float min, float max) { mTiled = false; mGlobalMin = min; mGlobalMax = max; mArr.Add(Range(min,max)); } iRangeCollection::~iRangeCollection() { } void iRangeCollection::SetGlobalRange(float min, float max) { if(min < max) { // // Scale ranges fist // int i; float oldStart = this->ApplyStretch(mGlobalMin,false); float newStart = this->ApplyStretch(min,false); float scale = (this->ApplyStretch(max,true)-newStart)/(this->ApplyStretch(mGlobalMax,true)-oldStart); for(i=0; iResetStretch(newStart+scale*(this->ApplyStretch(mArr[i].Min,false)-oldStart)); mArr[i].Max = this->ResetStretch(newStart+scale*(this->ApplyStretch(mArr[i].Max,true)-oldStart)); } mGlobalMin = min; mGlobalMax = max; } } void iRangeCollection::SetRange(int i, float min, float max) { if(i<0 || i>=mArr.Size()) return; if(min > max) { float tmp = min; min = max; max = tmp; } if(mTiled && i>0) { if(min < mArr[i-1].Min) min = mArr[i-1].Min; mArr[i].Min = mArr[i-1].Max = min; } else if(!mTiled) { if(min < mGlobalMin) min = mGlobalMin; mArr[i].Min = min; } if(mTiled && i mArr[i+1].Max) max = mArr[i+1].Max; mArr[i].Max = mArr[i+1].Min = max; } else if(!mTiled) { if(max > mGlobalMax) max = mGlobalMax; mArr[i].Max = max; } } void iRangeCollection::AddRange(float min, float max) { mArr.Add(Range(min,max)); } void iRangeCollection::AddRange() { int n = mArr.Size() - 1; float mid = this->ResetStretch(0.5f*(this->ApplyStretch(mArr[n].Min,false)+this->ApplyStretch(mArr[n].Max,true))); float max = mArr[n].Max; mArr[n].Max = mid; this->AddRange(mid,max); } bool iRangeCollection::RemoveRange(int n) { if(mArr.Size()>1 && n>=0 && n 0) { mArr[n-1].Max = mArr[n].Max; } else { mArr[1].Min = mGlobalMin; } } mArr.Remove(n); return true; } else return false; } void iRangeCollection::Reset() { while(mArr.Size() > 1) mArr.RemoveLast(); mArr[0].Min = mGlobalMin; mArr[0].Max = mGlobalMax; } void iRangeCollection::SetTiled(bool s) { int i, j; Range tmp; if(mTiled == s) return; mTiled = s; if(!s) return; // // bubble sort - since the number of pieces is likely to be small // for(i=1; imArr.Size(); i++) mArr[i] = f->mArr[i]; while(mArr.Size() < f->mArr.Size()) mArr.Add(f->mArr[mArr.Size()]); while(mArr.Size() > f->mArr.Size()) mArr.RemoveLast(); mGlobalMin = f->mGlobalMin; mGlobalMax = f->mGlobalMax; mTiled = f->mTiled; this->SetStretch(f->GetStretch()); } ifrit-3.4.2/core/irangecollection.h0000755000175700010010000001012612167404417015635 0ustar HomeNone/*========================================================================= Program: Ionization FRont Interactive Tool (IFRIT) Language: C++ Copyright (c) 2002-2012 Nick Gnedin All rights reserved. This file may be distributed and/or modified under the terms of the GNU General Public License version 2 as published by the Free Software Foundation and appearing in the file LICENSE.GPL included in the packaging of this file. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHORS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. =========================================================================*/ #ifndef IRANGECOLLECTION_H #define IRANGECOLLECTION_H #include "idatastretch.h" #include "iarray.h" class iRangeCollection : public iDataStretchUser { public: class Range { public: Range(){ Min = 0.0; Max = 0.0; } Range(float min, float max){ Min = min; Max = max; } float Min, Max; }; iRangeCollection(float min = 0.0, float max = 1.0); ~iRangeCollection(); inline int GetN() const { return mArr.Size(); } float GetMin(int i) const; float GetMax(int i) const; float GetGlobalMin() const; float GetGlobalMax() const; void GetRange(int i, float &min, float &max) const; // // Functions that return stretched values // float GetStretchedMin(int i) const; float GetStretchedMax(int i) const; float GetStretchedGlobalMin() const; float GetStretchedGlobalMax() const; void SetGlobalRange(float min, float max); void SetGlobalMin(float min); void SetGlobalMax(float max); void SetRange(int i, float min, float max); void SetMin(int i, float min); void SetMax(int i, float max); void SetTiled(bool s); inline bool GetTiled() const { return mTiled; } void AddRange(); void AddRange(float min, float max); bool RemoveRange(int n); void Copy(const iRangeCollection *f); void Reset(); private: iArray mArr; float mGlobalMin, mGlobalMax; bool mTiled; }; inline float iRangeCollection::GetMin(int i) const { if(i>=0 && i=0 && i=0 && iApplyStretch(mArr[i].Min,false); else return this->ApplyStretch(mGlobalMin,false); } inline float iRangeCollection::GetStretchedMax(int i) const { if(i>=0 && iApplyStretch(mArr[i].Max,true); else return this->ApplyStretch(mGlobalMax,true); } inline float iRangeCollection::GetStretchedGlobalMin() const { return this->ApplyStretch(mGlobalMin,false); } inline float iRangeCollection::GetStretchedGlobalMax() const { return this->ApplyStretch(mGlobalMax,true); } inline void iRangeCollection::GetRange(int i, float &min, float &max) const { if(i>=0 && iSetGlobalRange(min,mGlobalMax); } inline void iRangeCollection::SetGlobalMax(float max) { this->SetGlobalRange(mGlobalMin,max); } inline void iRangeCollection::SetMin(int i, float min) { this->SetRange(i,min,this->GetMax(i)); } inline void iRangeCollection::SetMax(int i, float max) { this->SetRange(i,this->GetMin(i),max); } #endif // IRANGECOLLECTION_H ifrit-3.4.2/core/irangemapping.cpp0000755000175700010010000000344412167404435015475 0ustar HomeNone/*========================================================================= Program: Ionization FRont Interactive Tool (IFRIT) Language: C++ Copyright (c) 2002-2012 Nick Gnedin All rights reserved. This file may be distributed and/or modified under the terms of the GNU General Public License version 2 as published by the Free Software Foundation and appearing in the file LICENSE.GPL included in the packaging of this file. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHORS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. =========================================================================*/ #include "irangemapping.h" #include "ihistogrammaker.h" #include "irangecollection.h" #include iRangeMapping::iRangeMapping(iRangeCollection *rc, iHistogramMaker *hm, vtkObject *user) { mRC = rc; mHM = hm; mUser = user; } const iHistogram* iRangeMapping::GetHistogram(int nBins) const { mHM->SetStretch(mRC->GetStretch()); return mHM->GetHistogram(nBins); } int iRangeMapping::GetEstimatedNumberOfBins() const { return mHM->GetEstimatedNumberOfBins(); } void iRangeMapping::Modified() const { if(mUser != 0) mUser->Modified(); } ifrit-3.4.2/core/irangemapping.h0000755000175700010010000000354512167404417015144 0ustar HomeNone/*========================================================================= Program: Ionization FRont Interactive Tool (IFRIT) Language: C++ Copyright (c) 2002-2012 Nick Gnedin All rights reserved. This file may be distributed and/or modified under the terms of the GNU General Public License version 2 as published by the Free Software Foundation and appearing in the file LICENSE.GPL included in the packaging of this file. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHORS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. =========================================================================*/ // // A wrapper to package the range collection and its histogram together // #ifndef IRANGEMAPPING_H #define IRANGEMAPPING_H class iHistogram; class iHistogramMaker; class iRangeCollection; class vtkObject; class iRangeMapping { public: iRangeMapping(iRangeCollection *rc, iHistogramMaker *hm, vtkObject *user); inline iRangeCollection* GetRangeCollection() const { return mRC; } const iHistogram* GetHistogram(int nBins = 0) const; int GetEstimatedNumberOfBins() const; void Modified() const; private: iHistogramMaker *mHM; iRangeCollection *mRC; vtkObject *mUser; }; #endif // IRANGENMAPPING_H ifrit-3.4.2/core/ireducepolydatafilter.cpp0000755000175700010010000000356212167404435017241 0ustar HomeNone/*========================================================================= Program: Ionization FRont Interactive Tool (IFRIT) Language: C++ Copyright (c) 2002-2012 Nick Gnedin All rights reserved. This file may be distributed and/or modified under the terms of the GNU General Public License version 2 as published by the Free Software Foundation and appearing in the file LICENSE.GPL included in the packaging of this file. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHORS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. =========================================================================*/ #include "ireducepolydatafilter.h" // // Templates // #include "igenericfiltertemplate.h" iReducePolyDataFilter::iReducePolyDataFilter(iViewSubject *vo) : iGenericPolyDataToPolyDataFilter(vo,1,true,false) { } void iReducePolyDataFilter::ProduceOutput() { vtkPolyData *input = vtkPolyData::SafeDownCast(this->GetInput()); vtkPolyData *output = this->GetOutput(); if(input->GetPoints()==0 || input->GetPoints()->GetDataType()==VTK_FLOAT) { this->ExecuteParent(); } else { vtkWarningMacro("Cannot reduce polygonal data with double-valued coordinates due to a VTK bug."); output->ShallowCopy(input); } } ifrit-3.4.2/core/ireducepolydatafilter.h0000644000175700010010000000313412167404417016676 0ustar HomeNone/*========================================================================= Program: Ionization FRont Interactive Tool (IFRIT) Language: C++ Copyright (c) 2002-2012 Nick Gnedin All rights reserved. This file may be distributed and/or modified under the terms of the GNU General Public License version 2 as published by the Free Software Foundation and appearing in the file LICENSE.GPL included in the packaging of this file. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHORS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. =========================================================================*/ #ifndef IREDUCEPOLYDATAFILTER_H #define IREDUCEPOLYDATAFILTER_H #include "igenericfilter.h" #include class iReducePolyDataFilter : public iGenericPolyDataToPolyDataFilter { IGENERICFILTER_DECLARE(iReducePolyDataFilter,vtkDecimatePro); protected: virtual void ProduceOutput(); }; #endif // IREDUCEPOLYDATAFILTER_H ifrit-3.4.2/core/ireducepolydatafilter2.cpp0000755000175700010010000002206312167404435017320 0ustar HomeNone/*========================================================================= Program: Ionization FRont Interactive Tool (IFRIT) Language: C++ Copyright (c) 2002-2012 Nick Gnedin All rights reserved. This file may be distributed and/or modified under the terms of the GNU General Public License version 2 as published by the Free Software Foundation and appearing in the file LICENSE.GPL included in the packaging of this file. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHORS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. =========================================================================*/ #include "ireducepolydatafilter2.h" #include "vtkCellArray.h" #include "vtkEdgeTable.h" #include "vtkDoubleArray.h" #include "vtkIdList.h" #include "vtkMath.h" #include "vtkPointData.h" #include "vtkPriorityQueue.h" // // Templates // #include "igenericfiltertemplate.h" iReducePolyDataFilter2::iReducePolyDataFilter2(iViewSubject *vo) : iGenericPolyDataToPolyDataFilter(vo,1,true,false) { } void iReducePolyDataFilter2::ProduceOutput() { vtkPolyData *input = vtkPolyData::SafeDownCast(this->GetInput()); vtkPolyData *output = this->GetOutput(); // // The code between === lines is copied from vtkQuadricDecimation.cxx file with minor modifications, as marked behind /// comments // Below is the original copyright notice. // // Copyright (c) Ken Martin, Will Schroeder, Bill Lorensen // All rights reserved. // See Copyright.txt or http://www.kitware.com/Copyright.htm for details. // // ========================================================================= // vtkIdType numPts = input->GetNumberOfPoints(); vtkIdType numTris = input->GetNumberOfPolys(); vtkIdType edgeId, i; int j; double cost; double *x; vtkCellArray *polys; vtkDataArray *attrib; vtkPoints *points; vtkPointData *pointData; vtkIdType endPtIds[2]; vtkIdList *outputCellList; vtkIdType npts, *pts; vtkIdType numDeletedTris=0; // check some assuptiona about the data if (input->GetPolys() == NULL || input->GetPoints() == NULL || input->GetPointData() == NULL || input->GetFieldData() == NULL) { vtkErrorMacro("Nothing to decimate"); return; } if (input->GetPolys()->GetMaxCellSize() > 3) { vtkErrorMacro("Can only decimate triangles"); return; } polys = vtkCellArray::New(); /// ------ Removed ------------------------------------------ /// points = vtkPoints::New(); /// --------------------------------------------------------- /// ++++++ Added ++++++++++++++++++++++++++++++++++++++++++++ points = vtkPoints::New(input->GetPoints()->GetDataType()); /// +++++++++++++++++++++++++++++++++++++++++++++++++++++++++ pointData = vtkPointData::New(); outputCellList = vtkIdList::New(); // copy the input (only polys) to our working mesh this->Mesh = vtkPolyData::New(); points->DeepCopy(input->GetPoints()); this->Mesh->SetPoints(points); points->Delete(); polys->DeepCopy(input->GetPolys()); this->Mesh->SetPolys(polys); polys->Delete(); if (this->AttributeErrorMetric) { this->Mesh->GetPointData()->DeepCopy(input->GetPointData()); } pointData->Delete(); this->Mesh->GetFieldData()->PassData(input->GetFieldData()); this->Mesh->BuildCells(); this->Mesh->BuildLinks(); this->ErrorQuadrics = new vtkQuadricDecimation::ErrorQuadric[numPts]; vtkDebugMacro(<<"Computing Edges"); this->Edges->InitEdgeInsertion(numPts, 1); // storing edge id as attribute this->EdgeCosts->Allocate(this->Mesh->GetPolys()->GetNumberOfCells() * 3); for (i = 0; i < this->Mesh->GetNumberOfCells(); i++) { this->Mesh->GetCellPoints(i, npts, pts); for (j = 0; j < 3; j++) { if (this->Edges->IsEdge(pts[j], pts[(j+1)%3]) == -1) { // If this edge has not been processed, get an id for it, add it to // the edge list (Edges), and add its endpoints to the EndPoint1List // and EndPoint2List (the 2 endpoints to different lists). edgeId = this->Edges->GetNumberOfEdges(); this->Edges->InsertEdge(pts[j], pts[(j+1)%3], edgeId); this->EndPoint1List->InsertId(edgeId, pts[j]); this->EndPoint2List->InsertId(edgeId, pts[(j+1)%3]); } } } this->UpdateProgress(0.1); this->NumberOfComponents = 0; if (this->AttributeErrorMetric) { this->ComputeNumberOfComponents(); } x = new double [3+this->NumberOfComponents]; this->CollapseCellIds = vtkIdList::New(); this->TempX = new double [3+this->NumberOfComponents]; this->TempQuad = new double[11 + 4 * this->NumberOfComponents]; this->TempB = new double [3 + this->NumberOfComponents]; this->TempA = new double*[3 + this->NumberOfComponents]; this->TempData = new double [(3 + this->NumberOfComponents)*(3 + this->NumberOfComponents)]; for (i = 0; i < 3 + this->NumberOfComponents; i++) { this->TempA[i] = this->TempData+i*(3 + this->NumberOfComponents); } this->TargetPoints->SetNumberOfComponents(3+this->NumberOfComponents); vtkDebugMacro(<<"Computing Quadrics"); this->InitializeQuadrics(numPts); this->AddBoundaryConstraints(); this->UpdateProgress(0.15); vtkDebugMacro(<<"Computing Costs"); // Compute the cost of and target point for collapsing each edge. for (i = 0; i < this->Edges->GetNumberOfEdges(); i++) { if (this->AttributeErrorMetric) { cost = this->ComputeCost2(i, x); } else { cost = this->ComputeCost(i, x); } this->EdgeCosts->Insert(cost, i); this->TargetPoints->InsertTuple(i, x); } this->UpdateProgress(0.20); // Okay collapse edges until desired reduction is reached this->ActualReduction = 0.00f; this->NumberOfEdgeCollapses = 0; edgeId = this->EdgeCosts->Pop(0,cost); int abort = 0; while ( !abort && edgeId >= 0 && cost < VTK_DOUBLE_MAX && this->ActualReduction < this->TargetReduction ) { if ( ! (this->NumberOfEdgeCollapses % 10000) ) { vtkDebugMacro(<<"Collapsing edge#" << this->NumberOfEdgeCollapses); this->UpdateProgress (0.20 + 0.80*this->NumberOfEdgeCollapses/numPts); abort = this->GetAbortExecute(); } endPtIds[0] = this->EndPoint1List->GetId(edgeId); endPtIds[1] = this->EndPoint2List->GetId(edgeId); this->TargetPoints->GetTuple(edgeId, x); // check for a poorly placed point if ( !this->IsGoodPlacement(endPtIds[0], endPtIds[1], x)) { vtkDebugMacro(<<"Poor placement detected " << edgeId << " " << cost); // return the point to the queue but with the max cost so that // when it is recomputed it will be reconsidered this->EdgeCosts->Insert(VTK_DOUBLE_MAX, edgeId); edgeId = this->EdgeCosts->Pop(0, cost); continue; } this->NumberOfEdgeCollapses++; // Set the new coordinates of point0. this->SetPointAttributeArray(endPtIds[0], x); vtkDebugMacro(<<"Cost: " << cost << " Edge: " << endPtIds[0] << " " << endPtIds[1]); // Merge the quadrics of the two points. this->AddQuadric(endPtIds[1], endPtIds[0]); this->UpdateEdgeData(endPtIds[0], endPtIds[1]); // Update the output triangles. numDeletedTris += this->CollapseEdge(endPtIds[0], endPtIds[1]); this->ActualReduction = (double) numDeletedTris / numTris; edgeId = this->EdgeCosts->Pop(0, cost); } vtkDebugMacro(<<"Number Of Edge Collapses: " << this->NumberOfEdgeCollapses << " Cost: " << cost); // clean up working data for (i = 0; i < numPts; i++) { delete [] this->ErrorQuadrics[i].Quadric; } delete [] this->ErrorQuadrics; delete [] x; this->CollapseCellIds->Delete(); delete [] this->TempX; delete [] this->TempQuad; delete [] this->TempB; delete [] this->TempA; delete [] this->TempData; // copy the simplified mesh from the working mesh to the output mesh for (i = 0; i < this->Mesh->GetNumberOfCells(); i++) { if (this->Mesh->GetCell(i)->GetCellType() != VTK_EMPTY_CELL) { outputCellList->InsertNextId(i); } } output->Reset(); /// ++++++ Added ++++++++++++++++++++++++++++++++++++++++++++ output->SetPoints(points); /// +++++++++++++++++++++++++++++++++++++++++++++++++++++++++ output->Allocate(this->Mesh, outputCellList->GetNumberOfIds()); output->GetPointData()->CopyAllocate(this->Mesh->GetPointData(),1); output->CopyCells(this->Mesh, outputCellList); this->Mesh->DeleteLinks(); this->Mesh->Delete(); outputCellList->Delete(); // renormalize, clamp attributes if (this->AttributeErrorMetric) { if (NULL != (attrib = output->GetPointData()->GetNormals())) { for (i = 0; i < attrib->GetNumberOfTuples(); i++) { vtkMath::Normalize(attrib->GetTuple3(i)); } } // might want to add clamping texture coordinates?? } // // ========================================================================= // } ifrit-3.4.2/core/ireducepolydatafilter2.h0000644000175700010010000000316412167404417016763 0ustar HomeNone/*========================================================================= Program: Ionization FRont Interactive Tool (IFRIT) Language: C++ Copyright (c) 2002-2012 Nick Gnedin All rights reserved. This file may be distributed and/or modified under the terms of the GNU General Public License version 2 as published by the Free Software Foundation and appearing in the file LICENSE.GPL included in the packaging of this file. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHORS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. =========================================================================*/ #ifndef IREDUCEPOLYDATAFILTER2_H #define IREDUCEPOLYDATAFILTER2_H #include "igenericfilter.h" #include class iReducePolyDataFilter2 : public iGenericPolyDataToPolyDataFilter { IGENERICFILTER_DECLARE(iReducePolyDataFilter2,vtkQuadricDecimation); protected: virtual void ProduceOutput(); }; #endif // IREDUCEPOLYDATAFILTER2_H ifrit-3.4.2/core/irendertool.cpp0000755000175700010010000005515712167404435015212 0ustar HomeNone/*========================================================================= Program: Ionization FRont Interactive Tool (IFRIT) Language: C++ Copyright (c) 2002-2012 Nick Gnedin All rights reserved. This file may be distributed and/or modified under the terms of the GNU General Public License version 2 as published by the Free Software Foundation and appearing in the file LICENSE.GPL included in the packaging of this file. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHORS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. =========================================================================*/ #include "irendertool.h" #include "iactor.h" #include "icamera.h" #include "icontrolmodule.h" #include "ierror.h" #include "ieventobserver.h" #include "iextensionfactory.h" #include "ilightkit.h" #include "imagnifier.h" #include "irendertoolbackground.h" #include "ishell.h" #include "ishellfactory.h" #include "istereoimage.h" #include "istereoimagearray.h" #include "iviewmodule.h" #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include // // Templates // #include "iarraytemplate.h" using namespace iParameter; // // Helper classes // class iDualWindowObserver : public iEventObserver { public: vtkTypeMacro(iDualWindowObserver,iEventObserver); static iDualWindowObserver* New(iRenderTool *rt = 0) { IERROR_ASSERT(rt); return new iDualWindowObserver(rt); } protected: iDualWindowObserver(iRenderTool *rt) : iEventObserver(rt->GetViewModule()->GetControlModule()->GetShell()) { mRenderTool = rt; } virtual void ExecuteBody(vtkObject *, unsigned long event, void *) { switch(event) { case EndEvent: { if(mRenderTool->mDualWin != 0) mRenderTool->mDualWin->Render(); break; } case ModifiedEvent: { if(mRenderTool->mDualWin != 0) mRenderTool->mDualWin->SetSize(mRenderTool->mMainWin->GetSize()); break; } } } private: iRenderTool *mRenderTool; }; class iRendererObserver : public iEventObserver { public: vtkTypeMacro(iRendererObserver,iEventObserver); static iRendererObserver* New(iRenderTool *rt = 0) { IERROR_ASSERT(rt); return new iRendererObserver(rt); } protected: iRendererObserver(iRenderTool *rt) : iEventObserver(rt->GetViewModule()->GetControlModule()->GetShell()) { mRenderTool = rt; } virtual void ExecuteBody(vtkObject *, unsigned long event, void *) { switch(event) { case ModifiedEvent: { mRenderTool->GetViewModule()->ClearCache(); // our size is cached by VM break; } case ResetCameraClippingRangeEvent: { double *cr = mRenderTool->mMainRen->GetActiveCamera()->GetClippingRange(); if(mRenderTool->mAutoClippingRange) { mRenderTool->mClippingRange[0] = cr[0]; mRenderTool->mClippingRange[1] = cr[1]; } else { cr[0] = mRenderTool->mClippingRange[0]; cr[1] = mRenderTool->mClippingRange[1]; } break; } } } private: iRenderTool *mRenderTool; }; class iStereoRenderObserver : public iEventObserver { public: vtkTypeMacro(iStereoRenderObserver,iEventObserver); static iStereoRenderObserver* New(iRenderTool *rt = 0) { IERROR_ASSERT(rt); return new iStereoRenderObserver(rt); } protected: iStereoRenderObserver(iRenderTool *rt) : iEventObserver(rt->GetViewModule()->GetControlModule()->GetShell()) { mRenderTool = rt; } virtual void ExecuteBody(vtkObject *, unsigned long event, void *) { switch(event) { case ModifiedEvent: { if(mRenderTool->mMainWinStereoRender != (mRenderTool->mMainWin->GetStereoRender()!=0)) { mRenderTool->mMainWin->SetStereoRender(mRenderTool->mMainWinStereoRender?1:0); iConsole::Display(iConsole::_Notification,"Pressing 3 to toggle the stereo mode is no longer supported.\nPlease use GUI/command-line controls to toggle the stereo mode."); } break; } } } private: iRenderTool *mRenderTool; }; // // Main class // iRenderTool* iRenderTool::New(iViewModule *vm) { IERROR_ASSERT(vm); iRenderTool *tmp = iExtensionFactory::CreateRenderTool(vm); IERROR_ASSERT(tmp); return tmp; } iRenderTool::iRenderTool(iViewModule *vm, vtkRenderer *ren, iMagnifier *mag) : mViewModule(vm), mStereoModeOffset(2-VTK_STEREO_CRYSTAL_EYES) { // // Keeping the rendering order (a workaround for a VTK bug) // mActorObjects = vtkPropCollection::New(); IERROR_ASSERT(mActorObjects); mVolumeObjects = vtkPropCollection::New(); IERROR_ASSERT(mVolumeObjects); // // Main Window stuff // mDualWin = 0; mMainWin = iShellFactory::CreateRenderWindow(this); IERROR_ASSERT(mMainWin); #ifdef I_NO_STEREO mMainWin->SetStereoCapableWindow(0); #else mMainWin->SetStereoCapableWindow(1); #endif if(ren == 0) { mMainRen = vtkRenderer::New(); IERROR_ASSERT(mMainRen); mMainInt = iShellFactory::CreateRenderWindowInteractor(this); IERROR_ASSERT(mMainInt); mMainCam = iCamera::New(this); IERROR_ASSERT(mMainCam); mMainRen->SetActiveCamera(mMainCam->GetDevice()); // // Configure Renderer. It is important to switch the backing store off for the // stereo mode to work properly. // mMainRen->SetLayer(IRENDERTOOLBACKGROUND_FRONT_LAYER); mMainRen->BackingStoreOff(); mMainRen->TwoSidedLightingOff(); mMainRen->LightFollowCameraOn(); mMainRen->GetActiveCamera()->SetEyeAngle(2.0); // // Configure Interactor // mMainInt->SetRenderWindow(mMainWin); mMainInt->LightFollowCameraOff(); // // Create and initiate lights // mLights = iLightKit::New(); IERROR_ASSERT(mLights); mLights->AddLightsToRenderer(mMainRen); // // Image magnifier // mMagnifier = iMagnifier::New(); IERROR_ASSERT(mMagnifier); } else { mMainRen = ren; mMainInt = 0; mMainCam = 0; mLights = 0; mMagnifier = mag; IERROR_ASSERT(mMagnifier); mMagnifier->Register(ren); } // // Create backgrounds // mMainBkg = iRenderToolBackground::New(); IERROR_ASSERT(mMainBkg); mDualBkg = iRenderToolBackground::New(); IERROR_ASSERT(mDualBkg); // // Configure Window // mMainWin->SetSize(640,480); mMainWin->SetNumberOfLayers(2); mMainWin->AddRenderer(mMainBkg->GetRenderer()); mMainWin->AddRenderer(mMainRen); mMainWin->SetWindowName("IFrIT - Visualization Window"); // // Dual window renderer and observer // mDualRen = this->CreateRenderer(); mDualRen->SetActiveCamera(mMainRen->GetActiveCamera()); mDualRen->LightFollowCameraOff(); // // Dual window observer // mDualWindowObserver = iDualWindowObserver::New(this); IERROR_ASSERT(mDualWindowObserver); // // Dual window alignment markers (only needed for the primary window) // if(ren == 0) { mStereoAlignmentMarksActor = vtkPropAssembly::New(); IERROR_ASSERT(mStereoAlignmentMarksActor); mStereoAlignmentMarksActor->VisibilityOff(); mStereoAlignmentMarksActor->PickableOff(); vtkPolyDataMapper2D *mapper2D = vtkPolyDataMapper2D::New(); IERROR_ASSERT(mapper2D); vtkLineSource *ls; vtkActor2D *actor2D[8]; float aml = 0.15; float amo = 0.1; int i; for(i=0; i<8; i++) { actor2D[i] = vtkActor2D::New(); IERROR_ASSERT(actor2D[i]); mapper2D = vtkPolyDataMapper2D::New(); IERROR_ASSERT(mapper2D); ls = vtkLineSource::New(); IERROR_ASSERT(ls); ls->SetResolution(1); if(i%2 == 0) { ls->SetPoint1(-aml,0.0,0.0); ls->SetPoint2(aml,0.0,0.0); } else { ls->SetPoint1(0.0,-aml,0.0); ls->SetPoint2(0.0,aml,0.0); } ls->Update(); mapper2D->SetInput(ls->GetOutput()); ls->Delete(); vtkCoordinate *c = vtkCoordinate::New(); IERROR_ASSERT(c); c->SetCoordinateSystemToView(); mapper2D->SetTransformCoordinate(c); c->Delete(); actor2D[i]->SetMapper(mapper2D); mapper2D->Delete(); actor2D[i]->GetProperty()->SetColor(0.0,0.0,0.0); actor2D[i]->GetPositionCoordinate()->SetCoordinateSystemToNormalizedViewport(); actor2D[i]->PickableOff(); actor2D[i]->SetPosition((0.5-amo)*(2*((i/2)%2)-1),(0.5-amo)*(2*((i/4)%2)-1)); actor2D[i]->SetLayerNumber(1); mStereoAlignmentMarksActor->AddPart(actor2D[i]); actor2D[i]->Delete(); } this->AddObject(mStereoAlignmentMarksActor); mStereoAlignmentMarksActor->Delete(); } else { mStereoAlignmentMarksActor = 0; } // // Clipping range controls // mRendererObserver = iRendererObserver::New(this); IERROR_ASSERT(mRendererObserver); mAutoClippingRange = true; mMainRen->AddObserver(vtkCommand::ResetCameraClippingRangeEvent,mRendererObserver); mMainRen->AddObserver(vtkCommand::ModifiedEvent,mRendererObserver); // // Disable pressing 3 in the render window // mStereoRenderObserver = iStereoRenderObserver::New(this); IERROR_ASSERT(mStereoRenderObserver); mMainWin->AddObserver(vtkCommand::ModifiedEvent,mStereoRenderObserver); // // RenderWindow collection // mWindowCollection = vtkRenderWindowCollection::New(); IERROR_ASSERT(mWindowCollection); mWindowCollectionUpToDate = false; // // Properties // mStereoMode = 0; this->SetMainWinStereoRender(false); mMainWin->SetStereoType(0); // for pressing 3 in the render window mAntialiasing = mBackgroundImageFixedAspect = false; mStereoAlignmentMarksOn = true; // // Set the properties // mFontScale = 0; mFontType = TextType::Arial; //this->SetAntialiasing(true); } iRenderTool::~iRenderTool() { this->ShowDualWindow(false); mActorObjects->Delete(); mVolumeObjects->Delete(); mWindowCollection->RemoveAllItems(); mWindowCollection->Delete(); mDualWindowObserver->Delete(); mMagnifier->Delete(); mMainRen->RemoveObserver(mStereoRenderObserver); mStereoRenderObserver->Delete(); mMainRen->RemoveObserver(mRendererObserver); mRendererObserver->Delete(); if(mLights != 0) mLights->Delete(); if(mMainInt != 0) mMainInt->Delete(); if(mMainCam != 0) mMainCam->Delete(); mMainRen->SetRenderWindow(0); mMainWin->RemoveRenderer(mMainRen); mMainWin->RemoveRenderer(mMainBkg->GetRenderer()); mMainBkg->Delete(); mDualBkg->Delete(); mDualRen->Delete(); mMainWin->RemoveAllObservers(); mMainRen->Delete(); mMainWin->Delete(); } int iRenderTool::GetRenderingMagnification() const { return mMagnifier->GetMagnification(); } int iRenderTool::GetNumberOfActiveViews() const { return (mDualWin == 0) ? 1 : 2; } void iRenderTool::Render() { mMainWin->InvokeEvent(vtkCommand::StartEvent,NULL); this->ResetCameraClippingRange(); mMainWin->Render(); mMainWin->InvokeEvent(vtkCommand::EndEvent,NULL); } void iRenderTool::ResetCamera() { const double scale = 1.6/sqrt(3.0); int i; double bounds[6], fp[3]; mMainRen->ComputeVisiblePropBounds(bounds); mMainRen->GetActiveCamera()->GetFocalPoint(fp); for(i=0; i<3; i++) { if(fabs(bounds[2*i+0]-fp[i]) > fabs(bounds[2*i+1]-fp[i])) { bounds[2*i+1] = 2*fp[i] - bounds[2*i+0]; } else { bounds[2*i+0] = 2*fp[i] - bounds[2*i+1]; } } mMainRen->ResetCamera(bounds); // // IFrIT-style reset // mMainCam->GetDevice()->SetParallelScale(scale*mMainCam->GetDevice()->GetParallelScale()); mMainCam->GetDevice()->Dolly(1.0/scale); mMainRen->ResetCameraClippingRange(); } void iRenderTool::AddObserver(unsigned long event, iEventObserver *command) { Observer tmp; tmp.Event = event; tmp.Command = command; mObservers.Add(tmp); mMainWin->AddObserver(event,command); if(mDualWin != 0) mDualWin->AddObserver(event,command); } void iRenderTool::UpdateWindowName(const iString &base) { if(mDualWin == 0) { mMainWin->SetWindowName(base.ToCharPointer()); } else { mMainWin->SetWindowName((base+": Left Eye").ToCharPointer()); mDualWin->SetWindowName((base+": Right Eye").ToCharPointer()); } } vtkRenderWindowCollection* iRenderTool::GetRenderWindowCollection() { if(!mWindowCollectionUpToDate) { this->UpdateWindowCollection(); mWindowCollectionUpToDate = true; } return mWindowCollection; } void iRenderTool::UpdateWindowCollection() { mWindowCollection->RemoveAllItems(); mWindowCollection->AddItem(mMainWin); if(mDualWin != 0) mWindowCollection->AddItem(mDualWin); } void iRenderTool::WindowsModified() { mWindowCollectionUpToDate = false; } void iRenderTool::ResetCameraClippingRange() { if(mAutoClippingRange) mMainRen->ResetCameraClippingRange(); } void iRenderTool::SetBackground(const iColor &color) { mMainRen->SetBackground(color.ToVTK()); mDualRen->SetBackground(color.ToVTK()); mMainBkg->SetColor(color); mDualBkg->SetColor(color); } void iRenderTool::SetBackground(const iImage &image) { mMainBkg->SetImage(image); mDualBkg->SetImage(image); } void iRenderTool::AddObject(vtkProp* p) { if(p == 0) return; if(p->IsA("vtkVolume") != 0) { mVolumeObjects->AddItem(p); mMainRen->AddViewProp(p); mDualRen->AddViewProp(p); } else { // // Make sure all actors are ahead of volumes (is it a VTK bug?) // mActorObjects->AddItem(p); mMainRen->RemoveAllViewProps(); mDualRen->RemoveAllViewProps(); vtkProp *p; mActorObjects->InitTraversal(); while((p = mActorObjects->GetNextProp()) != 0) { mMainRen->AddViewProp(p); mDualRen->AddViewProp(p); } mVolumeObjects->InitTraversal(); while((p = mVolumeObjects->GetNextProp()) != 0) { mMainRen->AddViewProp(p); mDualRen->AddViewProp(p); } } } void iRenderTool::RemoveObject(vtkProp* p) { if(p == 0) return; if(p->IsA("vtkVolume") != 0) { mVolumeObjects->RemoveItem(p); } else { mActorObjects->RemoveItem(p); } mMainRen->RemoveViewProp(p); mDualRen->RemoveViewProp(p); } const int* iRenderTool::GetRenderWindowSize() const { return mMainWin->GetSize(); } void iRenderTool::SetRenderWindowSize(int w, int h) { mMainWin->SetSize(w,h); if(mDualWin != 0) mDualWin->SetSize(w,h); } const int* iRenderTool::GetRenderWindowPosition() const { return mMainWin->GetPosition(); } void iRenderTool::SetRenderWindowPosition(int x, int y) { mMainWin->SetPosition(x,y); } void iRenderTool::SetAntialiasing(bool s) { mAntialiasing = s; if(s) { mMainWin->SetLineSmoothing(1); mMainWin->SetPointSmoothing(1); if(mDualWin != 0) { mDualWin->SetLineSmoothing(1); mDualWin->SetPointSmoothing(1); } } else { mMainWin->SetLineSmoothing(0); mMainWin->SetPointSmoothing(0); if(mDualWin != 0) { mDualWin->SetLineSmoothing(0); mDualWin->SetPointSmoothing(0); } } #ifndef I_OFFSCREEN vtkOpenGLRenderWindow *w = vtkOpenGLRenderWindow::SafeDownCast(mMainWin); if(w!=0 && w->GetNeverRendered()==0) { w->MakeCurrent(); w->OpenGLInit(); } if(mDualWin != 0) { w = vtkOpenGLRenderWindow::SafeDownCast(mDualWin); if(w!=0 && w->GetNeverRendered()==0) { w->MakeCurrent(); w->OpenGLInit(); } } #endif } void iRenderTool::SetAdjustCameraClippingRangeAutomatically(bool s) { mAutoClippingRange = s; } void iRenderTool::SetBackgroundImageFixedAspect(bool s) { if(mBackgroundImageFixedAspect != s) { mBackgroundImageFixedAspect = s; mMainBkg->SetImageFixedAspect(s); mDualBkg->SetImageFixedAspect(s); } } void iRenderTool::SetBackgroundImageTile(float tx, float ty, float tw, float th) { float tile[4]; tile[0] = tx; tile[1] = ty; tile[2] = tw; tile[3] = th; this->SetBackgroundImageTile(tile); } void iRenderTool::SetBackgroundImageTile(const float tile[4]) { mMainBkg->SetImageTile(tile); mDualBkg->SetImageTile(tile); } void iRenderTool::SetCameraClippingRange(double cr[2]) { // // This is a dirty trick to avoid the minimum bound on the nearest clipping range of 0.0001 // if(!mAutoClippingRange) { double *d = mMainRen->GetActiveCamera()->GetClippingRange(); mClippingRange[0] = d[0] = cr[0]; mClippingRange[1] = d[1] = cr[1]; } } void iRenderTool::RenderImages(int mag, iStereoImageArray &images) { iStereoImage tmp; images.Clear(); this->RenderStereoImage(mag,tmp); images.Add(tmp); } void iRenderTool::RenderStereoImage(int mag, iStereoImage &image) { int v = 0; mDualWindowObserver->Block(true); if(mStereoAlignmentMarksActor != 0) { v = mStereoAlignmentMarksActor->GetVisibility(); mStereoAlignmentMarksActor->VisibilityOff(); } mMagnifier->SetMagnification(mag); // // Render main window // int lfc = mMainRen->GetLightFollowCamera(); mMainRen->SetLightFollowCamera(0); // Maintain correct lighting under magnification mMagnifier->SetInput(mMainRen); mMagnifier->Modified(); mMagnifier->UpdateWholeExtent(); image.ReplaceData(0,mMagnifier->GetOutput()); mMainRen->SetLightFollowCamera(lfc); // // Render dual window // if(mDualWin != 0) { mMagnifier->SetInput(mDualRen); mMagnifier->Modified(); mMagnifier->UpdateWholeExtent(); mMagnifier->Update(); image.ReplaceData(1,mMagnifier->GetOutput()); } mMagnifier->SetMagnification(1); if(mStereoAlignmentMarksActor != 0) { mStereoAlignmentMarksActor->SetVisibility(v); } mDualWindowObserver->Block(false); } float iRenderTool::GetLastRenderTimeInSeconds() const { float s = mMainRen->GetLastRenderTimeInSeconds(); if(mDualWin != 0) s += mDualRen->GetLastRenderTimeInSeconds(); return s; } void iRenderTool::GetAspectRatio(double ar[2]) const { mMainRen->GetAspect(ar); } // // Stereo operations // void iRenderTool::ShowStereoAlignmentMarks(bool s) { mStereoAlignmentMarksOn = s; mStereoAlignmentMarksActor->SetVisibility((s && mDualWin!=0)?1:0); } void iRenderTool::SetStereoMode(int m) { if(m==mStereoMode || m<0) return; if(mStereoMode == 1) this->ShowDualWindow(false); if(mStereoMode == 2) { // // This seems extraneous, but that trick was needed to avoid flicker // that Doug was complaining about. It was debugged on Robert's laptop. // this->SetMainWinStereoRender(false); mMainWin->Render(); } mStereoMode = m; // // Don't get stuck in a right-eye-only mode, it is not renderable in the non-stereo mode // mMainWin->SetStereoType(0); switch(mStereoMode) { case 0: { this->SetMainWinStereoRender(false); break; } case 1: { this->ShowDualWindow(true); break; } case 2: { if(mMainWin->GetStereoCapableWindow() == 0) { this->SetStereoMode(0); iConsole::Display(iConsole::_Notification,"Crystal Eyes mode is not supported on this machine."); } else { mMainWin->SetStereoType(VTK_STEREO_CRYSTAL_EYES); this->SetMainWinStereoRender(true); } break; } default: { mMainWin->SetStereoType(mStereoMode-mStereoModeOffset); mStereoMode = mMainWin->GetStereoType() + mStereoModeOffset; this->SetMainWinStereoRender(true); break; } } } void iRenderTool::ShowDualWindow(bool s) { if(s) { if(mDualWin == 0) // DualWindow is not shown yet { mDualWin = iShellFactory::CreateRenderWindow(this); IERROR_ASSERT(mDualWin); mDualWin->SetStereoCapableWindow(0); mDualWin->SetStereoTypeToRight(); mDualWin->StereoRenderOn(); int *s = mMainWin->GetSize(); mDualWin->SetSize(s[0],s[1]); this->WindowsModified(); int i; for(i=0; iAddObserver(mObservers[i].Event,mObservers[i].Command); } // // Copy RenderWindows // mDualWin->SetLineSmoothing(mMainWin->GetLineSmoothing()); mDualWin->SetPointSmoothing(mMainWin->GetPointSmoothing()); mDualWin->SetNumberOfLayers(2); mDualWin->AddRenderer(mDualBkg->GetRenderer()); mDualWin->AddRenderer(mDualRen); mMainWin->SetStereoTypeToLeft(); this->SetMainWinStereoRender(true); mMainWin->AddObserver(vtkCommand::StartEvent,mDualWindowObserver); mMainWin->AddObserver(vtkCommand::EndEvent,mDualWindowObserver); mMainWin->AddObserver(vtkCommand::ModifiedEvent,mDualWindowObserver); if(mStereoAlignmentMarksActor!=0 && mStereoAlignmentMarksOn) mStereoAlignmentMarksActor->VisibilityOn(); this->GetViewModule()->UpdateWindowNumber(); } } else { if(mDualWin != 0) { this->WindowsModified(); mDualRen->SetRenderWindow(0); mDualBkg->GetRenderer()->SetRenderWindow(0); mDualWin->RemoveRenderer(mDualRen); mDualWin->RemoveRenderer(mDualBkg->GetRenderer()); mDualWin->Delete(); mDualWin = 0; this->SetMainWinStereoRender(false); mMainWin->RemoveObserver(mDualWindowObserver); if(mStereoAlignmentMarksActor != 0) mStereoAlignmentMarksActor->VisibilityOff(); this->GetViewModule()->UpdateWindowNumber(); } } } iRenderTool* iRenderTool::CreateInstance(vtkRenderer *ren) const { return new iRenderTool(this->GetViewModule(),ren,mMagnifier); } vtkRenderer* iRenderTool::CreateRenderer() const { vtkRenderer *ren = vtkRenderer::New(); if(ren == 0) return 0; ren->SetLayer(IRENDERTOOLBACKGROUND_FRONT_LAYER); // // Copy the state of the primary renderer // ren->SetBackingStore(mMainRen->GetBackingStore()); ren->SetTwoSidedLighting(mMainRen->GetTwoSidedLighting()); ren->SetBackground(mMainRen->GetBackground()); ren->LightFollowCameraOff(); // only the primary renderer can control lights // // Copy props. The trick is that we need to register the new renderer with every iActor // so that iActors can create special mappers for this renderer. Otherwise, vtkPolyDataMappers // remember the last window they rendered into, and will reset at switching to a different window. // vtkPropCollection *pc = mMainRen->GetViewProps(); vtkProp *p; pc->InitTraversal(); while((p = pc->GetNextProp()) != 0) { ren->AddViewProp(p); } // // Copy lights // vtkLight *l; vtkLightCollection *lc = mMainRen->GetLights(); lc->InitTraversal(); while((l = lc->GetNextItem()) != 0) ren->AddLight(l); // // Copy cullers // vtkCuller *c; vtkCullerCollection *cc = mMainRen->GetCullers(); cc->InitTraversal(); ren->GetCullers()->RemoveAllItems(); while((c = cc->GetNextItem()) != 0) ren->AddCuller(c); return ren; } int iRenderTool::GetFullScreenMode() const { return 1; } void iRenderTool::CopyBackground(const iRenderTool *source) { if(source != 0) { mMainBkg->Copy(source->mMainBkg); mDualBkg->Copy(source->mDualBkg); } } void iRenderTool::SetFontScale(int s) { if(s>-10 && s<10) { mFontScale = s; } } void iRenderTool::SetFontType(int s) { if(TextType::IsValid(s)) { mFontType = s; } } void iRenderTool::SetMainWinStereoRender(bool s) { mMainWinStereoRender = s; mMainWin->SetStereoRender(s?1:0); } ifrit-3.4.2/core/irendertool.h0000755000175700010010000001450412167404420014640 0ustar HomeNone/*========================================================================= Program: Ionization FRont Interactive Tool (IFRIT) Language: C++ Copyright (c) 2002-2012 Nick Gnedin All rights reserved. This file may be distributed and/or modified under the terms of the GNU General Public License version 2 as published by the Free Software Foundation and appearing in the file LICENSE.GPL included in the packaging of this file. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHORS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. =========================================================================*/ // // iRenderTool is a combination of a RenderWindow and a Renderer. // In dual-window stereo mode it pops up a separate view for the right eye. // #ifndef IRENDERTOOL_H #define IRENDERTOOL_H #include #include "iarray.h" #include "ipointermacro.h" #include class iActor; class iCamera; class iColor; class iEventObserver; class iImage; class iLightKit; class iMagnifier; class iRenderToolBackground; class iString; class iStereoImage; class iStereoImageArray; class iViewModule; class vtkProp; class vtkPropAssembly; class vtkPropCollection; class vtkRenderer; class vtkRenderWindow; class vtkRenderWindowCollection; class vtkRenderWindowInteractor; namespace iParameter { namespace TextType { const int Arial = 0; const int Courier = 1; const int Times = 2; inline bool IsValid(int m){ return m>=0 && m<=2; } }; }; class iRenderTool : public vtkObjectBase { friend class iCamera; friend class iDualWindowObserver; friend class iExtensionFactory; friend class iRendererObserver; friend class iStereoRenderObserver; IPOINTER_AS_PART(ViewModule); public: vtkTypeMacro(iRenderTool,vtkObjectBase); static iRenderTool* New(iViewModule *vm = 0); virtual int GetNumberOfActiveViews() const; void SetRenderWindowPosition(int x, int y); void SetRenderWindowPosition(const int *p){ this->SetRenderWindowPosition(p[0],p[1]); } const int* GetRenderWindowPosition() const; virtual void SetRenderWindowSize(int w, int h); void SetRenderWindowSize(const int *s){ this->SetRenderWindowSize(s[0],s[1]); } const int* GetRenderWindowSize() const; inline iMagnifier* GetMagnifier() const { return mMagnifier; } inline vtkRenderer* GetRenderer() const { return mMainRen; } inline vtkRenderWindow* GetRenderWindow() const { return mMainWin; } inline vtkRenderWindowInteractor* GetInteractor() const { return mMainInt; } vtkRenderWindowCollection* GetRenderWindowCollection(); inline iCamera* GetCamera() const { return mMainCam; } int GetRenderingMagnification() const; void Render(); virtual void AddObserver(unsigned long event, iEventObserver *observer); virtual void UpdateWindowName(const iString &base); iLightKit* GetLights() const { return mLights; } virtual void SetBackground(const iColor &color); virtual void SetBackground(const iImage &image); virtual float GetLastRenderTimeInSeconds() const; void GetAspectRatio(double ar[2]) const; virtual void AddObject(vtkProp* p); virtual void RemoveObject(vtkProp* p); virtual void SetAntialiasing(bool s); inline bool GetAntialiasing() const { return mAntialiasing; } virtual void SetStereoMode(int m); inline int GetStereoMode() const { return mStereoMode; } void SetBackgroundImageTile(float tx, float ty, float tw, float th); void SetBackgroundImageTile(const float tile[4]); virtual void SetBackgroundImageFixedAspect(bool s); inline bool GetBackgroundImageFixedAspect() const { return mBackgroundImageFixedAspect; } virtual int GetFullScreenMode() const; virtual void CopyBackground(const iRenderTool *source); virtual void ShowStereoAlignmentMarks(bool s); virtual void RenderImages(int mag, iStereoImageArray &images); void RenderStereoImage(int mag, iStereoImage &image); virtual void SetFontType(int t); inline int GetFontType() const { return mFontType; } virtual void SetFontScale(int t); inline int GetFontScale() const { return mFontScale; } protected: iRenderTool(iViewModule *vm, vtkRenderer *ren = 0, iMagnifier *mag = 0); virtual ~iRenderTool(); virtual iRenderTool* CreateInstance(vtkRenderer *ren) const; vtkRenderer* CreateRenderer() const; void ShowDualWindow(bool s); // // Functions used by iCamera class // virtual void ResetCamera(); void ResetCameraClippingRange(); void SetAdjustCameraClippingRangeAutomatically(bool s); inline bool GetAdjustCameraClippingRangeAutomatically() const { return mAutoClippingRange; } void SetCameraClippingRange(double cr[2]); inline void GetCameraClippingRange(double cr[2]) const { cr[0] = mClippingRange[0]; cr[1] = mClippingRange[1]; } virtual void UpdateWindowCollection(); void WindowsModified(); // // Rendering pipeline // vtkRenderWindow *mMainWin, *mDualWin; vtkRenderer *mMainRen, *mDualRen; iRenderToolBackground *mMainBkg, *mDualBkg; vtkRenderWindowInteractor *mMainInt; vtkRenderWindowCollection *mWindowCollection; iCamera *mMainCam; vtkPropAssembly *mStereoAlignmentMarksActor; iEventObserver *mDualWindowObserver, *mRendererObserver, *mStereoRenderObserver; // // Observers registry // struct Observer { unsigned long Event; iEventObserver *Command; Observer(){ Event = 0L; Command = 0; } }; iArray mObservers; private: // // Other members // iLightKit *mLights; iMagnifier *mMagnifier; int mStereoMode, mFontScale, mFontType; double mClippingRange[2]; bool mAntialiasing, mStereoAlignmentMarksOn, mAutoClippingRange, mWindowCollectionUpToDate, mBackgroundImageFixedAspect; const int mStereoModeOffset; bool mMainWinStereoRender; void SetMainWinStereoRender(bool s); // // For ordered rendering // vtkPropCollection *mActorObjects, *mVolumeObjects; }; #endif // IRENDERVIEW_H ifrit-3.4.2/core/irendertoolbackground.cpp0000755000175700010010000001317312167404435017242 0ustar HomeNone/*========================================================================= Program: Ionization FRont Interactive Tool (IFRIT) Language: C++ Copyright (c) 2002-2012 Nick Gnedin All rights reserved. This file may be distributed and/or modified under the terms of the GNU General Public License version 2 as published by the Free Software Foundation and appearing in the file LICENSE.GPL included in the packaging of this file. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHORS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. =========================================================================*/ #include "irendertoolbackground.h" #include "ierror.h" #include "iimage.h" #include "imath.h" #include #include #include #include class iRenderToolBackgroundImageMapper : public vtkImageMapper { public: static iRenderToolBackgroundImageMapper* New() { return new iRenderToolBackgroundImageMapper; } virtual void RenderData(vtkViewport *, vtkImageData *, vtkActor2D *) { } virtual void RenderOverlay(vtkViewport *viewport, vtkActor2D *actor) { int *size = viewport->GetSize(); if(this->GetMTime()>mBuildTime || size[0]!=mOldSize[0] || size[1]!=mOldSize[1]) { mOldSize[0] = size[0]; mOldSize[1] = size[1]; mImageTile = mImageFull;; if(mTile[0]>0.0 || mTile[2]<1.0 || mTile[1]>0.0 || mTile[3]<1.0) { int fw = mImageFull.Width(); int fh = mImageFull.Height(); if(mFixedAspect) { float sx = float(fw)/size[0]; float sy = float(fh)/size[1]; if(sx > sy) { fw = round(sy*size[0]); } else { fh = round(sx*size[1]); } } int x = round(mTile[0]*fw); int w = round(mTile[2]*fw) - x; int y = round(mTile[1]*fh); int h = round(mTile[3]*fh) - y; mImageTile.Crop(x,y,w,h); } mImageTile.Scale(size[0],size[1]); mWorker->SetInput(mImageTile.DataObject()); mBuildTime.Modified(); } mWorker->RenderOverlay(viewport,actor); } void SetImageFixedAspect(bool s) { if(mFixedAspect != s) { mFixedAspect = s; this->Modified(); } } bool GetImageFixedAspect() { return mFixedAspect; } void SetImageTile(const float tile[4]) { if(tile[0]!=mTile[0] || tile[1]!=mTile[1] || tile[2]!=mTile[2] || tile[3]!=mTile[3]) { int j; for(j=0; j<4; j++) { mTile[j] = tile[j]; } this->Modified(); } } void SetImage(const iImage &im) { mImageFull = im; this->Modified(); } protected: iRenderToolBackgroundImageMapper() { mFixedAspect = false; mTile[0] = mTile[1] = 0.0; mTile[2] = mTile[3] = 1.0; mOldSize[0] = mOldSize[1] = 0; mWorker = vtkImageMapper::New(); IERROR_ASSERT(mWorker); mWorker->SetColorWindow(255.0); mWorker->SetColorLevel(127.5); mWorker->RenderToRectangleOff(); mWorker->UseCustomExtentsOff(); } ~iRenderToolBackgroundImageMapper() { mWorker->Delete(); } bool mFixedAspect; float mTile[2], mMinExtent[2], mMaxExtent[2]; int mOldSize[2]; iImage mImageFull, mImageTile; vtkImageMapper *mWorker; vtkTimeStamp mBuildTime; }; // // Main class // iRenderToolBackground* iRenderToolBackground::New() { return new iRenderToolBackground; } iRenderToolBackground::iRenderToolBackground() { mRenderer = vtkRenderer::New(); IERROR_ASSERT(mRenderer); mActor = vtkActor2D::New(); IERROR_ASSERT(mActor); mMapper = iRenderToolBackgroundImageMapper::New(); IERROR_ASSERT(mMapper); mMapper->SetColorWindow(255.0); mMapper->SetColorLevel(127.5); mMapper->RenderToRectangleOn(); mMapper->UseCustomExtentsOff(); mActor->SetMapper(mMapper); mMapper->Delete(); mActor->GetPositionCoordinate()->SetCoordinateSystemToNormalizedViewport(); mActor->SetPosition(0.0,0.0); mActor->GetPosition2Coordinate()->SetCoordinateSystemToNormalizedViewport(); mActor->SetPosition2(1.0,1.0); mActor->VisibilityOff(); mActor->PickableOff(); mActor->GetProperty()->SetDisplayLocationToBackground(); mRenderer->AddActor2D(mActor); mRenderer->SetLayer(IRENDERTOOLBACKGROUND_BACK_LAYER); mRenderer->SetInteractive(0); } iRenderToolBackground::~iRenderToolBackground() { mRenderer->RemoveActor2D(mActor); mRenderer->Delete(); mActor->Delete(); } void iRenderToolBackground::SetColor(const iColor &color) { if(color != mColor) { mColor = color; mRenderer->SetBackground(color.ToVTK()); } } void iRenderToolBackground::SetImage(const iImage &image) { if(image != mImage) { if(image.IsEmpty()) { mImage.Clear(); mActor->VisibilityOff(); } else { mImage = image; mMapper->SetImage(mImage); mActor->VisibilityOn(); } } } void iRenderToolBackground::SetImageFixedAspect(bool s) { mMapper->SetImageFixedAspect(s); } void iRenderToolBackground::SetImageTile(const float tile[4]) { mMapper->SetImageTile(tile); } void iRenderToolBackground::Copy(const iRenderToolBackground *source) { if(source != 0) { this->SetColor(source->mColor); this->SetImage(source->mImage); mMapper->SetImageFixedAspect(source->mMapper->GetImageFixedAspect()); } } ifrit-3.4.2/core/irendertoolbackground.h0000644000175700010010000000457612167404420016705 0ustar HomeNone/*========================================================================= Program: Ionization FRont Interactive Tool (IFRIT) Language: C++ Copyright (c) 2002-2012 Nick Gnedin All rights reserved. This file may be distributed and/or modified under the terms of the GNU General Public License version 2 as published by the Free Software Foundation and appearing in the file LICENSE.GPL included in the packaging of this file. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHORS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. =========================================================================*/ // // A background renderer for iRenderTool // #ifndef IRENDERTOOLBACKGROUND_H #define IRENDERTOOLBACKGROUND_H #include #include "icolor.h" #include "iimage.h" #include class iRenderToolBackgroundImageMapper; class vtkActor2D; class vtkRenderer; #define IRENDERTOOLBACKGROUND_BACK_LAYER 0 #define IRENDERTOOLBACKGROUND_FRONT_LAYER 1 class iRenderToolBackground : public vtkObjectBase { public: vtkTypeMacro(iRenderToolBackground,vtkObjectBase); static iRenderToolBackground* New(); inline vtkRenderer* GetRenderer() const { return mRenderer; } void SetColor(const iColor &color); inline const iColor& GetColor() const { return mColor; } void SetImage(const iImage &image); inline const iImage& GetImage() const { return mImage; } void SetImageFixedAspect(bool s); void SetImageTile(const float tile[4]); void Copy(const iRenderToolBackground *source); protected: virtual ~iRenderToolBackground(); private: iRenderToolBackground(); iColor mColor; iImage mImage; vtkActor2D *mActor; iRenderToolBackgroundImageMapper *mMapper; vtkRenderer *mRenderer; }; #endif // IRENDERTOOLBACKGROUND_H ifrit-3.4.2/core/ireplicatedactor.cpp0000755000175700010010000001235612167404435016174 0ustar HomeNone/*========================================================================= Program: Ionization FRont Interactive Tool (IFRIT) Language: C++ Copyright (c) 2002-2012 Nick Gnedin All rights reserved. This file may be distributed and/or modified under the terms of the GNU General Public License version 2 as published by the Free Software Foundation and appearing in the file LICENSE.GPL included in the packaging of this file. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHORS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. =========================================================================*/ #include "ireplicatedactor.h" #include "iarray.h" #include "ierror.h" #include #include #include // // Templates // #include "iarraytemplate.h" // // We need to take over Device to know which mapper to use on all replicas // class iReplicatedActorDevice: public vtkActor { friend class iReplicatedActor; private: struct Replica { vtkActor *Actor; int Pos[3]; Replica(){ Actor = 0; Pos[0] = Pos[1] = Pos[2] = 0; } }; static iReplicatedActorDevice* New(iReplicatedActor *parent) { return new iReplicatedActorDevice(parent); } virtual void Render(vtkRenderer *ren, vtkMapper *mapper) { int i; for(i=0; iGetMTime() < mParent->GetMTime()) { mReplicas[i].Actor->ShallowCopy(mParent); mReplicas[i].Actor->SetPosition(2.0*mReplicas[i].Pos[0],2.0*mReplicas[i].Pos[1],2.0*mReplicas[i].Pos[2]); mReplicas[i].Actor->Modified(); // Actor is not modifed on ShallowCopy } mReplicas[i].Actor->Render(ren,mapper); } } void CreateReplica(int i, int j, int k) { mReplicas.Add(Replica()); Replica &tmp = mReplicas.Last(); tmp.Pos[0] = i; tmp.Pos[1] = j; tmp.Pos[2] = k; tmp.Actor = vtkActor::New(); IERROR_ASSERT(tmp.Actor); tmp.Actor->SetPosition(2.0*tmp.Pos[0],2.0*tmp.Pos[1],2.0*tmp.Pos[2]); } // // Delete unneeded actors // void DeleteReplicas(int numReplicas[6]) { int k; for(k=0; knumReplicas[1] || mReplicas[k].Pos[1]<-numReplicas[2] || mReplicas[k].Pos[1]>numReplicas[3] || mReplicas[k].Pos[2]<-numReplicas[4] || mReplicas[k].Pos[2]>numReplicas[5]) { mReplicas[k].Actor->Delete(); mReplicas.Remove(k); k--; } } } iReplicatedActorDevice(iReplicatedActor *parent) { mParent = parent; IERROR_ASSERT(mParent); vtkMatrix4x4 *m = vtkMatrix4x4::New(); IERROR_ASSERT(m); this->SetUserMatrix(m); m->Delete(); this->CreateReplica(0,0,0); } virtual ~iReplicatedActorDevice() { while(mReplicas.Size() > 0) mReplicas.RemoveLast().Actor->Delete(); } iArray mReplicas; iReplicatedActor *mParent; }; // // Main class // iReplicatedActor* iReplicatedActor::New(iViewSubject *vs, bool scaled) { IERROR_ASSERT(vs); return new iReplicatedActor(vs,scaled); } iReplicatedActor::iReplicatedActor(iViewSubject *vs, bool scaled) : iActor(scaled), iReplicatedElement(false) { // // Must create property first - it is not created by default // IERROR_ASSERT(this->GetProperty()); // // Substitute the device // this->Device->Delete(); this->Device = mRealDevice = iReplicatedActorDevice::New(this); IERROR_ASSERT(mRealDevice); this->ReplicateAs(vs); } iReplicatedActor::~iReplicatedActor() { } double* iReplicatedActor::GetBounds() { int i; iActor::GetBounds(); if(this->Bounds!=0 && mReplicatedBoundsMTimeBoundsMTime) { mReplicatedBoundsMTime.Modified(); for(i=0; i<3; i++) { this->Bounds[2*i+0] -= 2.0*mNumReplicas[2*i+0]; this->Bounds[2*i+1] += 2.0*mNumReplicas[2*i+1]; } } return this->Bounds; } void iReplicatedActor::Render(vtkRenderer *ren, vtkMapper *m) { iActor::Render(ren,m); // // Update time // this->EstimatedRenderTime *= (mNumReplicas[0]+mNumReplicas[1])*(mNumReplicas[2]+mNumReplicas[3])*(mNumReplicas[4]+mNumReplicas[5]); } void iReplicatedActor::UpdateReplicasBody() { int i, j, k; // // Add needed actors // for(k=-mNumReplicas[4]; k<=mNumReplicas[5]; k++) { for(j=-mNumReplicas[2]; j<=mNumReplicas[3]; j++) { for(i=-mNumReplicas[0]; i<=mNumReplicas[1]; i++) { if(i<-mOldNumReplicas[0] || i>mOldNumReplicas[1] || j<-mOldNumReplicas[2] || j>mOldNumReplicas[3] || k<-mOldNumReplicas[4] || k>mOldNumReplicas[5]) { mRealDevice->CreateReplica(i,j,k); } } } } // // Delete unneeded actors // mRealDevice->DeleteReplicas(mNumReplicas); // // Need to redo bounds // this->BoundsMTime.Modified(); } ifrit-3.4.2/core/ireplicatedactor.h0000755000175700010010000000404612167404420015630 0ustar HomeNone/*========================================================================= Program: Ionization FRont Interactive Tool (IFRIT) Language: C++ Copyright (c) 2002-2012 Nick Gnedin All rights reserved. This file may be distributed and/or modified under the terms of the GNU General Public License version 2 as published by the Free Software Foundation and appearing in the file LICENSE.GPL included in the packaging of this file. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHORS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. =========================================================================*/ // // An actor that can be replicated periodically. This is a preferred way to replicate, since // we create no new data and re-use mappers. // #ifndef IREPLICATEDACTOR_H #define IREPLICATEDACTOR_H #include "iactor.h" #include "ireplicatedelement.h" class iReplicatedActorDevice; class iReplicatedActor : public iActor, public iReplicatedElement { public: vtkTypeMacro(iReplicatedActor,iActor); static iReplicatedActor* New(iViewSubject *vs = 0, bool scaled = false); virtual double* GetBounds(); virtual void Render(vtkRenderer *ren, vtkMapper *m); protected: iReplicatedActor(iViewSubject *vs, bool scaled); virtual ~iReplicatedActor(); virtual void UpdateReplicasBody(); private: iReplicatedActorDevice *mRealDevice; vtkTimeStamp mReplicatedBoundsMTime; }; #endif // IREPLICATEDACTOR_H ifrit-3.4.2/core/ireplicatedelement.cpp0000755000175700010010000000540112167404435016506 0ustar HomeNone/*========================================================================= Program: Ionization FRont Interactive Tool (IFRIT) Language: C++ Copyright (c) 2002-2012 Nick Gnedin All rights reserved. This file may be distributed and/or modified under the terms of the GNU General Public License version 2 as published by the Free Software Foundation and appearing in the file LICENSE.GPL included in the packaging of this file. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHORS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. =========================================================================*/ #include "ireplicatedelement.h" #include "ierror.h" #include "iviewsubject.h" iReplicatedElement::iReplicatedElement(bool isData) : mIsData(isData) { int i; for(i=0; i<6; i++) mNumReplicas[i] = mOldNumReplicas[i] = 0; mParent = 0; } iReplicatedElement::~iReplicatedElement() { if(mParent != 0) { mParent->UnRegisterReplicatedElement(this); } } void iReplicatedElement::ReplicateAs(iViewSubject *parent) { if(mParent != 0) { mParent->UnRegisterReplicatedElement(this); } mParent = parent; if(mParent != 0) { mParent->RegisterReplicatedElement(this,mIsData); } this->UpdateReplicas(); } void iReplicatedElement::UpdateReplicas(bool force) { int i; bool work = force; this->UpdateReplicasHead(); if(mParent != 0) { if(mIsData == mParent->IsOptimizedForQuality()) { for(i=0; i<6; i++) mNumReplicas[i] = mParent->mNumReplicas[i]; } else { for(i=0; i<6; i++) mNumReplicas[i] = 0; } } for(i=0; !work && i<6; i++) { if(mOldNumReplicas[i] != mNumReplicas[i]) work = true; } if(work) { this->UpdateReplicasBody(); for(i=0; i<6; i++) mOldNumReplicas[i] = mNumReplicas[i]; } } void iReplicatedElement::SetNumReplicas(const int n[6]) { int i; for(i=0; i<6; i++) mNumReplicas[i] = n[i]; this->UpdateReplicas(); } void iReplicatedElement::SetNumReplicas(int d, int n) { if(n>=0 && d>=0 && d<6 && n!=mNumReplicas[d]) { mNumReplicas[d] = n; this->UpdateReplicas(); } } void iReplicatedElement::GetNumReplicas(int n[6]) { int i; for(i=0; i<6; i++) n[i] = mNumReplicas[i]; } ifrit-3.4.2/core/ireplicatedelement.h0000755000175700010010000000427012167404420016150 0ustar HomeNone/*========================================================================= Program: Ionization FRont Interactive Tool (IFRIT) Language: C++ Copyright (c) 2002-2012 Nick Gnedin All rights reserved. This file may be distributed and/or modified under the terms of the GNU General Public License version 2 as published by the Free Software Foundation and appearing in the file LICENSE.GPL included in the packaging of this file. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHORS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. =========================================================================*/ // // A class that can be replicated periodically in all 3 directions. // #ifndef IREPLICATEDELEMENT_H #define IREPLICATEDELEMENT_H class iViewSubject; class iReplicatedElement { friend class iViewSubject; public: void SetNumReplicas(const int n[6]); void SetNumReplicas(int d, int n); inline int GetNumReplicas(int d) const { if(d>=0 && d<6) return mNumReplicas[d]; else return 0; } void GetNumReplicas(int n[6]); inline bool IsReplicated() const { return mNumReplicas[0]>0 || mNumReplicas[1]>0 || mNumReplicas[2]>0 || mNumReplicas[3]>0 || mNumReplicas[4]>0 || mNumReplicas[5]>0; } void ReplicateAs(iViewSubject *parent); protected: iReplicatedElement(bool isData); virtual ~iReplicatedElement(); void UpdateReplicas(bool force = false); virtual void UpdateReplicasHead(){} virtual void UpdateReplicasBody() = 0; const bool mIsData; int mNumReplicas[6], mOldNumReplicas[6]; iViewSubject *mParent; }; #endif // IREPLICATEDELEMENT_H ifrit-3.4.2/core/ireplicatedgriddata.cpp0000755000175700010010000001142512167404435016637 0ustar HomeNone/*========================================================================= Program: Ionization FRont Interactive Tool (IFRIT) Language: C++ Copyright (c) 2002-2012 Nick Gnedin All rights reserved. This file may be distributed and/or modified under the terms of the GNU General Public License version 2 as published by the Free Software Foundation and appearing in the file LICENSE.GPL included in the packaging of this file. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHORS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. =========================================================================*/ #include "ireplicatedgriddata.h" #include "idata.h" #include "ierror.h" #include "iparallel.h" #include "iviewmodule.h" #include "iviewsubject.h" #include #include #include #include // // Templates // #include "igenericfiltertemplate.h" iReplicatedGridData::iReplicatedGridData(iViewSubject *vo) : iGenericFilter(vo,1,true,true), iParallelWorker(vo->GetViewModule()->GetParallelManager()), iReplicatedElement(true) { this->ReplicateAs(vo); } void iReplicatedGridData::UpdateReplicasBody() { this->Modified(); } void iReplicatedGridData::InitExecution() { int i, ext[6]; double org[3]; vtkImageData *input = this->GetInput(); vtkImageData *output = this->GetOutput(); input->GetWholeExtent(ext); input->GetOrigin(org); for(i=0; i<3; i++) { ext[2*i+1] = 1 + (ext[2*i+1]-1)*(mNumReplicas[2*i+1]+mNumReplicas[2*i]+1); org[i] -= 2.0*mNumReplicas[2*i]; } output->SetWholeExtent(ext); output->SetSpacing(input->GetSpacing()); output->SetOrigin(org); } void iReplicatedGridData::ProduceOutput() { int extDown[3], extUp[3]; int i; double pos[3]; vtkImageData *input = this->GetInput(); vtkImageData *output = this->GetOutput(); output->Initialize(); int n = input->GetNumberOfScalarComponents(); if(n == 0) return; bool work = false; for(i=0; i<3; i++) { extDown[i] = -mNumReplicas[2*i]; extUp[i] = mNumReplicas[2*i+1]; if(extDown[i] != 0) work = true; if(extUp[i] != 0) work = true; } if(!work) { output->ShallowCopy(input); return; } input->GetSpacing(pos); output->SetSpacing(pos); input->GetDimensions(wDimsIn); input->GetOrigin(pos); int next = 1; for(i=0; i<3; i++) { wExt[i] = extUp[i] - extDown[i] + 1; wDimsOut[i] = 1 + (wDimsIn[i]-1)*wExt[i]; next *= wExt[i]; } wSize = input->GetScalarSize()*input->GetNumberOfScalarComponents(); wSize0 = (wDimsIn[0]-1)*wSize; wSize1 = wSize0 + wSize; output->SetScalarType(input->GetScalarType()); output->SetNumberOfScalarComponents(input->GetNumberOfScalarComponents()); for(i=0; i<3; i++) pos[i] += 2.0*extDown[i]; output->SetOrigin(pos); output->SetDimensions(wDimsOut); vtkUnsignedCharArray *data; data = vtkUnsignedCharArray::New(); IERROR_ASSERT(data); data->SetNumberOfComponents(wSize); data->SetNumberOfTuples((vtkIdType)wDimsOut[0]*wDimsOut[1]*wDimsOut[2]); output->GetPointData()->SetScalars(data); data->Delete(); wPtrIn = (char *)input->GetScalarPointer(); wPtrOut = (char *)data->GetVoidPointer(0); this->ParallelExecute(0); } int iReplicatedGridData::ExecuteStep(int, iParallel::ProcessorInfo &p) { int j, k, i1, j1, k1; int kBeg, kEnd, kStp; vtkIdType loff, loff1, loff2; iParallel::SplitRange(p,wDimsIn[2],kBeg,kEnd,kStp); for(k1=0; k1IsMaster(p)) { this->UpdateProgress((float)(k-kBeg+wDimsIn[2]*k1)/((kEnd-kBeg)*wExt[2])); } if(this->GetAbortExecute()) break; for(j1=0; j1IsReplicated()) return this->iGenericFilter::GetMemorySize(); else return 0.0; } ifrit-3.4.2/core/ireplicatedgriddata.h0000755000175700010010000000426712167404420016304 0ustar HomeNone/*========================================================================= Program: Ionization FRont Interactive Tool (IFRIT) Language: C++ Copyright (c) 2002-2012 Nick Gnedin All rights reserved. This file may be distributed and/or modified under the terms of the GNU General Public License version 2 as published by the Free Software Foundation and appearing in the file LICENSE.GPL included in the packaging of this file. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHORS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. =========================================================================*/ // // Takes StructuredPoints data of any type and replicates them periodically. // #ifndef IREPLICATEDGRIDDATA_H #define IREPLICATEDGRIDDATA_H #include "igenericfilter.h" #include #include "iparallelworker.h" #include "ireplicatedelement.h" class iReplicatedGridData : public iGenericFilter, protected iParallelWorker, public iReplicatedElement { IGENERICFILTER_DECLARE(iReplicatedGridData,vtkStructuredPointsToStructuredPointsFilter); public: virtual float GetMemorySize(); protected: virtual void InitExecution(); virtual void ProduceOutput(); virtual void UpdateReplicasBody(); virtual int ExecuteStep(int step, iParallel::ProcessorInfo &p); private: // // Work variables // int wDimsIn[3], wDimsOut[3], wExt[3]; vtkIdType wSize, wSize0, wSize1; char *wPtrIn, *wPtrOut; }; #endif // IREPLICATEDGRIDDATA_H ifrit-3.4.2/core/ireplicatedpolydata.cpp0000755000175700010010000003334012167404435016675 0ustar HomeNone/*========================================================================= Program: Ionization FRont Interactive Tool (IFRIT) Language: C++ Copyright (c) 2002-2012 Nick Gnedin All rights reserved. This file may be distributed and/or modified under the terms of the GNU General Public License version 2 as published by the Free Software Foundation and appearing in the file LICENSE.GPL included in the packaging of this file. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHORS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. =========================================================================*/ #include "ireplicatedpolydata.h" #include "ierror.h" #include "imath.h" #include "iviewmodule.h" #include #include #include #include #include #include // // Templates // #include "igenericfiltertemplate.h" namespace iReplicatedPolyData_Private { // // QuickFind // #define ARR(i) lptr1[i] bool Find(vtkIdType n, vtkIdType *lptr1, vtkIdType l, vtkIdType &ind) { vtkIdType i1 = 0; vtkIdType i2 = n - 1; vtkIdType ic; if(l < ARR(i1)) { ind = -1; return false; } if(l > ARR(i2)) { ind = -1; return false; } while(i2-i1 > 1) { ic = (i1+i2)/2; if(l >= ARR(ic)) i1 = ic; if(l <= ARR(ic)) i2 = ic; } if(l == ARR(i1)) { ind = i1; return true; } else if(l == ARR(i2)) { ind = i2; return true; } else { ind = -1; return false; } } // // QuickSort // #define SAVE(CELL,i1) { ltmp1 = lptr1[i1]; ltmp2 = lptr2[i1]; } #define MOVE(i1,i2) { lptr1[i1] = lptr1[i2]; lptr2[i1] = lptr2[i2]; } #define RESTORE(i2,CELL) { lptr1[i2] = ltmp1; lptr2[i2] = ltmp2; } #define SWAP(i1,i2) { SAVE(1,i1); MOVE(i1,i2); RESTORE(i2,1); } // // Recursive worker // void SortWorker(vtkIdType l, vtkIdType r, vtkIdType *lptr1, vtkIdType *lptr2) { const int M = 8; vtkIdType i, j, v, ltmp1, ltmp2; if ((r-l)>M) { // // Use quicksort // i = (r+l)/2; if (ARR(l)>ARR(i)) SWAP(l,i); // Tri-Median Method! if (ARR(l)>ARR(r)) SWAP(l,r); if (ARR(i)>ARR(r)) SWAP(i,r); j = r-1; SWAP(i,j); i = l; v = ARR(j); for(;;) { do i++; while(ARR(i) < v); // no ++i/--j in macro expansion! do j--; while(ARR(j) > v); if (jl && ARR(j-1)>v) { MOVE(j,j-1); j--; } RESTORE(j,1); } } } // // Do our own quick sort for efficiency reason (based on a Java code by Denis Ahrens) // void Sort(vtkIdType n, vtkIdType *lptr1, vtkIdType *lptr2) { SortWorker(0,n-1,lptr1,lptr2); } }; using namespace iReplicatedPolyData_Private; iReplicatedPolyData::iReplicatedPolyData(iViewSubject *vo) : iGenericPolyDataToPolyDataFilter(vo,1,true,true), iReplicatedElement(true) { this->ReplicateAs(vo); } void iReplicatedPolyData::UpdateReplicasBody() { this->Modified(); } void iReplicatedPolyData::ProduceOutput() { int extDown[3], extUp[3]; int i; vtkPolyData *input = this->GetInput(); vtkPolyData *output = this->GetOutput(); output->ShallowCopy(input); bool work = false; for(i=0; i<3; i++) { extDown[i] = -mNumReplicas[2*i]; extUp[i] = mNumReplicas[2*i+1]; if(extDown[i] != 0) work = true; if(extUp[i] != 0) work = true; } if(!work) return; vtkPolyData *tmp = vtkPolyData::New(); if(tmp == 0) return; for(i=0; i<3; i++) if(extUp[i]>0 || extDown[i]<0) { tmp->ShallowCopy(output); this->ExtendDirection(tmp,output,i,extDown[i],extUp[i]); } tmp->Delete(); } void iReplicatedPolyData::ExtendDirection(vtkPolyData *input, vtkPolyData *output, int dim, int extDown, int extUp) { int i, j; if(input==0 || output==0 || dim<0 || dim>2 || extDown>0 || extUp<0) return; output->ShallowCopy(input); int next = extUp - extDown + 1; if(next < 2) return; vtkPoints *ipoi = input->GetPoints(); if(ipoi == 0) return; vtkCellArray *iver = input->GetVerts(); vtkCellArray *ilin = input->GetLines(); vtkCellArray *ipol = input->GetPolys(); vtkCellArray *isrp = input->GetStrips(); vtkDataArray *isca = input->GetPointData()->GetScalars(); vtkDataArray *inor = input->GetPointData()->GetNormals(); float *iptrpoiF = 0; double *iptrpoiD = 0; float *iptrsca = (isca == 0) ? 0 : (float *)isca->GetVoidPointer(0); float *iptrnor = (inor == 0) ? 0 : (float *)inor->GetVoidPointer(0); vtkIdType npoi = ipoi->GetNumberOfPoints(); if(npoi == 0) return; vtkIdType nver = (iver == 0) ? 0 : iver->GetNumberOfCells(); vtkIdType nlin = (ilin == 0) ? 0 : ilin->GetNumberOfCells(); vtkIdType npol = (ipol == 0) ? 0 : ipol->GetNumberOfCells(); vtkIdType nsrp = (isrp == 0) ? 0 : isrp->GetNumberOfCells(); vtkIdType nsca = (isca == 0) ? 0 : isca->GetNumberOfComponents()*isca->GetNumberOfTuples(); vtkIdType nnor = (inor == 0) ? 0 : inor->GetNumberOfComponents()*inor->GetNumberOfTuples(); vtkPoints *opoi; opoi = vtkPoints::New(ipoi->GetDataType()); IERROR_ASSERT(opoi); opoi->SetNumberOfPoints(next*npoi); float *optrpoiF = 0; double *optrpoiD = 0; float *optrsca = 0, *optrnor = 0; vtkCellArray *over = 0, *olin = 0, *opol = 0, *osrp = 0; vtkFloatArray *osca = 0, *onor = 0; bool pointsAreFloat; switch(ipoi->GetDataType()) { case VTK_FLOAT: { pointsAreFloat = true; iptrpoiF = (float *)ipoi->GetVoidPointer(0); optrpoiF = (float *)opoi->GetVoidPointer(0); break; } case VTK_DOUBLE: { pointsAreFloat = false; iptrpoiD = (double *)ipoi->GetVoidPointer(0); optrpoiD = (double *)opoi->GetVoidPointer(0); break; } default: { vtkErrorMacro("Incorrect Points type"); return; } } if(nver > 0) { over = vtkCellArray::New(); IERROR_ASSERT(over); } if(nlin > 0) { olin = vtkCellArray::New(); IERROR_ASSERT(olin); } if(npol > 0) { opol = vtkCellArray::New(); IERROR_ASSERT(opol); } if(nsrp > 0) { osrp = vtkCellArray::New(); IERROR_ASSERT(osrp); } if(nsca > 0) { osca = vtkFloatArray::New(); IERROR_ASSERT(osca); osca->SetNumberOfComponents(isca->GetNumberOfComponents()); osca->SetNumberOfTuples(next*isca->GetNumberOfTuples()); optrsca = (float *)osca->GetVoidPointer(0); } if(nnor > 0) { onor = vtkFloatArray::New(); IERROR_ASSERT(onor); onor->SetNumberOfComponents(3); onor->SetNumberOfTuples(next*inor->GetNumberOfTuples()); optrnor = (float *)onor->GetVoidPointer(0); } vtkIdType npts, *pts, *pts1; int maxCellSize = 0, curmax; if(nver > 0) { curmax = iver->GetMaxCellSize(); if(curmax > maxCellSize) maxCellSize = curmax; } if(nlin > 0) { curmax = ilin->GetMaxCellSize(); if(curmax > maxCellSize) maxCellSize = curmax; } if(npol > 0) { curmax = ipol->GetMaxCellSize(); if(curmax > maxCellSize) maxCellSize = curmax; } if(nsrp > 0) { curmax = isrp->GetMaxCellSize(); if(curmax > maxCellSize) maxCellSize = curmax; } pts = new vtkIdType[maxCellSize]; IERROR_ASSERT(pts); double s[3]; s[0] = s[1] = s[2] = 0.0; s[dim] = 2.0; int off = 0; vtkIdType l, loff1, loff2, noff; for(j=extDown; j<=extUp; j++) { this->UpdateProgress((float)(j-extDown)/next); if(this->GetAbortExecute()) break; noff = off*npoi; if(pointsAreFloat) { for(l=0; l 0) for(iver->InitTraversal(); iver->GetNextCell(npts,pts1)!=0; ) { pts[0] = pts1[0] + noff; over->InsertNextCell(1,pts); } if(nlin > 0) for(ilin->InitTraversal(); ilin->GetNextCell(npts,pts1)!=0; ) { for(i=0; iInsertNextCell(npts,pts); } if(npol > 0) for(ipol->InitTraversal(); ipol->GetNextCell(npts,pts1)!=0; ) { for(i=0; iInsertNextCell(npts,pts); } if(nsrp > 0) for(isrp->InitTraversal(); isrp->GetNextCell(npts,pts1)!=0; ) { for(i=0; iInsertNextCell(npts,pts); } if(nsca > 0) memcpy(optrsca+off*nsca,iptrsca,nsca*sizeof(float)); if(nnor > 0) memcpy(optrnor+off*nnor,iptrnor,nnor*sizeof(float)); off++; } delete [] pts; output->SetPoints(opoi); opoi->Delete(); if(nver > 0) { output->SetVerts(over); over->Delete(); } if(nlin > 0) { output->SetLines(olin); olin->Delete(); } if(npol > 0) { output->SetPolys(opol); opol->Delete(); } if(nsrp > 0) { output->SetStrips(osrp); osrp->Delete(); } if(nsca > 0) { output->GetPointData()->SetScalars(osca); osca->Delete(); } if(nnor > 0) { output->GetPointData()->SetNormals(onor); onor->Delete(); } // // Patch stitches // double *edges = new double[next-1]; if(edges == 0) return; for(j=0; jIsReplicated()) return this->iGenericPolyDataToPolyDataFilter::GetMemorySize(); else return 0.0; } void iReplicatedPolyData::PatchStitches(vtkPolyData *input, int ndim, double *edges, vtkIdType nEdges) { int i, j, k; if(input==0 || nEdges<=0 || ndim<0 || ndim>2) { return; } vtkCellArray *cell[4]; cell[0] = input->GetVerts(); cell[1] = input->GetLines(); cell[2] = input->GetPolys(); cell[3] = input->GetStrips(); vtkPoints *points = input->GetPoints(); if(points == 0) return; float *ptrF = 0; double *ptrD = 0; bool pointsAreFloat = false; double tolerance; switch (points->GetDataType()) { case VTK_FLOAT: { pointsAreFloat = true; ptrF = (float *)points->GetVoidPointer(0); tolerance = iMath::_FloatTolerance; break; } case VTK_DOUBLE: { pointsAreFloat = false; ptrD = (double *)points->GetVoidPointer(0); tolerance = iMath::_DoubleTolerance; break; } default: tolerance = 0.0; } vtkIdList *edgeIds = vtkIdList::New(); IERROR_ASSERT(edgeIds); vtkIdList *outIds = vtkIdList::New(); IERROR_ASSERT(outIds); vtkIdList *repIds = vtkIdList::New(); IERROR_ASSERT(repIds); vtkIdList *indIds = vtkIdList::New(); IERROR_ASSERT(indIds); vtkPointLocator *loc = vtkPointLocator::New(); IERROR_ASSERT(loc); vtkPoints *tmpPoints = vtkPoints::New(points->GetDataType()); IERROR_ASSERT(tmpPoints); int div[3]; for(i=0; i<3; i++) { div[i] = 100; } div[ndim] = 1; loc->SetTolerance(tolerance); vtkIdType np = points->GetNumberOfPoints(); vtkIdType l, lid, ncell, *pcell; double xe, x[3], bounds[6]; vtkIdType *outptr, *repptr, nout; float *nor, *norptr = 0; if(input->GetPointData()->GetNormals() != 0) norptr = (float *)input->GetPointData()->GetNormals()->GetVoidPointer(0); points->GetBounds(bounds); for(k=0; kInitialize(); xe = edges[k]; if(pointsAreFloat) { for(l=0; lInsertNextId(l); } } } else { for(l=0; lInsertNextId(l); } } } loc->Initialize(); outIds->Initialize(); repIds->Initialize(); indIds->Initialize(); tmpPoints->Initialize(); loc->SetDivisions(div); bounds[2*ndim] = xe - 2*tolerance; bounds[2*ndim+1] = xe + 2*tolerance; loc->InitPointInsertion(tmpPoints,bounds); for(l=0; lGetNumberOfIds(); l++) { points->GetPoint(edgeIds->GetId(l),x); if(loc->InsertUniquePoint(x,lid) == 0) { outIds->InsertNextId(edgeIds->GetId(l)); repIds->InsertNextId(edgeIds->GetId(indIds->GetId(lid))); } else indIds->InsertNextId(l); } // // We need to sort outIds and repIds arrays to make searching efficient // nout = outIds->GetNumberOfIds(); bool *norFixed = new bool[nout]; if(norFixed!=0 && nout>0) { outptr = outIds->GetPointer(0); repptr = repIds->GetPointer(0); Sort(nout,outptr,repptr); memset(norFixed,0,nout); // // Replace outIds with repIds and fix normals on the way. make sure not to // do it more than once. // for(i=0; i<4; i++) if(cell[i] != 0) { cell[i]->InitTraversal(); while(cell[i]->GetNextCell(ncell,pcell) > 0) { for(l=0; lDelete(); edgeIds->Delete(); tmpPoints->Delete(); outIds->Delete(); repIds->Delete(); indIds->Delete(); } ifrit-3.4.2/core/ireplicatedpolydata.h0000755000175700010010000000412012167404420016326 0ustar HomeNone/*========================================================================= Program: Ionization FRont Interactive Tool (IFRIT) Language: C++ Copyright (c) 2002-2012 Nick Gnedin All rights reserved. This file may be distributed and/or modified under the terms of the GNU General Public License version 2 as published by the Free Software Foundation and appearing in the file LICENSE.GPL included in the packaging of this file. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHORS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. =========================================================================*/ // // Takes PolyData data of any type and replicates them periodically. // #ifndef IREPLICATEDPOLYDATA_H #define IREPLICATEDPOLYDATA_H #include "igenericfilter.h" #include #include "ireplicatedelement.h" class iReplicatedPolyData : public iGenericPolyDataToPolyDataFilter, public iReplicatedElement { IGENERICFILTER_DECLARE(iReplicatedPolyData,vtkPolyDataToPolyDataFilter); public: virtual float GetMemorySize(); // // Removes stitches between extensions in place // static void PatchStitches(vtkPolyData *input, int ndim, double *edges, vtkIdType nEdges); protected: virtual void ProduceOutput(); virtual void UpdateReplicasBody(); private: void ExtendDirection(vtkPolyData *input, vtkPolyData *output, int dim, int extDown, int extUp); }; #endif // IREPLICATEDPOLYDATA_H ifrit-3.4.2/core/ireplicatedvolume.cpp0000755000175700010010000001054212167404435016366 0ustar HomeNone/*========================================================================= Program: Ionization FRont Interactive Tool (IFRIT) Language: C++ Copyright (c) 2002-2012 Nick Gnedin All rights reserved. This file may be distributed and/or modified under the terms of the GNU General Public License version 2 as published by the Free Software Foundation and appearing in the file LICENSE.GPL included in the packaging of this file. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHORS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. =========================================================================*/ #include "ireplicatedvolume.h" #include "ibuffer.h" #include "ierror.h" #include #include #include #include #include // // Templates // #include "iarraytemplate.h" #include "ibuffertemplate.h" #include "igenericproptemplate.h" // // Main class // iReplicatedVolume* iReplicatedVolume::New(iViewSubject *vs) { IERROR_ASSERT(vs); return new iReplicatedVolume(vs); } iReplicatedVolume::iReplicatedVolume(iViewSubject *vs) : iGenericProp(false), iReplicatedElement(false) { // // Must create property first - it is not created by default // IERROR_ASSERT(this->GetProperty()); // // Create main replica // this->CreateReplica(0,0,0); this->ReplicateAs(vs); mCuller = vtkFrustumCoverageCuller::New(); IERROR_ASSERT(mCuller); mCuller->SetSortingStyleToBackToFront(); } iReplicatedVolume::~iReplicatedVolume() { mCuller->Delete(); while(mReplicas.Size() > 0) mReplicas.RemoveLast().Volume->Delete(); } void iReplicatedVolume::CreateReplica(int i, int j, int k) { mReplicas.Add(Replica()); Replica &tmp = mReplicas.Last(); tmp.Pos[0] = i; tmp.Pos[1] = j; tmp.Pos[2] = k; tmp.Volume = vtkVolume::New(); tmp.Volume->ShallowCopy(this); tmp.Volume->SetPosition(2.0*tmp.Pos[0],2.0*tmp.Pos[1],2.0*tmp.Pos[2]); } double* iReplicatedVolume::GetBounds() { int i; vtkVolume::GetBounds(); if(this->Bounds != 0) { for(i=0; i<3; i++) { this->Bounds[2*i+0] -= 2.0*mNumReplicas[2*i+0]; this->Bounds[2*i+1] += 2.0*mNumReplicas[2*i+1]; } } return this->Bounds; } void iReplicatedVolume::UpdateGeometry(vtkViewport *vp) { int initialized = 0; int i, n = mReplicas.Size(); vtkProp** buf = new vtkProp*[n]; IERROR_ASSERT(buf); for(i=0; iGetMTime() < this->GetMTime()) { mReplicas[i].Volume->ShallowCopy(this); mReplicas[i].Volume->SetPosition(2.0*mReplicas[i].Pos[0],2.0*mReplicas[i].Pos[1],2.0*mReplicas[i].Pos[2]); } buf[i] = mReplicas[i].Volume; } // // Reorder volumes // mCuller->Cull(iRequiredCast(INFO,vp),buf,n,initialized); // // n can change inside Cull() // this->RemoveAllComponents(); for(i=0; iAppendComponent(buf[i]); delete [] buf; } void iReplicatedVolume::UpdateReplicasBody() { int i, j, k; Replica tmp; // // Add needed actors // for(k=-mNumReplicas[4]; k<=mNumReplicas[5]; k++) { for(j=-mNumReplicas[2]; j<=mNumReplicas[3]; j++) { for(i=-mNumReplicas[0]; i<=mNumReplicas[1]; i++) { if(i<-mOldNumReplicas[0] || i>mOldNumReplicas[1] || j<-mOldNumReplicas[2] || j>mOldNumReplicas[3] || k<-mOldNumReplicas[4] || k>mOldNumReplicas[5]) { this->CreateReplica(i,j,k); } } } } // // Delete unneeded actors // for(k=0; kmNumReplicas[1] || mReplicas[k].Pos[1]<-mNumReplicas[2] || mReplicas[k].Pos[1]>mNumReplicas[3] || mReplicas[k].Pos[2]<-mNumReplicas[4] || mReplicas[k].Pos[2]>mNumReplicas[5]) { mReplicas[k].Volume->Delete(); mReplicas.Remove(k); } } } ifrit-3.4.2/core/ireplicatedvolume.h0000755000175700010010000000457312167404420016034 0ustar HomeNone/*========================================================================= Program: Ionization FRont Interactive Tool (IFRIT) Language: C++ Copyright (c) 2002-2012 Nick Gnedin All rights reserved. This file may be distributed and/or modified under the terms of the GNU General Public License version 2 as published by the Free Software Foundation and appearing in the file LICENSE.GPL included in the packaging of this file. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHORS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. =========================================================================*/ // // A volume that can be replicated periodically. This is a preferred way to replicate, since // we create no new data and re-use mappers. // #ifndef IREPLICATEDVOLUME_H #define IREPLICATEDVOLUME_H #include "igenericprop.h" #include #include "ireplicatedelement.h" #include "iarray.h" #include "ipointermacro.h" //class iViewModule; class vtkFrustumCoverageCuller; class iReplicatedVolume : public iGenericProp, public iReplicatedElement { // IPOINTER_AS_PART(ViewModule); public: vtkTypeMacro(iReplicatedVolume,vtkVolume); static iReplicatedVolume* New(iViewSubject *vs = 0); virtual double* GetBounds(); inline vtkTransform* GetTransform() const { return this->Transform; } protected: iReplicatedVolume(iViewSubject *vs); virtual ~iReplicatedVolume(); virtual void UpdateGeometry(vtkViewport *vp); virtual void UpdateReplicasBody(); private: void CreateReplica(int i, int j, int k); struct Replica { vtkVolume *Volume; int Pos[3]; Replica(){ Volume = 0; Pos[0] = Pos[1] = Pos[2] = 0; } }; iArray mReplicas; vtkFrustumCoverageCuller *mCuller; }; #endif // IREPLICATEDVOLUME_H ifrit-3.4.2/core/iresampleimagedatafilter.cpp0000755000175700010010000000325212167404435017675 0ustar HomeNone/*========================================================================= Program: Ionization FRont Interactive Tool (IFRIT) Language: C++ Copyright (c) 2002-2012 Nick Gnedin All rights reserved. This file may be distributed and/or modified under the terms of the GNU General Public License version 2 as published by the Free Software Foundation and appearing in the file LICENSE.GPL included in the packaging of this file. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHORS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. =========================================================================*/ #include "iresampleimagedatafilter.h" // // Templates // #include "igenericfiltertemplate.h" iResampleImageDataFilter::iResampleImageDataFilter(iViewSubject *vo) : iGenericFilter(vo,1,true,false) { } void iResampleImageDataFilter::ProduceOutput() { this->ExecuteParent(); // // Somehow origin is not passed? // this->GetOutput()->SetOrigin(this->GetImageDataInput(0)->GetOrigin()); } ifrit-3.4.2/core/iresampleimagedatafilter.h0000644000175700010010000000316112167404420017330 0ustar HomeNone/*========================================================================= Program: Ionization FRont Interactive Tool (IFRIT) Language: C++ Copyright (c) 2002-2012 Nick Gnedin All rights reserved. This file may be distributed and/or modified under the terms of the GNU General Public License version 2 as published by the Free Software Foundation and appearing in the file LICENSE.GPL included in the packaging of this file. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHORS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. =========================================================================*/ #ifndef IRESAMPLEIMAGEDATAFILTER_H #define IRESAMPLEIMAGEDATAFILTER_H #include "igenericfilter.h" #include class iResampleImageDataFilter : public iGenericFilter { IGENERICFILTER_DECLARE(iResampleImageDataFilter,vtkExtractVOI); protected: virtual void ProduceOutput(); }; #endif // IRESAMPLEIMAGEDATAFILTER_H ifrit-3.4.2/core/iruler.cpp0000755000175700010010000000770212167404435014157 0ustar HomeNone/*========================================================================= Program: Ionization FRont Interactive Tool (IFRIT) Language: C++ Copyright (c) 2002-2012 Nick Gnedin All rights reserved. This file may be distributed and/or modified under the terms of the GNU General Public License version 2 as published by the Free Software Foundation and appearing in the file LICENSE.GPL included in the packaging of this file. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHORS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. =========================================================================*/ #include "iruler.h" #include "icamera.h" #include "ierror.h" #include "ioverlayhelper.h" #include "irendertool.h" #include "iviewmodule.h" #include #include #include // // Templates // #include "iarraytemplate.h" #include "igenericproptemplate.h" iRuler* iRuler::New(iViewModule *vm) { IERROR_ASSERT(vm); return new iRuler(vm); } iRuler::iRuler(iViewModule *vm) : iAxis(vm->GetRenderTool()), mViewModule(vm) { mStarted = false; mScale = mBaseScale = 1.0; this->LabelTextProperty->SetVerticalJustificationToTop(); this->TitleTextProperty->SetJustificationToCentered(); this->TitleTextProperty->SetVerticalJustificationToBottom(); this->SetPoint1(0.25,0.9); this->SetPoint2(0.75,0.9); this->SetRange(0.0,1.0); this->AdjustLabelsOff(); this->SetNumberOfLabels(3); } iRuler::~iRuler() { } void iRuler::UpdateGeometry(vtkViewport *vp) { vtkCamera *cam = this->GetOverlayHelper()->GetCamera(vp); if(cam==0 || cam->GetParallelProjection()==0) { this->Disable(); return; } int mag = this->GetOverlayHelper()->GetRenderingMagnification(); if(mag == 1) { if(!mStarted) { mStarted = true; mBaseScale = cam->GetParallelScale(); } float s; if(cam->GetParallelProjection() != 0) { s = cam->GetParallelScale()/mBaseScale; } else { s = cam->GetDistance()*(1.0e-35+tan(0.5*iMath::Deg2Rad(cam->GetViewAngle())))/mBaseScale; } double as[2]; vp->GetAspect(as); float dx = 0.5/mBaseScale*as[1]/as[0]; if(!this->GetViewModule()->GetOpenGLCoordinates()) s *= this->GetViewModule()->GetBoxSize(); this->SetRange(0.0,s); mScale = s; this->SetPoint1(0.5-dx,0.9); this->SetPoint2(0.5+dx,0.9); } this->iAxis::UpdateGeometry(vp); } void iRuler::UpdateOverlay(vtkViewport *vp) { int mag = this->GetOverlayHelper()->GetRenderingMagnification(); if(mag == 1) { int *sz = vp->GetSize(); this->TitleActor->SetPosition(0.5*sz[0],0.91*sz[1]); } this->iAxis::UpdateOverlay(vp); } void iRuler::SetBaseScale(float s) { if(s > 0.0) { mStarted = true; mBaseScale = s; this->Modified(); } } void iRuler::SetScale(float s) { if(!mStarted) { mStarted = true; mBaseScale = this->GetOverlayHelper()->GetRenderTool()->GetCamera()->GetDevice()->GetParallelScale(); } if(s > 0.0) { if(!this->GetViewModule()->GetOpenGLCoordinates()) s /= this->GetViewModule()->GetBoxSize(); this->GetOverlayHelper()->GetRenderTool()->GetCamera()->GetDevice()->SetParallelScale(s*mBaseScale); this->Modified(); } } void iRuler::SetTitle(const iString &title) { mTitle = title; this->vtkAxisActor2D::SetTitle(title.ToCharPointer()); if(mTitle.IsEmpty()) this->TitleVisibilityOff(); else this->TitleVisibilityOn(); this->Modified(); } ifrit-3.4.2/core/iruler.h0000755000175700010010000000365612167404420013622 0ustar HomeNone/*========================================================================= Program: Ionization FRont Interactive Tool (IFRIT) Language: C++ Copyright (c) 2002-2012 Nick Gnedin All rights reserved. This file may be distributed and/or modified under the terms of the GNU General Public License version 2 as published by the Free Software Foundation and appearing in the file LICENSE.GPL included in the packaging of this file. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHORS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. =========================================================================*/ #ifndef IRULER_H #define IRULER_H #include "iaxis.h" #include "istring.h" class iViewModule; class iRuler: public iAxis { IPOINTER_AS_PART(ViewModule); public: vtkTypeMacro(iRuler,iAxis); static iRuler* New(iViewModule *vm = 0); void SetBaseScale(float s); void SetScale(float s); inline float GetScale() const { return mScale; } void SetTitle(const iString &title); inline const iString& GetTitle() const { return mTitle; } protected: virtual ~iRuler(); virtual void UpdateGeometry(vtkViewport *vp); virtual void UpdateOverlay(vtkViewport *vp); private: iRuler(iViewModule *vm); bool mStarted; float mScale, mBaseScale; iString mTitle; }; #endif // IRULER_H ifrit-3.4.2/core/iscript.cpp0000755000175700010010000004113012167404435014323 0ustar HomeNone/*========================================================================= Program: Ionization FRont Interactive Tool (IFRIT) Language: C++ Copyright (c) 2002-2012 Nick Gnedin All rights reserved. This file may be distributed and/or modified under the terms of the GNU General Public License version 2 as published by the Free Software Foundation and appearing in the file LICENSE.GPL included in the packaging of this file. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHORS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. =========================================================================*/ #include "iscript.h" #include "icalculator.h" #include "ierror.h" #include "ierrorstatus.h" #include "imath.h" #include "iscriptkit.h" // // Templates // #include "iarraytemplate.h" //#include "icalculatortemplate.h" iScript::iScript(iScript *parent) : mErrorStatus("Script") { mParent = parent; mCalculator = 0; mAllowChildAccess = true; // children can only access my vars if this is true mNumStatementPrototypes = mNumAssignmentPrototypes = 0; mBlock = mIsCompiled = false; mErrorLine = mErrorPosition = -1; //mText = ""; mThisEntry = mNextEntry = -1; // // Special characters - can be overwritten in a child class // mCommentString = "#"; // // Continuation symbols - can be overwritten in a child class // (may be useful for creatting REALLY complex multi-line syntax!) // mHeadOfLineContinuationString = ""; mTailOfLineContinuationString = "\\"; // standard C-type continuation line mAppendSeparator = ""; // this separates strings when they are appended - useful for complex syntax } iScript::~iScript() { int i; this->Reset(); this->RemoveVariables(); for(i=0; i 0) mObservers.RemoveLast()->SetScript(0); if(mCalculator != 0) delete mCalculator; } // // Observers // void iScript::AddObserver(iScriptObserver *obs) { if(obs != 0) mObservers.AddUnique(obs); } void iScript::RemoveObserver(iScriptObserver *obs) { if(obs != 0) mObservers.Remove(obs); } // // Script Creation // void iScript::CreateAliasWord(const iString &alias, const iString &word) { AliasWord tmp; tmp.Alias = alias; tmp.Word = word; mAliasWords.Add(tmp); } void iScript::CreateDummyWord(const iString &v) { if(!v.IsEmpty()) mDummyWords.Add(v); } void iScript::AddConstant(iScriptKit::Value *value) { IERROR_ASSERT(value); int i; for(i=0; iName() == mConstants[i]->Name()) return; mConstants.Add(value); } iScriptKit::Calculator* iScript::CreateCalculator() { int i; iScriptKit::Calculator* calc = this->CreateCalculatorBody(); IERROR_ASSERT(calc); for(i=0; iAddVariable(mConstants[i]->CalculatorValue()); //for(i=0; iAddVariable(mVariables[i]->CalculatorValue()); return calc; } iScriptKit::Calculator* iScript::CreateCalculatorBody() { return new iScriptKit::Calculator(this); } // // Public interface // void iScript::SetText(const iString &s) { static const char d = 'a' - 'A'; if(s != mText) { mText = s; this->GetErrorStatus()->Clear(); if(!mText.IsEmpty()) { if(mText[mText.Length()-1] != '\n') mText += "\n"; if(!mCaseSensitive) { // // Turn the script into lower case, but not the quoted strings or comments // const char *cs = mCommentString.ToCharPointer(); char *ptr = mText.GetWritePointer(mText.Length()); bool doit = true; int i, n = mText.Length(), l = mCommentString.Length(); for(i=0; i='A' && ptr[i]<='Z') ptr[i] += d; } } } // // Do partial reset // this->Reset(); } } bool iScript::IsDummyWord(const iString &s) const { return (mDummyWords.Find(s) != -1); } bool iScript::IsCommandWord(const iString &s) const { int i; for(i=0; iCommand() == s) return true; return false; } bool iScript::IsVariableName(const iString &s) const { int i; for(i=0; iName() == s) return true; return false; } bool iScript::IsConstantName(const iString &s) const { int i; for(i=0; iName() == s) return true; return false; } bool iScript::IsReservedWord(const iString &s) const { return this->IsDummyWord(s) || this->IsCommandWord(s) || this->IsConstantName(s); } const iString &iScript::GetReservedWord(int i) const { static const iString none; if(i < 0) return none; if(i < mDummyWords.Size()) return mDummyWords[i]; i -= mDummyWords.Size(); if(i < mNumStatementPrototypes) return mPrototypes[i]->Command(); i -= mNumStatementPrototypes; if(i < mConstants.Size()) return mConstants[i]->Name(); return none; } // // Get the line of code // iString iScript::GetText(int i)const { static const iString none; if(i >= 0) return mText.Section("\n",i,i); else return none; } // // Remove the pseudocode // void iScript::Reset() { // // Delete the code and the stack // while(mCode.Size() > 0) delete mCode.RemoveLast(); while(mStack.Size() > 0) mStack.RemoveLast(); while(mPrototypes.Size() > mNumAssignmentPrototypes) // remove unkept variables { this->RemoveVariable(mPrototypes.Last()->Command()); delete mPrototypes.RemoveLast(); } mLoopCur = -1; mLoopNum = 0; mThisEntry = mNextEntry = -1; mBlock = mIsCompiled = false; } // // Remove the declared variables // void iScript::RemoveVariables() { // // Delete all variables and their associated commands // while(mPrototypes.Size() > mNumStatementPrototypes) { this->RemoveVariable(mPrototypes.Last()->Command()); delete mPrototypes.RemoveLast(); } // // Remove the rest of variables // while(mVariables.Size() > 0) { if(mCalculator != 0) mCalculator->RemoveVariable(mVariables.Last()->Name()); delete mVariables.RemoveLast(); } mIsCompiled = false; } void iScript::ReportError(const iString &message, int pos, int line) { this->GetErrorStatus()->Set(message); mErrorPosition = pos; if(line == -1) line = this->GetThisLine(); mErrorLine = line; } void iScript::Execute(bool keepVariables) { if(this->StartExecute()) { while(this->ExecuteOneLine() && this->GetErrorStatus()->NoError()); this->StopExecute(keepVariables); } } bool iScript::StartExecute() { if(!this->Compile()) return false; int i; for(i=0; iOnScriptStart(); mNextEntry = 0; return true; } void iScript::StopExecute(bool keepVariables) { int i; for(i=0; iOnScriptStop(this->GetErrorStatus()->Message()); mCalculator->Reset(); if(keepVariables) { if(this->GetErrorStatus()->NoError()) mNumAssignmentPrototypes = mPrototypes.Size(); } else this->RemoveVariables(); mThisEntry = mNextEntry = -1; } // // Interrupts // bool iScript::CheckAbort() const { if(mThisEntry>=0 && mThisEntryCheckAbort(mLoopCur,mLoopNum,0); } else { return this->CheckAbort(-1,0,0); } } bool iScript::CheckAbort(int cur, int num, int l) const { int i, level = mStack.Size() + l; bool abort = false; for(i=0; !abort && iOnScriptCheckAbort(cur,num,level); return abort; } // // Execute one line of script. Returns true if the script is not finished, and false // if it is done. // bool iScript::ExecuteOneLine() { // // Reset error status // this->GetErrorStatus()->Clear(); mErrorPosition = -1; if(mBlock) { this->GetErrorStatus()->Set("Attempting to call script recursively."); return false; // do not multi-thread me!!! } if(mNextEntry < 0) { this->GetErrorStatus()->Set("Script has not been started."); return false; } mBlock = true; mThisEntry = mNextEntry; if(mThisEntry == mCode.Size()) // Script is done { mBlock = false; return false; } int i, line; iString text; if(mObservers.Size() > 0) { line = this->GetThisLine(); text = this->GetText(line); for(i=0; iOnScriptBeginLine(line,text); } mNextEntry++; // set it here, so that a flow control statement can change it inside Execute if(mCode[mThisEntry]->Execute()) { if(this->CheckAbort()) { this->GetErrorStatus()->SetAbort(-1); mBlock = false; return false; } for(i=0; iOnScriptEndLine(line,text); mBlock = false; return true; } else { mBlock = false; return false; } } // // Compile the script. // bool iScript::Compile() { int i, j, k, n = this->GetNumberOfLines(); iString line, text, s; if(mIsCompiled) return true; // we can be compiled many times before the actual execution if(mCalculator == 0) { mCalculator = this->CreateCalculator(); } this->Reset(); int headLen = mHeadOfLineContinuationString.Length(); int tailLen = mTailOfLineContinuationString.Length(); for(k=0; kGetText(k); // // If the following lines are just continuations of this one, append them including mAppendSeparator // while(k+1 < n) { s = this->GetText(k+1); // // The head string preceedes the tail one // i = 0; while(i0 && s.Part(i,headLen)==mHeadOfLineContinuationString) { line += " " + mAppendSeparator + s.Part(headLen); k++; continue; } i = s.Length() - 1; while(i>=0 && s.IsWhiteSpace(i)) i--; if(tailLen>0 && line.Part(i+1-tailLen,tailLen)==mTailOfLineContinuationString) { line = line.Part(0,line.Length()-tailLen) + mAppendSeparator + s; k++; continue; } break; } // // Remove comments if they are present (but not inside a string) // i = line.Find(mCommentString); if(i>=0 && line.Part(0,i).Contains('"')%2==0) line = line.Part(0,i); // // Replace alias words - but not when they are parts of other words. // for(i=0; iFindCommandWord(line,mAliasWords[i].Alias))>-1) line.Replace(j,mAliasWords[i].Alias.Length(),mAliasWords[i].Word); } // // No command on this line // s = line; s.ReduceWhiteSpace(); if(s.IsEmpty() || (s.Length()==1 && s[0]==' ')) { continue; } // // Remove dummy words - but not when they are parts of other words. // for(i=0; iFindCommandWord(line,mDummyWords[i]))>-1) line.Replace(j,mDummyWords[i].Length()," "); } // // Search the list of command words. // Be carefult to find the exact complete match beginning at the start of the line // s = line; s.ReduceWhiteSpace(); for(i=0; iFindCommandWord(s,mPrototypes[i]->Command()) == 0) { break; } } if(i == mPrototypes.Size()) // The word is not a valid command { this->ReportError("Syntax error - invalid command or undefined variable.",0,k); return false; } j = -1; line.FindIgnoringWhiteSpace(mPrototypes[i]->Command(),0,&j); if(!mPrototypes[i]->Compile(line.Part(j),k,j)) { return false; } } // // Check that all closing flow control statements are present // if(mStack.Size() > 0) { this->ReportError("Missing loop or branch closing statement(s).",-1,k); return false; } mIsCompiled = true; return true; } int iScript::FindCommandWord(const iString &context, const iString &word, int index) const { int i = index; int l = word.Length(); while((i=context.Find(word,i))>-1) { // // Is this a full word? // if(i>0 && this->IsCommandWordLetter(context[i-1])) { i+=l; continue; } if(i+lIsCommandWordLetter(context[i+l])) { i+=l; continue; } // // Is it behind a quote - meaning, it is a string? // if(context.Part(0,i).Contains('"')%2 == 1) { i+=l; continue; } break; } return i; } bool iScript::IsCommandWordLetter(char c) const { // // Script words may contain letters, numbers, and '_'. // return ((c>='0'&&c<='9') || (c>='A'&&c<='Z') || (c>='a'&&c<='z') || c=='_'); } bool iScript::IsCommandWordFirstLetter(char c) const { // // Script words must start with a letter or '_'. // return ((c>='A'&&c<='Z') || (c>='a'&&c<='z') || c=='_'); } bool iScript::IsValidVariableName(const iString &name) const { return (mCalculator!=0 && mCalculator->IsValidVariableName(name)); } void iScript::AddVariable(iScriptKit::Value *value) { if(value != 0) { #ifdef I_DEBUG int i; for(i=0; iName() == mVariables[i]->Name()) { int ooo = 0; } #endif //if(mCalculator != 0) mCalculator->AddVariable(value->CalculatorValue()); mVariables.Add(value); } } void iScript::RemoveVariable(const iString &name) { if(!name.IsEmpty()) { int i; for(i=mVariables.MaxIndex(); i>=0; i--) // variables are always looped over in the reverse order to insure proper name resolution { if(mVariables[i]->Name() == name) { if(mCalculator != 0) mCalculator->RemoveVariable(mVariables[i]->Name()); delete mVariables[i]; mVariables.Remove(i); return; // remove one at a time } } } } iScriptKit::Value* iScript::FindVariable(const iString &name) const { int i; for(i=mVariables.MaxIndex(); i>=0; i--) if(mVariables[i]->Name() == name) return mVariables[i]; // // This ensures correct name resolution. // if(mParent!=0 && mParent->mAllowChildAccess) return mParent->FindVariable(name); else return 0; } // // Only return released variables // void iScript::QueryVariables(iArray &list) const { int i; list.Clear(); for(i=0; iIsReleased()) { list.Add(mVariables[i]); } } // // Other misc functions // void iScript::JumpToEntry(int entry) { if(entry>=0 && entry=0 && mThisEntryLineInScript(); else return -1; } int iScript::GetNextLine() const { if(mNextEntry>=0 && mNextEntryLineInScript(); else return -1; } int iScript::GetNumberOfLines() const { return mText.Contains('\n'); } void iScript::SetLoopParameters(int cur, int num) { mLoopCur = cur; mLoopNum = num; } bool iScript::SatisfyRequestForVariables(const iString &) { return true; // by default, there are no special, non-algebraic variables } void iScript::RegisterPrototype(iScriptKit::Prototype *prototype) { IERROR_ASSERT(prototype); if(mCalculator == 0) { int i; for(i=0; imPrototypes.Size(); i++) if(prototype->Command() == this->mPrototypes[i]->Command()) return; this->mPrototypes.Add(prototype); this->mNumStatementPrototypes++; mNumAssignmentPrototypes = mNumStatementPrototypes; } else { IERROR_FATAL("Script creation must be completed before the first compilation."); } } // // Observer functions // iScriptObserver::iScriptObserver(iScript *s) { mScript = s; if(mScript != 0) mScript->AddObserver(this); } iScriptObserver::~iScriptObserver() { if(mScript != 0) mScript->RemoveObserver(this); } bool iScriptObserver::OnScriptCheckAbort(int cur, int num, int level) { if(mScript != 0) return this->OnScriptCheckAbortBody(cur,num,level); else return false; } void iScriptObserver::OnScriptStart() { if(mScript != 0) this->OnScriptStartBody(); } void iScriptObserver::OnScriptStop(const iString &error) { if(mScript != 0) this->OnScriptStopBody(error); } void iScriptObserver::OnScriptBeginLine(int line, const iString &text) { if(mScript != 0) this->OnScriptBeginLineBody(line,text); } void iScriptObserver::OnScriptEndLine(int line, const iString &text) { if(mScript != 0) this->OnScriptEndLineBody(line,text); } void iScriptObserver::SetScript(iScript *s) { if(mScript != s) { if(mScript != 0) mScript->RemoveObserver(this); mScript = s; if(mScript != 0) mScript->AddObserver(this); } } ifrit-3.4.2/core/iscript.h0000755000175700010010000001575512167404420014000 0ustar HomeNone/*========================================================================= Program: Ionization FRont Interactive Tool (IFRIT) Language: C++ Copyright (c) 2002-2012 Nick Gnedin All rights reserved. This file may be distributed and/or modified under the terms of the GNU General Public License version 2 as published by the Free Software Foundation and appearing in the file LICENSE.GPL included in the packaging of this file. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHORS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. =========================================================================*/ // // Abstract script // #ifndef ISCRIPT_H #define ISCRIPT_H #include #define ISCRIPT_BACKWARD_COMPATIBLE // remove in the future #include "iarray.h" #include "ipointermacro.h" #include "istring.h" #include class iErrorStatus; class iScriptObserver; namespace iScriptKit { class Calculator; class Value; class Prototype; class Statement; class GenericFlowControlStatement; class LoopFlowControlStatement; class VariableDeclarationStatement; }; class iScript : public vtkObjectBase { friend class iScriptKit::Calculator; friend class iScriptKit::Value; friend class iScriptKit::Prototype; friend class iScriptKit::Statement; friend class iScriptKit::GenericFlowControlStatement; friend class iScriptKit::LoopFlowControlStatement; friend class iScriptKit::VariableDeclarationStatement; friend class iScriptObserver; IPOINTER_AS_USER(ErrorStatus); public: // // Aliasing // struct AliasWord { iString Word; iString Alias; }; vtkTypeMacro(iScript,vtkObjectBase); void SetText(const iString &s); inline const iString& GetText() const { return mText; } // // Using the script // bool Compile(); void Execute(bool keepVariables = false); // // Line-by-line driver components // bool StartExecute(); bool ExecuteOneLine(); void StopExecute(bool keepVariables = false); int GetThisLine() const; int GetNextLine() const; int GetNumberOfLines() const; bool IsDummyWord(const iString &s) const; bool IsCommandWord(const iString &s) const; bool IsVariableName(const iString &s) const; bool IsConstantName(const iString &s) const; bool IsReservedWord(const iString &s) const; inline int GetNumberOfReservedWords() const { return mNumStatementPrototypes+mConstants.Size()+mDummyWords.Size(); } virtual const iString& GetReservedWord(int i) const; void QueryVariables(iArray &list) const; inline int GetErrorLine() const { return mErrorLine; } inline int GetErrorPosition() const { return mErrorPosition; } // // Internal interrupt // bool CheckAbort(int cur, int num, int level) const; bool CheckAbort() const; // // Calculators // iScriptKit::Calculator* GetCalculator() const { return mCalculator; } inline bool IsEmbedded() const { return mParent != 0; } protected: iScript(iScript *parent); virtual ~iScript(); // // Script execution // void Reset(); void RemoveVariables(); bool CompileOneLine(int line); // // Other helpers // iString GetText(int) const; int FindCommandWord(const iString &context, const iString &word, int index = 0) const; virtual bool IsCommandWordLetter(char c) const; virtual bool IsCommandWordFirstLetter(char c) const; bool IsValidVariableName(const iString &name) const; // // Script creation // void CreateAliasWord(const iString &alias, const iString &word); void CreateDummyWord(const iString &word); void AddConstant(iScriptKit::Value *value); iScriptKit::Calculator* CreateCalculator(); // // Prototypes // template void AddPrototype(const iString &command); template void AddPrototype(const iString &command, A arg); template void AddPrototype(const iString &command, A1 arg1, A2 arg2); // // Factory method: a calculator can be replaced by a child. It is non-const so that a child's // calculator can add new variables and constants. // virtual iScriptKit::Calculator* CreateCalculatorBody(); // // Overwrite this to create special non-algebraic variables // virtual bool SatisfyRequestForVariables(const iString &vars); // // Variable manipulation // iScriptKit::Value* FindVariable(const iString &name) const; void AddVariable(iScriptKit::Value *value); void RemoveVariable(const iString &name); // // Changeable members // bool mCaseSensitive; bool mAllowChildAccess; iString mCommentString, mHeadOfLineContinuationString, mTailOfLineContinuationString, mAppendSeparator; iScript *mParent; // cannot be const private: // // Convenient error reporting for components // void ReportError(const iString &message, int pos, int line); // // Special access for FlowControl statements // void JumpToEntry(int entry); void SetLoopParameters(int cur, int num); // // Prototypes // void RegisterPrototype(iScriptKit::Prototype *prototype); // // Observers // void AddObserver(iScriptObserver *obs); void RemoveObserver(iScriptObserver *obs); bool mBlock, mIsCompiled; int mErrorLine, mErrorPosition; iArray mAliasWords; iSearchableArray mDummyWords; iArray mVariables; iArray mConstants; int mNumStatementPrototypes, mNumAssignmentPrototypes; iArray mCode; iArray mPrototypes; iArray mStack; iString mText; int mThisEntry, mNextEntry; int mLoopCur, mLoopNum; // for debuggers iScriptKit::Calculator *mCalculator; // for rare calculations iSearchableArray mObservers; }; // // Inheritable observer class // class iScriptObserver { public: void SetScript(iScript *parent); void OnScriptStart(); void OnScriptStop(const iString &error); void OnScriptBeginLine(int line, const iString &text); void OnScriptEndLine(int line, const iString &text); bool OnScriptCheckAbort(int cur, int num, int level); protected: iScriptObserver(iScript *s); virtual ~iScriptObserver(); virtual void OnScriptStartBody() = 0; virtual void OnScriptStopBody(const iString &error) = 0; virtual void OnScriptBeginLineBody(int line, const iString &text) = 0; virtual void OnScriptEndLineBody(int line, const iString &text) = 0; virtual bool OnScriptCheckAbortBody(int cur, int num, int level) = 0; private: iScript *mScript; }; #endif // ISCRIPT_H ifrit-3.4.2/core/iscriptkit.cpp0000755000175700010010000006210112167404436015035 0ustar HomeNone/*========================================================================= Program: Ionization FRont Interactive Tool (IFRIT) Language: C++ Copyright (c) 2002-2012 Nick Gnedin All rights reserved. This file may be distributed and/or modified under the terms of the GNU General Public License version 2 as published by the Free Software Foundation and appearing in the file LICENSE.GPL included in the packaging of this file. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHORS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. =========================================================================*/ #include "iscriptkit.h" #include "ierror.h" #include "iscript.h" // // Templates // #include "iarraytemplate.h" #include "icalculatortemplate.h" #include "iscriptkittemplate.h" namespace iScriptKit { #ifdef I_DEBUG int Value::mIdCounter = 0; #endif // // Calculator // Calculator::Calculator(iScript *script) : iCalculator(), mScript(script) { IERROR_ASSERT(mScript); this->SetTrapFPE(true); } bool Calculator::Verify(const iString &expr, int dim, int use, const iString &err) { const char *s[2] = { "numeric (0)", "boolean (1)" }; if(!this->Compile(expr) || !mScript->SatisfyRequestForVariables(this->ListUsedVariables()) || !this->Link()) return false; if(use > 1) use = 0; // just in case... if(use>-1 && this->GetResult()->Use()!=use) { this->SetError("The usage pattern of the "+err+" expression must be "+s[use]+" instead of "+s[this->GetResult()->Use()]+".",-1); return false; } if(dim>-1 && this->GetResult()->Dim()!=dim) { this->SetError("The dimension of the "+err+" expression must be "+iString::FromNumber(dim)+" instead of "+iString::FromNumber(this->GetResult()->Dim())+".",-1); return false; } return true; } void Calculator::AddVariable(const result_t *var) { this->iCalculator::AddVariable(var); } const iCalculatorKit::Variable* Calculator::FindExternalVariable(const iString &name) const { Value *var = mScript->FindVariable(name); if(var != 0) return var->CalculatorValue(); else return 0; } // // Base class for values (variables and parameters) // Value::Value(iScript *script, const iString &name, int dim, int use) : mScript(script) { IERROR_ASSERT(mScript); mIsReleased = false; if(dim < 1) { // // For non-positive dimension we create a morphable scalar // dim = 1; mValue = new iCalculatorKit::var_(dim,use,name); IERROR_ASSERT(mValue); } else { mValue = new iCalculatorKit::var_(dim,use,name); IERROR_ASSERT(mValue); } if(mScript->GetCalculator() != 0) mScript->GetCalculator()->AddVariable(mValue); #ifdef I_DEBUG mId = ++mIdCounter; iConsole::PrintDebugMessage("iScriptKit::Value: creating #"+iString::FromNumber(mId)+" ("+name+")"); #endif } Value::~Value() { #ifdef I_DEBUG mIdCounter--; iConsole::PrintDebugMessage("iScriptKit::Value: deleting #"+iString::FromNumber(mId)+" ("+this->Name()+"), "+iString::FromNumber(mIdCounter)+" left."); #endif if(mScript->GetCalculator() != 0) mScript->GetCalculator()->RemoveVariable(mValue->Name()); delete mValue; } bool Value::Morph(int dim) { return mValue->Morph(dim,mValue->Use()); } const iString& Value::Name() const { return mValue->Name(); } int Value::Dim() const { return mValue->Dim(); } int Value::Use() const { return mValue->Use(); } void Value::ReportError(const iString &str) { mScript->ReportError(str,-1,-1); } // // Base class for prototypes. // Prototype::Prototype(iScript *script, const iString &command) : mCommand(command), mScript(script) { IERROR_ASSERT(mScript); mCommand.ReduceWhiteSpace(); } Prototype::~Prototype() { } bool Prototype::Compile(const iString &arg, int line, int pos) { // // Create worker // Statement *worker = this->CreateWorker(); if(worker == 0) { mScript->ReportError("There is not enough free memory to proceed.",-1,line); return false; } // // Look for the index // int last = -1; int index = worker->ParseOperandForIndex(arg,0,last); if(index == -2) return false; if(index>-1 && !worker->mAcceptsArrays) { mScript->ReportError("This statement does not accept an index qualifier for the body of the command.",pos,line); return false; } // // Configure the worker // worker->mIndex = index; worker->mEntryInCode = mScript->mCode.Size(); worker->mArgument = arg; worker->mOperand = arg.Part(last+1); worker->mLineInScript = line; worker->ShiftOperandWhiteSpace(); if(index == 0) { // // Index is an expression and needs to be recomputed at run-time, so save it. // worker->mIndexExpression = arg.Part(1,last-1); } mScript->mCode.Add(worker); if(mScript->mStack.Size() > 0) worker->mOwnsCalculator = true; return worker->CompileBody(); } // // Base class for statements. // Statement::Statement(iScript *script, const iString &command) : mCommand(command), mScript(script) { IERROR_ASSERT(mScript); mAcceptsArrays = mOwnsCalculator = false; mIndex = mEntryInCode = mLineInScript = -1; } Statement::~Statement() { } bool Statement::Execute() { // // Call actual execute // #ifdef I_DEBUG iConsole::Display(iConsole::_Info,("Executing: {"+mCommand+" "+mArgument+"}...").ToCharPointer()); #endif return this->ExecuteBody(); } void Statement::ShiftOperandWhiteSpace() { int i = 0; while(mOperand.IsWhiteSpace(i)) i++; mOperand = mOperand.Part(i); } int Statement::ParseOperandForIndex(const iString &str, int pos, int &last) const { if(pos<0 || pos>str.Length()-3) return -1; int iBeg, iEnd; str.FindTokenMatch(mScript->GetCalculator()->SymbolOpeningBraket(),iBeg,mScript->GetCalculator()->SymbolClosingBraket(),iEnd,pos,true); if(iBeg != pos) return -1; if(iEnd ==-1) { this->ReportError("Missing closing bracket."); return -2; } if(iEnd < iBeg+2) { this->ReportError("Empty index expression."); return -2; } bool ok; int res = str.Part(iBeg+1,iEnd-iBeg-1).ToInt(ok); if(ok) { // // Index is an integer number, but is it positive? // if(res > 0) { last = iEnd; return res; } else { this->ReportError("Index must be a positive integer number.",str.Part(iBeg+1,iEnd-iBeg-1)); return -1; } } else { // // Index is not a number - may be an expression, and so should be left for the run-time evaluation. // We indicate it by assigning it a zero value. // last = iEnd; return 0; } } Value* Statement::FindVariable(const iString &name) const { return mScript->FindVariable(name); } Calculator* Statement::CreateCalculator() const { return mScript->CreateCalculator(); } void Statement::ReportError(const iString &message, const iString &context) const { int i = mArgument.FindIgnoringWhiteSpace(context); mScript->ReportError(message,mCommand.Length()+(i>0?i:0),-1); } void Statement::ReportError(const Calculator *c) const { if(c!=0 && !c->GetErrorMessage().IsEmpty()) { int i = mArgument.FindIgnoringWhiteSpace(mOperand); mScript->ReportError(c->GetErrorMessage(),mCommand.Length()+(i>-1?i+c->GetErrorPosition():0),mLineInScript); } } // // A simple, argument-less function call statement // SimpleStatement::SimpleStatement(iScript *script, const iString &command, FunctionType f) : Statement(script,command), mFun(f) { } bool SimpleStatement::CompileBody() { if(mFun != 0) { mOperand.ReduceWhiteSpace(); if(!mOperand.IsEmpty()) { this->ReportError("iScriptKit::SimpleStatement cannot have an argument."); return false; } } else { this->ReportError("iScriptKit::SimpleStatement is configured incorrectly."); return false; } return true; } bool SimpleStatement::ExecuteBody() { return this->mFun(mScript); } // // A deprecated statement // DeprecatedStatement::DeprecatedStatement(iScript *script, const iString &command, const iString &message) : Statement(script,command), mMessage(message) { } bool DeprecatedStatement::CompileBody() { if(mMessage.IsEmpty()) { this->ReportError("This statement is deprecated."); } else { this->ReportError("This statement is deprecated. "+mMessage); } return false; } bool DeprecatedStatement::ExecuteBody() { return true; } // // A programmable function call statement (can be specialized to implement any command) // FunctionCallStatement::FunctionCallStatement(iScript *script, const iString &command, FunctionType1 f) : Statement(script,command), mFun1(f), mFun2(0) { mAcceptsArrays = false; mIndexCalculator = 0; } FunctionCallStatement::FunctionCallStatement(iScript *script, const iString &command, FunctionType2 f) : Statement(script,command), mFun1(0), mFun2(f) { mAcceptsArrays = true; mIndexCalculator = 0; } bool FunctionCallStatement::CompileBody() { if(mFun1==0 && mFun2==0) { this->ReportError("iScriptKit::FunctionCallStatement is configured incorrectly."); return false; } if(mOwnsCalculator && mIndex==0) mIndexCalculator = this->CreateCalculator(); if(mIndex == 0) { if(!this->GetIndexCalculator()->Verify(mIndexExpression,1,0,"index")) { this->ReportError(this->GetIndexCalculator()); return false; } } return true; } bool FunctionCallStatement::ExecuteBody() { int index = mIndex; if(index == 0) { // // Need to recalculate // if(!this->GetIndexCalculator()->Evaluate(mIndexExpression)) { this->ReportError(this->GetIndexCalculator()); return false; } index = Constant::ConvertToNative(this->GetIndexCalculator()->GetResultData()[0]); if(index < 1) { this->ReportError("Index must be a positive integer number.",0); return false; } } // // Scalar/full vector assignment // if(index == -1) { if(mFun1 != 0) { return this->mFun1(mScript,mOperand); } else { this->ReportError("Internal error: null pointer for the called function (should be caught at compile-time)."); return false; } } else { if(index > 0) index--; // convert to a C-style index if(mFun2 != 0) { return this->mFun2(mScript,mOperand,index); } else { this->ReportError("Internal error: null pointer for the called function (should be caught at compile-time)."); return false; } } } Calculator* FunctionCallStatement::GetIndexCalculator() const { if(mIndexCalculator != 0) return mIndexCalculator; else return mScript->GetCalculator(); } // // Generic assignment statement // AssignmentStatement::AssignmentStatement(iScript *script, const iString &command, short mask, int dim, int use) : Statement(script,command), mAssignmentMask(mask), mDim(dim), mUse(use) { mCalculator = 0; mIndexCalculator = 0; } AssignmentStatement::~AssignmentStatement() { if(mCalculator != 0) delete mCalculator; if(mIndexCalculator != 0) delete mIndexCalculator; } bool AssignmentStatement::CompileBody() { if(!this->ParseOperandForAssignmentType()) return false; if(mOwnsCalculator) { mCalculator = this->CreateCalculator(); // if new fails, the pointer will be zero, which is ok if(mIndex == 0) mIndexCalculator = this->CreateCalculator(); } if(mIndex == 0) { if(!this->GetCalculator()->Verify(mOperand,1,mUse,"right-hand-side")) { this->ReportError(this->GetCalculator()); return false; } if(!this->GetIndexCalculator()->Verify(mIndexExpression,1,0,"index")) { this->ReportError(this->GetIndexCalculator()); return false; } } else { if(!this->GetCalculator()->Verify(mOperand,(mIndex>0?1:mDim),mUse,"right-hand-side")) { this->ReportError(this->GetCalculator()); return false; } } return true; } bool AssignmentStatement::ExecuteBody() { int index = mIndex; if(index == 0) { // // Need to recalculate // if(!this->GetIndexCalculator()->Evaluate(mIndexExpression)) { this->ReportError(this->GetIndexCalculator()); return false; } index = Constant::ConvertToNative(this->GetIndexCalculator()->GetResultData()[0]); if(index < 1) { this->ReportError("Index must be a positive integer number.",0); return false; } } // // Special case: variable to variable assignment (including vector variables) // if(index == -1) { iString w = this->mOperand; w.ReduceWhiteSpace(); const Value *v = this->FindVariable(w); if(v!=0 && (mDim<0 || v->Dim()==mDim) && (mUse<0 || v->Use()==mUse)) { return this->SetValue(v->CalculatorValue(),-1); } } // // Execute our calculator // if(!this->GetCalculator()->Evaluate(this->mOperand)) { this->ReportError(this->GetCalculator()); return false; } if(index > 0) index--; // convert to a C-style index return this->SetValue(this->GetCalculator()->GetResult(),index); } Calculator* AssignmentStatement::GetCalculator() const { if(mCalculator != 0) return mCalculator; else return mScript->GetCalculator(); } Calculator* AssignmentStatement::GetIndexCalculator() const { if(mIndexCalculator != 0) return mIndexCalculator; else return mScript->GetCalculator(); } bool AssignmentStatement::ParseOperandForAssignmentType() { // // Find the assignment type // mAssignmentType = _Direct; iString s(mOperand.Part(0,2)); if(s == "+=") { if((mAssignmentMask & _IncAdd) == 0) { this->ReportError("Incremental assigment += is not supported for this command."); return false; } else { mAssignmentType = _IncAdd; mOperand = mOperand.Part(2); } } else if(s == "-=") { if((mAssignmentMask & _IncSub) == 0) { this->ReportError("Incremental assigment -= is not supported for this command."); return false; } else { mAssignmentType = _IncSub; mOperand = mOperand.Part(2); } } else if(s == "*=") { if((mAssignmentMask & _IncMul) == 0) { this->ReportError("Incremental assigment *= is not supported for this command."); return false; } else { mAssignmentType = _IncMul; mOperand = mOperand.Part(2); } } else if(s == "/=") { if((mAssignmentMask & _IncDiv) == 0) { this->ReportError("Incremental assigment /= is not supported for this command."); return false; } else { mAssignmentType = _IncDiv; mOperand = mOperand.Part(2); } } if(mAssignmentType==_Direct && mOperand[0]=='=') { mOperand = mOperand.Part(1); } this->ShiftOperandWhiteSpace(); return true; } // // Generic flow control statement // GenericFlowControlStatement::GenericFlowControlStatement(iScript *script, const iString &command, FlowControlType type) : Statement(script,command), mType(type) { mState = _Empty; // this a flow control statement mJumpPoint = 0; } bool GenericFlowControlStatement::CompileBody() { if(this->IsOfType(_Exit)) { // // Is there an opening statement? // if(mScript->mStack.Size() == 0) { this->ReportError("This closing flow control statement does not close a valid opening statement."); return false; } mScript->mStack.Last()->mJumpPoint = this; mJumpPoint = mScript->mStack.Last(); mScript->mStack.RemoveLast(); } if(this->IsOfType(_Entry)) { mScript->mStack.Add(this); } return this->ChildCompileBody(); } bool GenericFlowControlStatement::ExecuteBody() { if(mJumpPoint == 0) { this->ReportError("Internal error: missing jump point for a flow control statement."); return false; } if(this->ChildExecuteBody()) { if(this->IsOfType(_Exit)) mScript->mStack.RemoveLast(); if(this->IsOfType(_Entry)) mScript->mStack.Add(this); return true; } else return false; } void GenericFlowControlStatement::Jump() { if(mJumpPoint == 0) { this->ReportError("Internal error: missing jump point for a flow control statement."); } else { mScript->JumpToEntry(mJumpPoint->EntryInCode()); } } // // Closing flow control statement (like enddo or endif) // ClosingFlowControlStatement::ClosingFlowControlStatement(iScript *script, const iString &command) : GenericFlowControlStatement(script,command,_Exit) { } bool ClosingFlowControlStatement::ChildCompileBody() { // // Nothing to do here // return true; } bool ClosingFlowControlStatement::ChildExecuteBody() { if(mJumpPoint->TestState(_Returning)) { this->Jump(); } return true; } // // Swapping flow control statement (like else) // SwappingFlowControlStatement::SwappingFlowControlStatement(iScript *script, const iString &command) : GenericFlowControlStatement(script,command,FlowControlType(_Entry|_Exit)) { mAllowInLoops = false; mArrivalPoint = 0; } bool SwappingFlowControlStatement::ChildCompileBody() { mArrivalPoint = mJumpPoint; return true; } bool SwappingFlowControlStatement::ChildExecuteBody() { // // Is this allowed? // if(!mAllowInLoops && mArrivalPoint->TestState(_Returning)) { this->ReportError("A swapping flow control statement is not permitted in loops."); return false; } // // If we jumped here, continue; if we come here sequentially, jump // if(!mArrivalPoint->TestState(_Jumped)) this->Jump(); return true; } // // Conditional flow control statement (like if) // ConditionalFlowControlStatement::ConditionalFlowControlStatement(iScript *script, const iString &command) : GenericFlowControlStatement(script,command,_Entry) { mCalculator = 0; } ConditionalFlowControlStatement::~ConditionalFlowControlStatement() { if(mCalculator != 0) delete mCalculator; } Calculator* ConditionalFlowControlStatement::GetCalculator() const { if(mCalculator != 0) return mCalculator; else return mScript->GetCalculator(); } bool ConditionalFlowControlStatement::ChildCompileBody() { if(!this->ParseOperandForCondition()) return false; if(mOwnsCalculator) { mCalculator = this->CreateCalculator(); } if(!this->GetCalculator()->Verify(mOperand,1,1,"condition")) { this->ReportError(this->GetCalculator()); return false; } return true; } bool ConditionalFlowControlStatement::ChildExecuteBody() { if(this->GetCalculator()->Evaluate(mOperand)) { bool result = Constant::ConvertToNative(this->GetCalculator()->GetResultData()[0]); if(result) mState = _Empty; else { mState = _Jumped; this->Jump(); } return true; } else { this->ReportError(this->GetCalculator()); return false; } } // // Loop flow control statement (like do or for) // LoopFlowControlStatement::LoopFlowControlStatement(iScript *script, const iString &command, bool usesSingleCalculator) : GenericFlowControlStatement(script,command,_Entry), mUsesSingleCalculator(usesSingleCalculator) { mIndex = iMath::_IntMax; mCount = 0; mStep = 1; int i; for(i=0; i<3; i++) mCalculator[i] = 0; } LoopFlowControlStatement::~LoopFlowControlStatement() { int i; for(i=0; i<3; i++) if(mCalculator[i] != 0) delete mCalculator[i]; } Calculator* LoopFlowControlStatement::GetCalculator(int i) const { if(i>=0 && i<3) { if(mCalculator[i] != 0) return mCalculator[i]; else return mScript->GetCalculator(); } else return mScript->GetCalculator(); } bool LoopFlowControlStatement::ChildCompileBody() { if(!this->ParseOperandForCount()) return false; if(mOwnsCalculator) { mCalculator[0] = this->CreateCalculator(); if(!mUsesSingleCalculator) { if(!mFirstExpression.IsEmpty()) mCalculator[1] = this->CreateCalculator(); if(!mStepExpression.IsEmpty()) mCalculator[2] = this->CreateCalculator(); } } if(!this->GetCalculator(0)->Verify(mOperand,1,0,"loop count")) { this->ReportError(this->GetCalculator(0)); return false; } if(!mFirstExpression.IsEmpty()) { if(!this->GetCalculator(1)->Verify(mFirstExpression,1,0,"loop first")) { this->ReportError(this->GetCalculator(1)); return false; } } if(!mStepExpression.IsEmpty()) { if(!this->GetCalculator(2)->Verify(mStepExpression,1,0,"loop step")) { this->ReportError(this->GetCalculator(2)); return false; } } return true; } bool LoopFlowControlStatement::ChildExecuteBody() { if(this->GetCalculator(0)->Evaluate(mOperand)) { mCount = Constant::ConvertToNative(this->GetCalculator(0)->GetResultData()[0]); } else { this->ReportError(this->GetCalculator(0)); return false; } if(mIndex == iMath::_IntMax) { if(mFirstExpression.IsEmpty()) { mIndex = 1; } else { if(this->GetCalculator(1)->Evaluate(mFirstExpression)) { mIndex = Constant::ConvertToNative(this->GetCalculator(1)->GetResultData()[0]); } else { this->ReportError(this->GetCalculator(1)); return false; } } } if(mStepExpression.IsEmpty()) { mStep = 1; } else { if(this->GetCalculator(2)->Evaluate(mStepExpression)) { mStep = Constant::ConvertToNative(this->GetCalculator(2)->GetResultData()[0]); if(mStep == 0) { this->ReportError("Zero step in the loop statement is not permitted."); return false; } } else { this->ReportError(this->GetCalculator(2)); return false; } } if((mStep>0 && mIndexmCount)) { mState = _Returning; } else if(mIndex == mCount) { mState = _Empty; } else { mState = _Jumped; this->Jump(); } mScript->SetLoopParameters(mIndex,mCount); this->OnExecute(); if(mState != _Returning) mIndex = iMath::_IntMax; else mIndex += mStep; return true; } // // Variable declaration statement // VariableDeclarationStatement::VariableDeclarationStatement(iScript *script, const iString &command) : Statement(script,command) { #ifdef ISCRIPT_BACKWARD_COMPATIBLE mAcceptsArrays = true; #endif } bool VariableDeclarationStatement::CompileBody() { iString w, s(mOperand); // // Remove commas if they are present - they are just for aestetics // s.Replace(","," "); s.ReduceWhiteSpace(); if(s.IsEmpty()) { this->ReportError("Variable name must be specified."); return false; } int i, n, last, k = 0; w = s.Section(" ",k,k); while(!w.IsEmpty()) { // // Check that the name is alpha-numeric // i = w.Find(mScript->GetCalculator()->SymbolOpeningBraket()); if(i == -1) i = w.Length(); if(!mScript->IsValidVariableName(w.Part(0,i))) { this->ReportError("Variable name must be alpha-numeric.",w); return false; } if(i == w.Length()) { // // No dimension argument // if(mIndex < 0) { // // No dimension argument at all, a scalar // n = 1; } else if(mIndex > 1) { n = mIndex; } else { this->ReportError("Array dimension must be an integer positive constant."); return false; } } else { last = i; n = this->ParseOperandForIndex(w,i,last); if(n == 0) { this->ReportError("Array dimension must be an integer positive constant.",w.Part(i)); return false; } if(n<0 || last!=w.Length()-1) { this->ReportError("Syntax error: foreign characters after the variable name.",w.Part(last)); return false; } } w = w.Part(0,i); // // Is it unique and non-reserved? // if(mScript->mDummyWords.Find(w) > -1) { this->ReportError("This name is reserved for a dummy command word.",w); return false; } iArray &c(mScript->mConstants); for(i=0; iName() == w) { this->ReportError("This name is reserved for a global constant.",w); return false; } iArray &ps(mScript->mPrototypes); for(i=0; imNumStatementPrototypes; i++) if(ps[i]->Command() == w) { this->ReportError("This name is reserved for a command word.",w); return false; } for(i=mScript->mNumStatementPrototypes; iCommand() == w) { this->ReportError("Variable with this name has already been declared.",w); return false; } Prototype *p = this->CreatePrototype(w,n); if(p == 0) { this->ReportError("There is not enough free memory to proceed."); return false; } ps.Add(p); mVarNames.Add(w); k++; w = s.Section(" ",k,k); } return true; } bool VariableDeclarationStatement::ExecuteBody() { // // Release the variables // int i; Value *val; for(i=0; iFindVariable(mVarNames[i]); if(val == 0) { this->ReportError("Internal error: cannnot find a declared variable."); return false; } val->mIsReleased = true; } return true; } }; ifrit-3.4.2/core/iscriptkit.h0000755000175700010010000003526512167404420014506 0ustar HomeNone/*========================================================================= Program: Ionization FRont Interactive Tool (IFRIT) Language: C++ Copyright (c) 2002-2012 Nick Gnedin All rights reserved. This file may be distributed and/or modified under the terms of the GNU General Public License version 2 as published by the Free Software Foundation and appearing in the file LICENSE.GPL included in the packaging of this file. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHORS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. =========================================================================*/ #ifndef ISCRIPTKIT_H #define ISCRIPTKIT_H #include "iarray.h" #include "icalculator.h" #include "istring.h" class iScript; namespace iScriptKit { // // Calculator with error-reporting type conversion // class Value; class Calculator : public iCalculator { friend class ::iScript; public: bool Verify(const iString &expr, int dim, int use, const iString &err); void AddVariable(const result_t *var); // scope resolution helper protected: Calculator(iScript *script); virtual const iCalculatorKit::Variable* FindExternalVariable(const iString &name) const; iScript *mScript; }; // // Base class for values (variables and parameters) // class Value { friend class VariableDeclarationStatement; public: virtual ~Value(); const iString& Name() const; int Dim() const; int Use() const; inline bool IsReleased() const { return mIsReleased; } inline const Calculator::result_t* CalculatorValue() const { return mValue; } virtual iString GetValueAsText() const = 0; virtual iString GetTypeAsText() const = 0; virtual int GetTypeId() const = 0; bool Morph(int dim); protected: Value(iScript *script, const iString &name, int dim, int use); void ReportError(const iString &str); Calculator::result_t *mValue; bool mIsReleased; iScript *mScript; #ifdef I_DEBUG private: int mId; static int mIdCounter; #endif }; // // Class for parameters. // template class Constant : public Value { public: static int UsagePattern(); static T ConvertToNative(Calculator::number_t v); static Calculator::number_t ConvertFromNative(T v); Constant(iScript *script, const iString &name, T v); Constant(iScript *script, const iString &name, int dim, T *v); Constant(iScript *script, const Calculator::result_t *val); // special direct assignment constructor virtual iString GetValueAsText() const; virtual iString GetTypeAsText() const; virtual int GetTypeId() const; protected: const iString& GetTypeName() const; }; template inline int Constant::UsagePattern() { return 0; } template<> inline int Constant::UsagePattern() { return 1; } template<> inline int Constant::GetTypeId() const { return 1; } template<> inline int Constant::GetTypeId() const { return 2; } template<> inline int Constant::GetTypeId() const { return 3; } template<> inline int Constant::GetTypeId() const { return 4; } template<> inline const iString& Constant::GetTypeName() const { static const iString t("int"); return t; } template<> inline const iString& Constant::GetTypeName() const { static const iString t("bool"); return t; } template<> inline const iString& Constant::GetTypeName() const { static const iString t("float"); return t; } template<> inline const iString& Constant::GetTypeName() const { static const iString t("double"); return t; } // // Assignment operation type // const short _Direct = 0; const short _IncAdd = 1; const short _IncSub = 2; const short _IncMul = 4; const short _IncDiv = 8; const short _IncAll = 15; // // Class for variables. // template class Variable : public Constant { public: static short NaturalMask(); static T Combine(T prev, T v, short at); Variable(iScript *script, const iString &name); Variable(iScript *script, const iString &name, int dim); bool Assign(const Calculator::result_t *v, short at, int index); bool Assign(T v, int index); }; template inline short Variable::NaturalMask() { return _IncAll; } template<> inline short Variable::NaturalMask() { return _Direct; } template inline T Variable::Combine(T prev, T v, short at) { switch(at) { case _IncAdd: { prev += v; break; } case _IncSub: { prev -= v; break; } case _IncMul: { prev *= v; break; } case _IncDiv: { prev /= v; break; } default: { prev = v; break; } } return prev; } template<> inline bool Variable::Combine(bool, bool v, short) { return v; } // // Base class for prototypes. // class Statement; class Prototype { friend class ::iScript; public: inline const iString& Command() const { return mCommand; } protected: Prototype(iScript *script, const iString &command); virtual ~Prototype(); virtual Statement* CreateWorker() const = 0; iString mCommand; iScript *mScript; private: // // A prototype cannot be compiled except by its script // bool Compile(const iString &arg, int line, int pos); }; // // Specific prototypes // template class Prototype0 : public Prototype { friend class ::iScript; protected: virtual Statement* CreateWorker() const; private: // // To be created by script only // Prototype0(iScript *script, const iString &command) : Prototype(script,command){} }; // // Specific prototypes // class VariableDeclarationStatement; template class Prototype1 : public Prototype { friend class ::iScript; friend class VariableDeclarationStatement; protected: virtual Statement* CreateWorker() const; private: // // To be created by script only // Prototype1(iScript *script, const iString &command, A arg) : Prototype(script,command), mArgument(arg){} A mArgument; }; // // Specific prototypes // template class Prototype2 : public Prototype { friend class ::iScript; protected: virtual Statement* CreateWorker() const; private: // // To be created by script only // Prototype2(iScript *script, const iString &command, A1 arg1, A2 arg2) : Prototype(script,command), mArgument1(arg1), mArgument2(arg2){} A1 mArgument1; A2 mArgument2; }; // // Base class for statements. // class Statement { friend class ::iScript; friend class Prototype; friend class GenericFlowControlStatement; public: virtual ~Statement(); inline int EntryInCode() const { return mEntryInCode; } inline int LineInScript() const { return mLineInScript; } inline const iString& Command() const { return mCommand; } inline const iString& Argument() const { return mArgument; } protected: Statement(iScript *script, const iString &command); virtual bool CompileBody() = 0; virtual bool ExecuteBody() = 0; // // Helper functiuons needed here and there // void ShiftOperandWhiteSpace(); int ParseOperandForIndex(const iString &str, int pos, int &last) const; Value* FindVariable(const iString &name) const; Calculator* CreateCalculator() const; inline void ReportError(const iString &message) const { this->ReportError(message,mOperand); } void ReportError(const iString &message, const iString &context) const; void ReportError(const Calculator *c) const; bool mAcceptsArrays, mOwnsCalculator; int mIndex, mEntryInCode, mLineInScript; iString mCommand, mOperand, mIndexExpression; iScript *mScript; private: iString mArgument; // // A statement cannot be executed except by its script // bool Execute(); }; // // A simple, argument-less function call statement // class SimpleStatement : public Statement { public: typedef bool (*FunctionType)(iScript *script); SimpleStatement(iScript *script, const iString &command, FunctionType f); protected: virtual bool CompileBody(); virtual bool ExecuteBody(); FunctionType mFun; }; // // A deprecated statement // class DeprecatedStatement : public Statement { public: DeprecatedStatement(iScript *script, const iString &command, const iString &message); protected: virtual bool CompileBody(); virtual bool ExecuteBody(); const iString mMessage; }; // // A programmable function call statement (can be specialized to implement any command) // class FunctionCallStatement : public Statement { public: typedef bool (*FunctionType1)(iScript *script, const iString &arg); typedef bool (*FunctionType2)(iScript *script, const iString &arg, int index); public: FunctionCallStatement(iScript *script, const iString &command, FunctionType1 f); FunctionCallStatement(iScript *script, const iString &command, FunctionType2 f); protected: virtual bool CompileBody(); virtual bool ExecuteBody(); Calculator* GetIndexCalculator() const; FunctionType1 mFun1; FunctionType2 mFun2; Calculator *mIndexCalculator; }; // // Assignment statement // class AssignmentStatement : public Statement { public: ~AssignmentStatement(); protected: AssignmentStatement(iScript *script, const iString &command, short mask, int dim, int use); virtual bool CompileBody(); virtual bool ExecuteBody(); virtual bool SetValue(const Calculator::result_t *result, int index) = 0; Calculator* GetCalculator() const; Calculator* GetIndexCalculator() const; bool ParseOperandForAssignmentType(); int mDim, mUse; short mAssignmentType, mAssignmentMask; Calculator *mCalculator, *mIndexCalculator; }; // // Variable assignment statement // template class VariableAssignmentStatement : public AssignmentStatement { public: VariableAssignmentStatement(iScript *script, Variable &var); protected: virtual bool SetValue(const Calculator::result_t *result, int index); Variable &mVar; }; // // Function call assignment statement // template class FunctionCallAssignmentStatement : public AssignmentStatement { private: typedef bool (*FunctionType1)(iScript *script, short at, T result); typedef bool (*FunctionType2)(iScript *script, short at, int num, const T *result, int index); public: FunctionCallAssignmentStatement(iScript *script, const iString &command, FunctionType1 f, short mask = Variable::NaturalMask()); FunctionCallAssignmentStatement(iScript *script, const iString &command, FunctionType2 f, short mask = Variable::NaturalMask()); protected: virtual bool SetValue(const Calculator::result_t *result, int index); FunctionType1 mFun1; FunctionType2 mFun2; }; // // FlowControl types // enum FlowControlType { _Entry = 1, // enter a branch _Exit = 2 // exit a branch }; enum FlowControlState { _Empty = 0, _Jumped = 1, _Returning = 2 }; // // Generic flow control statement // class GenericFlowControlStatement : public Statement { public: inline bool IsOfType(FlowControlType type) const { return (mType & type) != 0; } inline bool TestState(FlowControlState state) const { return (mState & state) != 0; } protected: GenericFlowControlStatement(iScript *script, const iString &command, FlowControlType type); virtual bool CompileBody(); virtual bool ExecuteBody(); virtual bool ChildCompileBody() = 0; virtual bool ChildExecuteBody() = 0; void Jump(); FlowControlType mType; FlowControlState mState; GenericFlowControlStatement* mJumpPoint; }; // // Closing flow control statement (like enddo or endif) // class ClosingFlowControlStatement : public GenericFlowControlStatement { public: ClosingFlowControlStatement(iScript *script, const iString &command); protected: virtual bool ChildCompileBody(); virtual bool ChildExecuteBody(); }; // // Swapping flow control statement (like else) // class SwappingFlowControlStatement : public GenericFlowControlStatement { public: SwappingFlowControlStatement(iScript *script, const iString &command); protected: virtual bool ChildCompileBody(); virtual bool ChildExecuteBody(); bool mAllowInLoops; GenericFlowControlStatement* mArrivalPoint; }; // // Conditional flow control statement (like if) // class ConditionalFlowControlStatement : public GenericFlowControlStatement { public: virtual ~ConditionalFlowControlStatement(); protected: ConditionalFlowControlStatement(iScript *script, const iString &command); virtual bool ChildCompileBody(); virtual bool ChildExecuteBody(); virtual bool ParseOperandForCondition() = 0; Calculator* GetCalculator() const; Calculator *mCalculator; }; // // Loop flow control statement (like do or for) // class LoopFlowControlStatement : public GenericFlowControlStatement { public: virtual ~LoopFlowControlStatement(); protected: LoopFlowControlStatement(iScript *script, const iString &command, bool usesSingleCalculator); virtual bool ChildCompileBody(); virtual bool ChildExecuteBody(); virtual bool ParseOperandForCount() = 0; virtual void OnExecute(){} Calculator* GetCalculator(int i) const; int mIndex, mCount, mStep; iString mFirstExpression, mStepExpression; Calculator *mCalculator[3]; bool mUsesSingleCalculator; }; // // Variable declaration statement // class VariableDeclarationStatement : public Statement { protected: VariableDeclarationStatement(iScript *script, const iString &command); virtual bool CompileBody(); // variables are actually created at compile-time virtual bool ExecuteBody(); virtual Prototype* CreatePrototype(const iString &name, int dim) const = 0; template Prototype* NewPrototype(const iString &name, int dim) const; private: iArray mVarNames; template class PrototypeHelper : public Prototype { public: PrototypeHelper(iScript *script, Variable &var) : Prototype(script,var.Name()), mVar(var){} protected: virtual Statement* CreateWorker() const { return new VariableAssignmentStatement(this->mScript,this->mVar); } private: Variable &mVar; }; }; }; #endif // ISCRIPTKIT_H ifrit-3.4.2/core/iscriptkittemplate.h0000755000175700010010000002237512167404420016240 0ustar HomeNone/*========================================================================= Program: Ionization FRont Interactive Tool (IFRIT) Language: C++ Copyright (c) 2002-2012 Nick Gnedin All rights reserved. This file may be distributed and/or modified under the terms of the GNU General Public License version 2 as published by the Free Software Foundation and appearing in the file LICENSE.GPL included in the packaging of this file. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHORS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. =========================================================================*/ #include "iscriptkit.h" #include "ierror.h" namespace iScriptKit { // // Class for parameters. // template Constant::Constant(iScript *script, const iString &name, T v) : Value(script,name,1,Constant::UsagePattern()) { this->mValue->Data()[0] = this->ConvertFromNative(v); } template Constant::Constant(iScript *script, const iString &name, int dim, T *v) : Value(script,name,dim,Constant::UsagePattern()) { int i, n = this->mValue->Dim(); Calculator::number_t *data = this->mValue->Data(); if(v != 0) { for(i=0; iConvertFromNative(v[i]); } else { for(i=0; iConvertFromNative(0); } } template Constant::Constant(iScript *script, const Calculator::result_t *val) : Value(script,val->Name(),val->Dim(),UsagePattern()) { this->mValue->Copy(*val); } template inline T Constant::ConvertToNative(Calculator::number_t v) { return T(v); } template<> inline bool Constant::ConvertToNative(Calculator::number_t v) { return (iCalculatorKit::ConvertToBoolRepresentation(v) > 0.5); } template inline Calculator::number_t Constant::ConvertFromNative(T v) { return Calculator::number_t(v); } template<> inline Calculator::number_t Constant::ConvertFromNative(bool v) { return (v ? 1.0 : 0.0); } template iString Constant::GetValueAsText() const { int n = this->mValue->Dim(); Calculator::number_t *data = this->mValue->Data(); if(n == 1) { return iString::FromNumber(ConvertToNative(data[0])); } else { int i; iString s("("); for(i=0; i 0) s += ","; s += iString::FromNumber(ConvertToNative(data[i])); } s += ")"; return s; } } template iString Constant::GetTypeAsText() const { static const iString s(" scalar"); static const iString a(" array"); if(this->Dim() == 1) return this->GetTypeName()+s; else return this->GetTypeName()+a; } // // Class for variables. // template Variable::Variable(iScript *script, const iString &name) : Constant(script,name,1,0) { } template Variable::Variable(iScript *script, const iString &name, int dim) : Constant(script,name,dim,0) { } template bool Variable::Assign(const Calculator::result_t *v, short at, int index) { if(v == 0) { this->ReportError("Internal error: assigning a null pointer to the variable {"+this->Name()+"}."); // shouldn't ever happen return false; } int n = this->mValue->Dim(); Calculator::number_t *data = this->mValue->Data(); Calculator::number_t *src = v->Data(); if(index == -1) // complete assignment { if(this->mValue->Dim()!=v->Dim() || this->mValue->Use()!=v->Use()) { this->ReportError("Internal error: incompatible assignment of {"+v->Name()+"} to {"+this->mValue->Name()+"} has not been detected at compile-time."); return false; } int i; for(i=0; iConvertFromNative(this->Combine(this->ConvertToNative(data[i]),this->ConvertToNative(src[i]),at)); } else { if(index<0 || index>=n) { this->ReportError("Accessing array "+this->mValue->Name()+" outside of bounds (with index="+iString::FromNumber(index+1)+")."); return false; } data[index] = this->ConvertFromNative(this->Combine(this->ConvertToNative(data[index]),this->ConvertToNative(src[0]),at)); } #ifdef I_DEBUG iConsole::Display(iConsole::_Info,(this->Name()+"{"+this->GetTypeAsText()+"}: "+this->GetValueAsText()+"\n").ToCharPointer()); #endif return true; } template bool Variable::Assign(T v, int index) { if(index<0 || index>=this->mValue->Dim()) { this->ReportError("Accessing array "+this->mValue->Name()+" outside of bounds (with index="+iString::FromNumber(index+1)+")."); return false; } this->mValue->Data()[index] = this->ConvertFromNative(v); #ifdef I_DEBUG iConsole::Display(iConsole::_Info,(this->Name()+"{"+this->GetTypeAsText()+"}: "+this->GetValueAsText()+"\n").ToCharPointer()); #endif return true; } // // Specific prototypes // template Statement* Prototype0::CreateWorker() const { return new T(mScript,mCommand); } template Statement* Prototype1::CreateWorker() const { return new T(mScript,mCommand,mArgument); } template Statement* Prototype2::CreateWorker() const { return new T(mScript,mCommand,mArgument1,mArgument2); } // // Variable assignment statement // template VariableAssignmentStatement::VariableAssignmentStatement(iScript *script, Variable &var) : AssignmentStatement(script,var.Name(),Variable::NaturalMask(),var.Dim(),var.Use()), mVar(var) { this->mAcceptsArrays = (var.Dim() > 1); } template bool VariableAssignmentStatement::SetValue(const Calculator::result_t *result, int index) { if(result == 0) { this->ReportError("Internal error: null pointer for the calculation result."); // shouldn't ever happen return false; } return this->mVar.Assign(result,this->mAssignmentType,index); } // // Function call assignment statement // template FunctionCallAssignmentStatement::FunctionCallAssignmentStatement(iScript *script, const iString &command, FunctionType1 f, short mask) : AssignmentStatement(script,command,mask,1,Constant::UsagePattern()), mFun1(f), mFun2(0) { this->mAcceptsArrays = false; } template FunctionCallAssignmentStatement::FunctionCallAssignmentStatement(iScript *script, const iString &command, FunctionType2 f, short mask) : AssignmentStatement(script,command,mask,-1,Constant::UsagePattern()), mFun1(0), mFun2(f) { this->mAcceptsArrays = true; } template bool FunctionCallAssignmentStatement::SetValue(const Calculator::result_t *result, int index) { if(result == 0) { this->ReportError("Internal error: null pointer for the calculation result."); // shouldn't ever happen return false; } if(index == -1) { if(this->mFun1 != 0) { return this->mFun1(this->mScript,this->mAssignmentType,Constant::ConvertToNative(result->Data()[0])); } else if(this->mFun2 != 0) { T *buffer = new T[result->Dim()]; if(buffer == 0) { this->ReportError("There is not enough memory to proceed."); return false; } int i; for(i=0; iDim(); i++) buffer[i] = Constant::ConvertToNative(result->Data()[i]); bool ret = this->mFun2(this->mScript,this->mAssignmentType,result->Dim(),buffer,-1); delete [] buffer; return ret; } else { this->ReportError("iScriptKit::FunctionCallAssignmentStatement is configured incorrectly."); return false; } } else { if(this->mFun2 != 0) { T tmp = Constant::ConvertToNative(result->Data()[0]); return this->mFun2(this->mScript,this->mAssignmentType,1,&tmp,index); } else { this->ReportError("iScriptKit::FunctionCallAssignmentStatement is configured incorrectly."); return false; } } } template Prototype* VariableDeclarationStatement::NewPrototype(const iString &name, int dim) const { Variable *v = new Variable(this->mScript,name,dim); if(v != 0) { Prototype *p = new PrototypeHelper(mScript,*v); if(p != 0) { this->mScript->AddVariable(v); return p; } delete v; } return 0; } }; template void iScript::AddPrototype(const iString &command) { iScriptKit::Prototype *prototype = new iScriptKit::Prototype0(this,command); this->RegisterPrototype(prototype); } template void iScript::AddPrototype(const iString &command, A arg) { iScriptKit::Prototype *prototype = new iScriptKit::Prototype1(this,command,arg); this->RegisterPrototype(prototype); } template void iScript::AddPrototype(const iString &command, A1 arg1, A2 arg2) { iScriptKit::Prototype *prototype = new iScriptKit::Prototype2(this,command,arg1,arg2); this->RegisterPrototype(prototype); } ifrit-3.4.2/core/iserialpipeline.h0000644000175700010010000000520412167404421015463 0ustar HomeNone/*========================================================================= Program: Ionization FRont Interactive Tool (IFRIT) Language: C++ Copyright (c) 2002-2012 Nick Gnedin All rights reserved. This file may be distributed and/or modified under the terms of the GNU General Public License version 2 as published by the Free Software Foundation and appearing in the file LICENSE.GPL included in the packaging of this file. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHORS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. =========================================================================*/ // // This is base class for all parallellizable pipelines // #ifndef ISERIALPIPELINE_H #define ISERIALPIPELINE_H #include "igenericfilter.h" template class iSerialPipeline : public Filter { public: virtual iSerialPipeline* Copy() const = 0; virtual float GetMemorySize() { return this->Filter::GetMemorySize() + this->GetContentsMemorySize(); } virtual void UpdateContents(int n, int info = 0) = 0; void SetGlobalInput(InputType *i) { this->mGlobalInput = i; } InputType* GetGlobalInput() const { return this->mGlobalInput; } virtual void SetNthInput(int num, vtkDataObject *input){ Filter::SetNthInput(num,input); } // vtkProcessObject::SetNthInput(num,input) is protected protected: iSerialPipeline(iViewSubject *vo, int numInputs) : Filter(vo,numInputs,true,true) { this->mGlobalInput = 0; } virtual float GetContentsMemorySize() const = 0; InputType *mGlobalInput; }; // // Create specific filters // typedef iSerialPipeline iPolyDataToPolyDataPipeline; typedef iSerialPipeline iGridDataToPolyDataPipeline; typedef iSerialPipeline iGridDataToGridDataPipeline; typedef iSerialPipeline iAnyDataToPolyDataPipeline; #endif // ISERIALPIPELINE_H ifrit-3.4.2/core/ishell.cpp0000755000175700010010000005506612167404436014144 0ustar HomeNone/*========================================================================= Program: Ionization FRont Interactive Tool (IFRIT) Language: C++ Copyright (c) 2002-2012 Nick Gnedin All rights reserved. This file may be distributed and/or modified under the terms of the GNU General Public License version 2 as published by the Free Software Foundation and appearing in the file LICENSE.GPL included in the packaging of this file. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHORS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. =========================================================================*/ #include "ishell.h" #include "icontrolmodule.h" #include "icontrolscript.h" #include "idirectory.h" #include "ierror.h" #include "ieventobserver.h" #include "ierrorstatus.h" #include "ifile.h" #include "iimagefactory.h" #include "ioutputchannel.h" #include "iparallelmanager.h" #include "ishellfactory.h" #include "iversion.h" #include "iviewmodule.h" #include "ivolumeviewsubject.h" #include #include #ifdef I_OFFSCREEN #include #include #endif // // Templates // #include "iarraytemplate.h" using namespace iParameter; const iString iShell::mOptionPrefix = "-"; namespace iShell_Private { void CheckSystem(); void TestPerformance(); class BatchModeObserver : public iScriptObserver { public: BatchModeObserver(iScript *s) : iScriptObserver(s) { } protected: virtual void OnScriptStartBody(){} virtual void OnScriptStopBody(const iString &error){} virtual void OnScriptBeginLineBody(int line, const iString &text) { iConsole::Display(iConsole::_Info,"Executing line #"+iString::FromNumber(line)+": "+text); } virtual void OnScriptEndLineBody(int , const iString &){} virtual bool OnScriptCheckAbortBody(int cur, int num, int level) { if(cur>-1 && num>0) { iConsole::Display(iConsole::_Info,"Loop: level #"+iString::FromNumber(level)+", iteration "+iString::FromNumber(cur)+" out of "+iString::FromNumber(num)); } return false; } }; }; using namespace iShell_Private; void iShell::RunApplication(const iString &t, int argc, char **argv) { #ifdef I_DEBUG // iHelpFactory::CreateUserGuide(iHelpFactory::_Publish); return; #endif iShell *tmp = iShell::New(t,argc,argv); if(tmp != 0) { tmp->Run(); tmp->Delete(); } } iShell::iShell(const iString &type, int, char **) : mType(type) { int i; mRunning = false; mControlModule = 0; // control module must be created after the constructor is finished mNumProcs = 1; mCurInitStep = 0; for(i=0; i<4; i++) { mInitSteps[i].Current = 0; } mInitSteps[0].Total = 10; // needs to be set manually during development. How to do it automatically? mInitSteps[1].Total = 161; // needs to be set manually during development. How to do it automatically? mInitSteps[2].Total = 1382; // needs to be set manually during development. How to do it automatically? mInitSteps[3].Total = 13; // needs to be set manually during development. How to do it automatically? // // Define some basic command-line options // this->AddCommandLineOption("h",false,"show this help"); this->AddCommandLineOption("help",false,"show this help"); this->AddCommandLineOption("-help",false,"show this help"); this->AddCommandLineOption("i",true,"load the state from a file with name "); this->AddCommandLineOption("b",true,"execute a control script from a file in the screenless mode"); this->AddCommandLineOption("np",true,"set the number of processors to use to "); this->AddCommandLineOption("test",false,"test performance and exit (must be the first and only option)"); this->AddCommandLineOption("GPU",false,"try to use GPU even if VTK does not find it"); this->AddCommandLineOption("no-GPU",false,"do not use GPU even if it is present on the system (useful for running IFrIT remotely)"); // // Set environment variables // Is the base-dir environment variable set? // char *e = getenv("IFRIT_DIR"); if(e != 0) { mEnvBaseDir = iString(e); if(mEnvBaseDir.IsEmpty()) mEnvBaseDir = iDirectory::Current(); if(!mEnvBaseDir.EndsWith(iDirectory::Separator())) mEnvBaseDir += iDirectory::Separator(); } else { // // Get the home directory, if it exists // e = getenv("APPDATA"); // windows? if(e != 0) { mEnvBaseDir = iString(e) + iDirectory::Separator() + "IfrIT" + iDirectory::Separator(); } else // unix? { e = getenv("HOME"); mEnvBaseDir = iString(e) + iDirectory::Separator() + ".ifrit" + iDirectory::Separator(); } // // Is it readable? // iDirectory dir; if(!dir.Open(mEnvBaseDir)) { // // try to create // if(!dir.Make(mEnvBaseDir)) { mEnvBaseDir = iDirectory::Current(); } } } // // Read other environment here // e = getenv("IFRIT_DATA_DIR"); if(e != 0) mEnvDataDir = iString(e) + iDirectory::Separator(); else mEnvDataDir = iDirectory::Current(); e = getenv("IFRIT_IMAGE_DIR"); if(e != 0) mEnvImageDir = iString(e) + iDirectory::Separator(); else mEnvImageDir = iDirectory::Current(); e = getenv("IFRIT_SCRIPT_DIR"); if(e != 0) mEnvScriptDir = iString(e) + iDirectory::Separator(); else mEnvScriptDir = mEnvBaseDir; e = getenv("IFRIT_PALETTE_DIR"); if(e != 0) mEnvPaletteDir = iString(e) + iDirectory::Separator(); else mEnvPaletteDir = mEnvBaseDir; iDirectory::ExpandFileName(mEnvBaseDir); iDirectory::ExpandFileName(mEnvDataDir); iDirectory::ExpandFileName(mEnvImageDir); iDirectory::ExpandFileName(mEnvScriptDir); iDirectory::ExpandFileName(mEnvPaletteDir); mInitTimer = vtkTimerLog::New(); IERROR_ASSERT(mInitTimer); mInitTimer->StartTimer(); #ifdef I_OFFSCREEN // // Configure Graphics Factory // vtkGraphicsFactory *graphics_factory = vtkGraphicsFactory::New(); IERROR_ASSERT(graphics_factory); graphics_factory->SetOffScreenOnlyMode(1); graphics_factory->SetUseMesaClasses(1); // // Configure Imaging Factory vtkImagingFactory *imaging_factory = vtkImagingFactory::New(); IERROR_ASSERT(imaging_factory); imaging_factory->SetUseMesaClasses(1); #endif } iShell::~iShell() { // // This ensures that control module is deleted after the shell is deleted. // // mControlModule->Delete(); mInitTimer->Delete(); } iShell* iShell::New(const iString &t, int argc, char **argv) { // // Check that sizes of basic types are correct // CheckSystem(); // // Check if a test call // if(argc==2 && iString(argv[1])==(mOptionPrefix+"test")) { TestPerformance(); return 0; } // // Also use options to specify shell - they overwrite the default choice // iString st = t; int firstOption = 1; if(argc>1 && iString(argv[1]).Part(0,mOptionPrefix.Length())==mOptionPrefix) { iString list, help, s = iString(argv[1]).Part(mOptionPrefix.Length()); iShellFactory::GetSupportedShells(list,help); if(list.Contains(s+"/") == 1) { st = s; firstOption = 2; } } // // If there is no default and no option, ask ShellFactory to query the user // if(st.IsEmpty()) { iConsole::Display(iConsole::_FatalError,"No shell has been specified. Use a \"-\" option to specify a two-letter shell abbreviation ."); return 0; } // // Create shell // iShell *tmp = iShellFactory::CreateShell(st,argc,argv); if(tmp == 0) { iConsole::Display(iConsole::_FatalError,"Shell '"+st+"' is not included in this installation."); return 0; } tmp->mFirstOption = firstOption; // // Make sure Image factory is up to date // iImageFactory::FindIcon("ok.png"); // // Parse command line options // tmp->DefineSpecificCommandLineOptions(); tmp->ParseCommandLineOptions(argc,argv); #ifdef I_DEBUG //tmp->mNumProcs = 2; #endif if(tmp->mScriptFileName.IsEmpty()) { tmp->PrepareForConstruction(); } #ifdef I_DEBUG tmp->InitHelper(); #endif // // This ensures that "tmp->this" pointer is correct before a control module is created. // tmp->mCurInitStep = 1; tmp->mControlModule = iControlModule::New(tmp); IERROR_ASSERT(tmp->mControlModule); if(tmp->mNumProcs >= 0) tmp->mControlModule->GetParallelManager()->SetNumberOfProcessors(tmp->mNumProcs); // // Set the state file name // if(tmp->mStateFileName.IsEmpty()) { iString fname = tmp->GetEnvironment(Environment::Base) + "ifrit.ini"; if(iFile::IsReadable(fname)) tmp->mStateFileName = fname; } #ifdef I_DEBUG tmp->InitHelper(); #endif // // Really construct the shell: control module needs to be fully initialized before a shell // is really constructed. // tmp->mCurInitStep = 2; if(tmp->mScriptFileName.IsEmpty()) { tmp->ConstructorBody(); } // // Load widget info into ObjectKeyHelp objects. // #ifdef I_DEBUG tmp->InitHelper(); #endif // // Load the state file if needed // tmp->mCurInitStep = 3; if(!tmp->mStateFileName.IsEmpty()) { if(tmp->mScriptFileName.IsEmpty()) { tmp->PrepareToLoadStateFile(); } if(!tmp->GetControlModule()->LoadStateFromFile(tmp->mStateFileName)) { iConsole::Display(iConsole::_HighError,"Unable to load the state file.\n Default values of parameters will be used."); } } #ifdef I_DEBUG tmp->InitHelper(); #endif if(tmp->mScriptFileName.IsEmpty()) { #ifdef I_OFFSCREEN // // In the off-screen mode we need the script // iConsole::Display(iConsole::_FatalError,"A batch script filename is required in the off-screen-only mode."); return 0; #else // // Start the shell // tmp->Start(); return tmp; #endif } else { // // Execute script and exit // int i, n = tmp->mControlModule->GetNumberOfViewModules(); for(i=0; imControlModule->GetViewModule(i)->GetRenderWindow()->SetOffScreenRendering(1); } if(tmp->mControlModule->GetViewModule(0)->GetRenderWindow()->GetOffScreenRendering() == 0) { iConsole::Display(iConsole::_FatalError,"This platform+shell combination does not support off-screen rendering.\n Off-screen rendering is needed for executing a script in a batch mode."); return 0; } // // Execute the batch script // iFile F(tmp->mScriptFileName); if(!F.Open(iFile::_Read,iFile::_Text)) { iConsole::Display(iConsole::_FatalError,iString("File ")+tmp->mScriptFileName+" cannot be open for reading."); return 0; } iConsole::Display(iConsole::_Info,"Reading the file..."); iString text, line; while(F.ReadLine(line)) text += "\n" + line; text += "\n"; iControlScript *cs = tmp->mControlModule->GetControlScript(); iConsole::Display(iConsole::_Info,"Compiling the script..."); cs->SetText(text); if(!cs->Compile()) { iConsole::Display(iConsole::_FatalError,iString("Syntax error in script, line ")+iString::FromNumber(cs->GetThisLine())+" : "+cs->GetErrorStatus()->Message()); return 0; } cs->SetAutoRender(false); iConsole::Display(iConsole::_Info,"Running the script..."); BatchModeObserver *obs = new BatchModeObserver(cs); cs->Execute(); if(obs != 0) delete obs; if(cs->GetErrorStatus()->IsError()) { iConsole::Display(iConsole::_HighError,iString("Runtime error in script, line ")+iString::FromNumber(cs->GetThisLine())+" : "+cs->GetErrorStatus()->Message()); } else iConsole::Display(iConsole::_Info,"Done."); tmp->Delete(); return 0; } } void iShell::Delete() { // // We are just about to start deleting objects. First thing we do is to block all // observers since we do not know at each moment in the deleting process which objects // are still present and which have been already deleted. // iEventObserver::BlockAllEventObservers(true); // // Check whether the error log was created by iConsole: // iOutputChannel::GetInstance()->NotifyIfLogCreated(); // // Go on rampage! // if(mScriptFileName.IsEmpty()) { this->DestructorBody(); } // // This ensures that control module is deleted before the shell is deleted. // mControlModule->Delete(); this->vtkObjectBase::Delete(); } void iShell::Run() { mRunning = true; this->RunBody(); mRunning = false; } void iShell::IgnoreCommandLineArgument(const iString &arg) { mIgnoredCommandLineArguments.Add(arg); } void iShell::AddCommandLineOption(const iString &root, bool hasValue, const iString &help) { Option tmp; tmp.Name = root; tmp.NeedsValue = hasValue; tmp.Help = help; mOptions.Add(tmp); } void iShell::ParseCommandLineOptions(int argc, char **argv) { int i, j; Option o; bool done; i = mFirstOption; while(i < argc) { // // Check if this word needs to be ignored // if(mIgnoredCommandLineArguments.Find(argv[i]) > -1) break; done = false; if(iString(argv[i]).Part(0,mOptionPrefix.Length()) == mOptionPrefix) { o.Name = argv[i] + mOptionPrefix.Length(); for(j=0; !done && j16384) return false; mNumProcs = n; return true; } if(o.Name == "i") { iString fn(o.Value); iDirectory::ExpandFileName(fn,this->GetEnvironment(Environment::Base)); if(iFile::IsReadable(fn)) { mStateFileName = fn; return true; } else { iConsole::Display(iConsole::_HighError,"File "+fn+" is not accessible.\nIFrIT will now exit."); exit(1); } } if(o.Name == "b") { iString fn (o.Value); iDirectory::ExpandFileName(fn,this->GetEnvironment(Environment::Base)); if(iFile::IsReadable(fn)) { mScriptFileName = fn; return true; } else { iConsole::Display(iConsole::_HighError,"File "+fn+" is not accessible.\nIFrIT will now exit."); exit(1); } } if(o.Name == "GPU") { iVolumeViewSubject::SetGPUMode(1); } if(o.Name == "no-GPU") { iVolumeViewSubject::SetGPUMode(-1); } return this->AnalyseOneExtendedCommandLineOption(o); } // // Environment querying // const iString& iShell::GetEnvironment(int key) const { static const iString none; switch(key) { case Environment::Base: { return mEnvBaseDir; } case Environment::Data: { return mEnvDataDir; } case Environment::Image: { return mEnvImageDir; } case Environment::Script: { return mEnvScriptDir; } case Environment::Palette: { return mEnvPaletteDir; } default: { return none; } } } bool iShell::HasStateFile() const { return !mStateFileName.IsEmpty(); } bool iShell::LoadShellStateFromFile(iFile &F) { if(mScriptFileName.IsEmpty()) { return this->LoadShellStateFromFileBody(F); } else return true; } bool iShell::SaveShellStateToFile(iFile &F) const { if(mScriptFileName.IsEmpty()) { return this->SaveShellStateToFileBody(F); } else return true; } void iShell::OnInitAtom() { mInitSteps[mCurInitStep].Current++; mInitTimer->StopTimer(); if(mInitTimer->GetElapsedTime() > 0.1) { mInitTimer->StartTimer(); this->OnInitAtomBody(true); } else { this->OnInitAtomBody(false); } } void iShell::OnInitAtomBody(bool) { } void iShell::OnLoadStateFileAtom(int prog) { this->OnLoadStateFileAtomBody(prog); } void iShell::OnLoadStateFileAtomBody(int) { } #ifdef I_DEBUG void iShell::InitHelper() { if(mInitSteps[mCurInitStep].Current != mInitSteps[mCurInitStep].Total) { int step = mCurInitStep; int total = mInitSteps[mCurInitStep].Current; int bp = 0; } } #endif #include #include #include #include #include #include #include #include #include #include #include namespace iShell_Private { void CheckSystem() { // // Check that sizes of basic types are correct // if(sizeof(int)!=4 || sizeof(float)!=4 || sizeof(double)!=8) { int sint = sizeof(int); int sflt = sizeof(float); int sdbl = sizeof(double); int sptr = sizeof(void*); int slng = sizeof(long); int svtk = sizeof(vtkIdType); int ssiz = sizeof(size_t); iConsole::Display(iConsole::_FatalError,"IFrIT has not been ported to this machine."); exit(0); } // // Check that vtkIdType can address a full pointer // if(sizeof(vtkIdType) < sizeof(void*)) { iConsole::Display(iConsole::_Notification,"This machine is "+iString::FromNumber(8*int(sizeof(void*)))+"-bit, but VTK has been compiled with "+iString::FromNumber(8*int(sizeof(vtkIdType)))+"-bit ids.\n" "IFrIT will not be able to use more than 2GB of memory per single array.\n" "Just letting you know.\n"); } if(sizeof(vtkIdType) > sizeof(void*)) { iConsole::Display(iConsole::_FatalError,"This machine is "+iString::FromNumber(8*int(sizeof(void*)))+"-bit, but VTK has been compiled with "+iString::FromNumber(8*int(sizeof(vtkIdType)))+"-bit ids.\n" "This configuration is inconsistent and is prone to crashes.\n" "Please recompile VTK with the advanced option VTK_USE_64BIT_IDS set to OFF.\n"); exit(0); } } float TestRenderingPerformance(vtkRenderer *ren) { // // Set up the timer // ren->GetActiveCamera()->SetPosition(0.0,0.0,1.0); ren->ResetCamera(); ren->GetRenderWindow()->Render(); vtkTimerLog *timer = vtkTimerLog::New(); timer->StartTimer(); int i; float r = 0; do { for(i=0; i<35; i++) { ren->GetActiveCamera()->Azimuth(9); ren->GetRenderWindow()->Render(); } for(i=0; i<35; i++) { ren->GetActiveCamera()->Elevation(9); ren->GetActiveCamera()->OrthogonalizeViewUp(); ren->GetRenderWindow()->Render(); } for(i=0; i<40; i++) { ren->GetActiveCamera()->Roll(9); ren->GetRenderWindow()->Render(); } for(i=0; i<5; i++) { ren->GetActiveCamera()->Elevation(9); ren->GetActiveCamera()->OrthogonalizeViewUp(); ren->GetRenderWindow()->Render(); } for(i=0; i<5; i++) { ren->GetActiveCamera()->Azimuth(9); ren->GetRenderWindow()->Render(); } timer->StopTimer(); r += 1; } while(timer->GetElapsedTime() < 3.0); r /= timer->GetElapsedTime(); timer->Delete(); return r; } void TestPerformance() { int i; const float renRateScale[2] = { 7.5f, 7.5f }; vtkRenderer *ren = vtkRenderer::New(); vtkRenderWindow *win = vtkRenderWindow::New(); win->AddRenderer(ren); ren->Delete(); vtkImageData *data = vtkImageData::New(); data->SetDimensions(17,17,17); data->SetSpacing(0.125,0.125,0.125); data->SetOrigin(-1.0,-1.0,-1.0); data->SetScalarTypeToUnsignedChar(); data->SetNumberOfScalarComponents(1); data->AllocateScalars(); unsigned char *ptr = (unsigned char *)data->GetScalarPointer(); for(i=0; iGetNumberOfPoints(); i++) { ptr[i] = i % 256; } vtkCubeSource *cube = vtkCubeSource::New(); cube->Update(); vtkGlyph3D *glyph = vtkGlyph3D::New(); glyph->SetScaleModeToDataScalingOff(); glyph->SetColorModeToColorByScalar(); glyph->SetScaleFactor(0.08); glyph->SetSource(cube->GetOutput()); glyph->SetInput(data); cube->Delete(); glyph->Update(); vtkPolyDataMapper *mapper = vtkPolyDataMapper::New(); vtkActor *actor = vtkActor::New(); mapper->ScalarVisibilityOn(); mapper->SetColorModeToMapScalars(); vtkLookupTable *lut = vtkLookupTable::New(); lut->SetRange(0.0,255.0); //lut->SetHueRange(0.0,255.0); mapper->SetLookupTable(lut); mapper->UseLookupTableScalarRangeOn(); lut->Delete(); actor->GetProperty()->SetColor(0.0,0.0,0.0); actor->SetMapper(mapper); mapper->Delete(); mapper->SetInput(glyph->GetOutput()); glyph->Delete(); ren->AddActor(actor); actor->Delete(); // // set the scene // win->SetSize(512,512); ren->SetBackground(1.0,1.0,1.0); // // draw the resulting scene // win->SetWindowName("IFrIT - Performance Test"); win->Render(); win->SetWindowName("IFrIT - Performance Test"); iString ws = "Rendering performance:\n\n"; float rr; actor->GetProperty()->SetOpacity(1.0); actor->GetProperty()->SetColor(0.0,0.0,1.0); rr = TestRenderingPerformance(ren)*renRateScale[0]; ws += "Opaque:\t\t " + iString::FromNumber(rr,"%.1f") + "\n"; actor->GetProperty()->SetOpacity(0.03); actor->GetProperty()->SetColor(1.0,0.0,0.0); rr = TestRenderingPerformance(ren)*renRateScale[1]; ws += "Transparent:\t " + iString::FromNumber(rr,"%.1f") + "\n"; ws += "\n"; ws += "Representative rangers for values:\n"; ws += "1-2\tLaptop with a chipset\n"; ws += "5-20\tDesktop with a low-end video card\n"; ws += "50-200\tWorkstation with a high-end video card\n\n"; ws += iString("VTK Version: ") + VTK_VERSION + "\n"; ws += "IFrIT Version: " + iVersion::GetVersion() + "\n"; #ifdef _WIN32 iConsole::Display(iConsole::_Notification,ws); #else iConsole::Display(iConsole::_Info,ws); #endif data->Delete(); win->RemoveRenderer(ren); win->Delete(); } }; ifrit-3.4.2/core/ishell.h0000755000175700010010000001223612167404421013573 0ustar HomeNone/*========================================================================= Program: Ionization FRont Interactive Tool (IFRIT) Language: C++ Copyright (c) 2002-2012 Nick Gnedin All rights reserved. This file may be distributed and/or modified under the terms of the GNU General Public License version 2 as published by the Free Software Foundation and appearing in the file LICENSE.GPL included in the packaging of this file. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHORS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. =========================================================================*/ // // A base class for all GUI shells around the VTK-based core // #ifndef ISHELL_H #define ISHELL_H #include #include "iarray.h" #include "istring.h" #include class iControlModule; class iFile; class vtkTimerLog; namespace iParameter { namespace Environment { const int Base = 0; const int Data = 1; const int Image = 2; const int Script = 3; const int Palette = 4; const int UniformScalarsData = 5; const int BasicParticlesData = 6; const int UniformVectorsData = 7; const int UniformTensorsData = 8; }; }; class iShell : public vtkObjectBase { public: struct Option { iString Name; iString Help; bool NeedsValue; iString Value; Option() { NeedsValue = false; } }; vtkTypeMacro(iShell,vtkObjectBase); // // A helper function that creates, runs, and deletes a shell in one call // static void RunApplication(const iString &type, int argc, char **argv); // // Create a shell with this function // static iShell* New(const iString &type = "", int argc = 0, char **argv = 0); // // This function does the shell's work after all the components are created. // void Run(); // // Exit from the current shell // virtual void Exit() = 0; // // Destroy the shell with this function // void Delete(); // // Access to components // inline const iString& Type() const { return mType; } inline iControlModule* GetControlModule() const { return mControlModule; } inline bool IsRunning() const { return mRunning; } const iString& GetEnvironment(int key) const; inline const iString& GetStateFileName() const { return mStateFileName; } bool LoadShellStateFromFile(iFile &F); bool SaveShellStateToFile(iFile &F) const; void OnInitAtom(); void OnLoadStateFileAtom(int prog); void IgnoreCommandLineArgument(const iString &arg); protected: iShell(const iString &type, int argc, char **argv); virtual ~iShell(); // // This functions parses command-line options. // void ParseCommandLineOptions(int argc, char **argv); void AddCommandLineOption(const iString &root, bool hasValue, const iString &help); bool AnalyseOneCommandLineOption(const struct Option &o); // // Because of cyclic dependence of different objects on each other, the constructor // and destructor functions of a child shell should be empty, and all constructor/destructor // work must be done in overwrites of the following two functions: // virtual void ConstructorBody() = 0; virtual void DestructorBody() = 0; // // These functions must be overwritten in a child class // virtual void Start() = 0; virtual void RunBody() = 0; // body of Run() virtual void PrepareForConstruction() = 0; virtual void PrepareToLoadStateFile() = 0; virtual bool LoadShellStateFromFileBody(iFile &F) = 0; virtual bool SaveShellStateToFileBody(iFile &F) const = 0; virtual void DefineSpecificCommandLineOptions() = 0; virtual bool AnalyseOneExtendedCommandLineOption(const struct Option &o) = 0; // // These functions can be used to animate the initialization/load state file progress. // Do nothing by default. // virtual void OnInitAtomBody(bool timed); virtual void OnLoadStateFileAtomBody(int prog); // // Useful helpers // bool HasStateFile() const; //inline iControlModule* ControlModule() const { return mControlModule; } private: iControlModule *mControlModule; bool mRunning; const iString mType; static const iString mOptionPrefix; iArray