diff --git a/.gitignore b/.gitignore index c4c1b9add1cca6fb92c973b33b29748e8c3a46a8..56410cfa551dd48078e87a6a355fa7eadf1823ab 100644 --- a/.gitignore +++ b/.gitignore @@ -12,6 +12,7 @@ CTestTestfile.cmake .* !.gitignore CMakeCache.txt +version.hh config.hh *.pyc index.txt diff --git a/CMakeLists.txt b/CMakeLists.txt index 12e52f7c6838493fb1e4ab528a3225f9b299f046..90755377da882c5c1d7c2e4b31134786a1df957c 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -4,13 +4,17 @@ cmake_minimum_required(VERSION 2.6.4 FATAL_ERROR) project(OpenStructure CXX C) +set (OST_VERSION_MAJOR 1) +set (OST_VERSION_MINOR 2) +set (OST_VERSION_PATCH 0) +set (OST_VERSION_STRING ${OST_VERSION_MAJOR}.${OST_VERSION_MINOR}.${OST_VERSION_PATCH} ) set(CMAKE_MODULE_PATH ${CMAKE_MODULE_PATH} ${PROJECT_SOURCE_DIR}/cmake_support) include(OST) option(USE_SHADER "whether to compile with shader support" OFF) -option(SET_RPATH "embed rpath upon make install" +option(USE_RPATH "embed rpath upon make install" OFF) option(COMPILE_TMTOOLS "whether to compile the tmalign and tmscore programs" OFF) @@ -30,8 +34,10 @@ option(ENABLE_SPNAV "whether 3DConnexion devices should be supported" OFF) option(STATIC_PROPERTY_WORKAROUND "workaround for static property bug with some boost/boost_python combinations" OFF) option(DEPLOYMENT "switch on deployment settings" OFF) -option(COMPILE_TESTS "wheter unit tests should be compiled by default" OFF) +option(COMPILE_TESTS "whether unit tests should be compiled by default" OFF) option(ENABLE_STATIC "whether static libraries should be compiled" OFF) +option(DEBIAN_STYLE_LIBEXEC "whether 'libexec' should be put under 'lib/openstructure" OFF) + if (CXX) set(CMAKE_CXX_COMPILER ${CXX}) endif() @@ -110,6 +116,12 @@ else() set(_PROFILE OFF) endif() +if (DEBIAN_STYLE_LIBEXEC) + set(_DEBIAN_STYLE_LIBEXEC ON) +else() + set(_DEBIAN_STYLE_LIBEXEC OFF) +endif() + add_definitions(-DEIGEN2_SUPPORT) if (COMPOUND_LIB) @@ -218,16 +230,17 @@ set_directory_properties(PROPERTIES ADDITIONAL_MAKE_CLEAN_FILES message(STATUS "OpenStructure will be built with the following options:\n" - " Install Prefix (-DPREFIX) : ${CMAKE_INSTALL_PREFIX}\n" - " RPath in install (-DUSE_RPATH) : ${_USE_RPATH}\n" - " Graphical interface (-DENABLE_GUI) : ${_UI}\n" - " OpenGL support (-DENABLE_GFX) : ${_OPENGL}\n" - " Image Processing support (-DENABLE_IMG) : ${_IMG}\n" - " Shader support (-DUSE_SHADER) : ${_SHADER}\n" - " Numpy support (-DUSE_NUMPY) : ${_NUMPY}\n" - " Optimize (-DOPTIMIZE) : ${_OPT}\n" - " Profiling support (-DPROFILE) : ${_PROFILE}\n" - " Double Precision (-DUSE_DOUBLE_PRECISION) : ${_DOUBLE_PREC}\n" - " Compound Lib (-DCOMPOUND_LIB) : ${_COMP_LIB}\n" - " TMAlign and TMScore (-DCOMPILE_TMTOOLS) : ${_TM_TOOLS}\n" - " Static Libraries (-DENABLE_STATIC) : ${ENABLE_STATIC}") + " Install Prefix (-DPREFIX) : ${CMAKE_INSTALL_PREFIX}\n" + " RPath in install (-DUSE_RPATH) : ${_USE_RPATH}\n" + " Graphical interface (-DENABLE_GUI) : ${_UI}\n" + " OpenGL support (-DENABLE_GFX) : ${_OPENGL}\n" + " Image Processing support (-DENABLE_IMG) : ${_IMG}\n" + " Shader support (-DUSE_SHADER) : ${_SHADER}\n" + " Numpy support (-DUSE_NUMPY) : ${_NUMPY}\n" + " Optimize (-DOPTIMIZE) : ${_OPT}\n" + " Profiling support (-DPROFILE) : ${_PROFILE}\n" + " Double Precision (-DUSE_DOUBLE_PRECISION) : ${_DOUBLE_PREC}\n" + " Compound Lib (-DCOMPOUND_LIB) : ${_COMP_LIB}\n" + " TMAlign and TMScore (-DCOMPILE_TMTOOLS) : ${_TM_TOOLS}\n" + " Static Libraries (-DENABLE_STATIC) : ${ENABLE_STATIC}\n" + " Debian-style 'libexec' (-DDEBIAN_STYLE_LIBEXEC) : ${_DEBIAN_STYLE_LIBEXEC}") \ No newline at end of file diff --git a/cmake_support/OST.cmake b/cmake_support/OST.cmake index f392eb87efd7054720015ac739ed908bec5c1571..297696f4ce0d1468309feed082bc96c68f0fa302 100644 --- a/cmake_support/OST.cmake +++ b/cmake_support/OST.cmake @@ -187,6 +187,9 @@ macro(module) get_target_property(_DEFS ${_LIB_NAME} COMPILE_DEFINITIONS) set_target_properties(${_LIB_NAME} PROPERTIES COMPILE_DEFINITIONS OST_MODULE_${_UPPER_LIB_NAME}) + set_target_properties(${_LIB_NAME} PROPERTIES + VERSION ${OST_VERSION_STRING} + SOVERSION ${OST_VERSION_MAJOR}.${OST_VERSION_MINOR}) set_target_properties(${_LIB_NAME} PROPERTIES LIBRARY_OUTPUT_DIRECTORY ${LIB_STAGE_PATH} ARCHIVE_OUTPUT_DIRECTORY ${LIB_STAGE_PATH} @@ -310,6 +313,40 @@ macro(executable) endmacro() +#------------------------------------------------------------------------------- +# Synopsis +# executable_libexec(NAME exe_name SOURCES source1 source2 LINK link1 link2) +# +# Description: +# Compile, link and stage a C++ executable into the libexec directory +#------------------------------------------------------------------------------- +macro(executable_libexec) + parse_argument_list(_ARG + "NAME;SOURCES;LINK;DEPENDS_ON" "NO_RPATH;STATIC" ${ARGN}) + if (NOT _ARG_NAME) + message(FATAL_ERROR "invalid use of executable(): a name must be provided") + endif() + add_executable(${_ARG_NAME} ${_ARG_SOURCES}) + set_target_properties(${_ARG_NAME} + PROPERTIES RUNTIME_OUTPUT_DIRECTORY + "${LIBEXEC_STAGE_PATH}") + if (APPLE AND NOT _ARG_NO_RPATH AND NOT _ARG_STATIC) + set_target_properties(${_ARG_NAME} PROPERTIES + LINK_FLAGS "-Wl,-rpath,@loader_path/../lib") + endif() + if (_ARG_LINK) + target_link_libraries(${_ARG_NAME} ${_ARG_LINK}) + endif() + if (ENABLE_STATIC AND _ARG_STATIC) + set(TARGET_SUFFIX _static) + target_link_libraries(${_ARG_NAME} ${STATIC_LIBRARIES}) + endif() + foreach(_DEP ${_ARG_DEPENDS_ON}) + target_link_libraries(${_ARG_NAME} ${_DEP}${TARGET_SUFFIX}) + endforeach() + install(TARGETS ${_ARG_NAME} DESTINATION ${LIBEXEC_PATH}) +endmacro() + #------------------------------------------------------------------------------- # Synopsis: # substitute(IN_FILE in_file OUT_FILE out_file DICT a=b c=d) @@ -583,7 +620,7 @@ macro(ost_unittest) endif() if (WIN32) target_link_libraries(${_test_name} ${BOOST_UNIT_TEST_LIBRARIES} "${_ARG_PREFIX}_${_ARG_MODULE}") - add_custom_target("${_test_name}_run" + add_custom_target("${_test_name}_run": COMMAND ${CMAKE_CURRENT_BINARY_DIR}/${CMAKE_BUILD_TYPE}/${_test_name}.exe || echo WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}/${CMAKE_BUILD_TYPE}/.. COMMENT "running checks for module ${_ARG_MODULE}" @@ -722,7 +759,6 @@ macro(setup_stage) set(STAGE_DIR "${CMAKE_BINARY_DIR}/stage") set(EXECUTABLE_OUTPUT_PATH ${STAGE_DIR}/bin ) set(HEADER_STAGE_PATH ${STAGE_DIR}/include ) - set(LIBEXEC_STAGE_PATH ${STAGE_DIR}/libexec/openstructure ) set(SHARED_DATA_PATH ${STAGE_DIR}/share/openstructure ) if (UNIX AND NOT APPLE) @@ -736,6 +772,16 @@ macro(setup_stage) set(LIB_DIR lib ) set(LIB_STAGE_PATH "${STAGE_DIR}/lib" ) endif() + if (_DEBIAN_STYLE_LIBEXEC) + set(LIBEXEC_PATH ${LIB_DIR}/openstructure/libexec ) + else() + set(LIBEXEC_PATH libexec/openstructure ) + endif() + if (_DEBIAN_STYLE_LIBEXEC) + set(LIBEXEC_STAGE_PATH ${LIB_STAGE_PATH}/openstructure/libexec ) + else() + set(LIBEXEC_STAGE_PATH ${STAGE_DIR}/libexec/openstructure ) + endif() include_directories("${HEADER_STAGE_PATH}") link_directories(${LIB_STAGE_PATH}) diff --git a/deployment/linux/README.txt b/deployment/linux/README.txt index 841009281b2e8f4b0cecec638baadc6305984263..2f1ab3010a1c0854b08e58e45337296f3fe4938a 100644 --- a/deployment/linux/README.txt +++ b/deployment/linux/README.txt @@ -4,13 +4,3 @@ HOW TO USE THE BUNDLE SCRIPTS: 2. Move to the <OpenStructure folder>/deployment/linux folder and start the create_bundle.py script using python 3. In <OpenStructure> you'll find a tar.gz file. That's the bundle! 4. If the process stops without completing, run the reset_repository.py script or delete the <OpenStructure Folder> and restart from scratch - - -HOW TO USE THE QMEAN BUNDLE SCRIPTS: - -1. Checkout a copy of the OpenStructure repository. -2. Check out a copy of the scratch repository in modules/scratch -3. Create a folder called ChemLib in the <OpenStructure Folder> and copy the compunds.chemlib file into it. -4. Move to the <OpenStructure folder>/deployment/linux folder and start the create_qmeqn_bundle.py script using python -3. In <OpenStructure> you'll find a tar.gz file. That's the bundle! -4. If the process stops without completing, run the reset_qmean_repository.py script or delete the <OpenStructure Folder> and restart from scratch \ No newline at end of file diff --git a/deployment/linux/create_bundle.py b/deployment/linux/create_bundle.py index dbb88bb70feaa46329922ba30e3efefaea0b89fb..3f04533f0c4d6c3f84e907a0f73099bdf5988929 100644 --- a/deployment/linux/create_bundle.py +++ b/deployment/linux/create_bundle.py @@ -12,7 +12,7 @@ if len(sys.argv) < 3: print 'usage: create_bundle.py additional_label system_python_version' sys.exit() -system_python_version=sys.argv[2] +system_python_version='python'+sys.argv[2] system_python_bin='/usr/bin/'+system_python_version system_python_libs='/usr/lib/'+system_python_version second_system_python_libs_flag=True @@ -43,28 +43,21 @@ date_pattern='%Y-%b-%d' build=datetime.date.today() directory_name='openstructure-linux-'+archstring+'-'+additional_label+'-'+str(build) print 'Hardcoding package python binary path in openstructure executables' -subprocess.call('mv scripts/ost.in scripts/ost.in.backup',shell=True,cwd='../../') -subprocess.call('sed "s/@PYTHON_BINARY@/\$DNG_ROOT\/bin\/'+python_bin_in_bundle+'/g" scripts/ost.in.backup > scripts/ost.in.prepreprepre',shell=True,cwd='../../') -subprocess.call('sed "s/\#export LD_LIBRARY_PATH/ export LD_LIBRARY_PATH/g" scripts/ost.in.prepreprepre > scripts/ost.in.preprepre',shell=True,cwd='../../') -subprocess.call('sed "s/\#export PYTHONHOME/ export PYTHONHOME/g" scripts/ost.in.preprepre > scripts/ost.in.prepre',shell=True,cwd='../../') -subprocess.call('sed "s/\#export PYTHONPATH/ export PYTHONPATH/g" scripts/ost.in.prepre > scripts/ost.in.pre',shell=True,cwd='../../') -subprocess.call('sed "s/\#export QT_PLUGIN_PATH/ export QT_PLUGIN_PATH/g" scripts/ost.in.pre > scripts/ost.in',shell=True,cwd='../../') -subprocess.call('mv scripts/dng.in scripts/dng.in.backup',shell=True,cwd='../../') -subprocess.call('sed "s/\#export LD_LIBRARY_PATH/ export LD_LIBRARY_PATH/g" scripts/dng.in.backup > scripts/dng.in.preprepre',shell=True,cwd='../../') -subprocess.call('sed "s/\#export PYTHONHOME/ export PYTHONHOME/g" scripts/dng.in.preprepre > scripts/dng.in.prepre',shell=True,cwd='../../') -subprocess.call('sed "s/\#export PYTHONPATH/ export PYTHONPATH/g" scripts/dng.in.prepre > scripts/dng.in.pre',shell=True,cwd='../../') -subprocess.call('sed "s/\#export QT_PLUGIN_PATH/ export QT_PLUGIN_PATH/g" scripts/dng.in.pre > scripts/dng.in',shell=True,cwd='../../') +subprocess.call('mv scripts/ost_config.in scripts/ost_config.in.backup',shell=True,cwd='../../') +subprocess.call('sed "s/@PYTHON_BINARY@/\$DNG_ROOT\/bin\/'+python_bin_in_bundle+'/g" scripts/ost_config.in.backup > scripts/ost_config.in.preprepre',shell=True,cwd='../../') +subprocess.call('sed "s/\#export PYTHONHOME/ export PYTHONHOME/g" scripts/ost_config.in.preprepre > scripts/ost_config.in.prepre',shell=True,cwd='../../') +subprocess.call('sed "s/\#export PYTHONPATH/ export PYTHONPATH/g" scripts/ost_config.in.prepre > scripts/ost_config.in.pre',shell=True,cwd='../../') +subprocess.call('sed "s/\#export QT_PLUGIN_PATH/ export QT_PLUGIN_PATH/g" scripts/ost_config.in.pre > scripts/ost_config.in',shell=True,cwd='../../') #print 'Downloading Chemlib dictionary' #subprocess.call('wget ftp://ftp.wwpdb.org/pub/pdb/data/monomers/components.cif', shell=True, cwd='../../') #print 'Compiling Openstructure' #subprocess.call('cmake ./ -DCMAKE_BUILD_TYPE=Release -DPREFIX='+directory_name+' -DBoost_COMPILER='+boost_string+'-DENABLE_IMG=OFF -DENABLE_UI=OFF -DENABLE_GFX=OFF', shell=True,cwd='../../') #subprocess.call('cmake ./ -DCMAKE_BUILD_TYPE=Release -DPREFIX='+directory_name+' s-DENABLE_IMG=OFF -DENABLE_UI=OFF -DENABLE_GFX=OFF', shell=True,cwd='../../') #subprocess.call('make -j5',shell=True,cwd='../../') -#print 'Converting Chemlib dictionary' -#subprocess.call('stage/bin/chemdict_tool create components.cif compounds.chemlib', shell=True, cwd='../../') -#print '\nStaging Chemlib dictionary' +##print 'Converting Chemlib dictionary' +##subprocess.call('stage/bin/chemdict_tool create components.cif compounds.chemlib', shell=True, cwd='../../') +print '\nStaging Chemlib dictionary' print 'Compiling Openstructure' -#subprocess.call('cmake ./ -DCMAKE_BUILD_TYPE=Release -DPREFIX='+directory_name+' -DBoost_COMPILER='+boost_string+' -DCOMPOUND_LIB=ChemLib/compounds.chemlib -DENABLE_IMG=ON -DENABLE_UI=ON -DENABLE_GFX=ON -DOPTIMIZE=ON',shell=True,cwd='../../') subprocess.call('cmake ./ -DCMAKE_BUILD_TYPE=Release -DPREFIX='+directory_name+' -DCOMPOUND_LIB=ChemLib/compounds.chemlib -DENABLE_IMG=ON -DENABLE_UI=ON -DENABLE_GFX=ON -DOPTIMIZE=ON',shell=True,cwd='../../') subprocess.call('make -j2',shell=True,cwd='../../') print 'Removing obsolete packages and package directory' @@ -73,13 +66,14 @@ print 'Creating new package directory' subprocess.call('mkdir '+directory_name,shell=True,cwd='../../') subprocess.call('mkdir '+directory_name+'/bin',shell=True,cwd='../../') print 'Copy python executable into stage for dependency detection' +print system_python_bin subprocess.call('cp '+system_python_bin+ ' stage/bin/python',shell=True,cwd='../../') print 'Copy python libraries into the stage for dependency detection' -subprocess.call('cp -pRL '+system_python_libs+' stage/'+libdir,shell=True,cwd='../../') -subprocess.call('rm -fr stage/'+libdir+'/'+system_python_version+'/dist-packages',shell=True,cwd='../../') +subprocess.call('cp -pRL '+system_python_libs+' stage/'+libdir+'/python',shell=True,cwd='../../') +subprocess.call('rm -fr stage/'+libdir+'/python/dist-packages',shell=True,cwd='../../') if second_system_python_libs_flag==True: - subprocess.call('cp -pRL '+second_system_python_libs+'/sip* stage/'+libdir+'/'+system_python_version,shell=True,cwd='../../') - subprocess.call('cp -pRL '+second_system_python_libs+'/PyQt* stage/'+libdir+'/'+system_python_version,shell=True,cwd='../../') + subprocess.call('cp -pRL '+second_system_python_libs+'/sip* stage/'+libdir+'/python/',shell=True,cwd='../../') + subprocess.call('cp -pRL '+second_system_python_libs+'/PyQt* stage/'+libdir+'/python/',shell=True,cwd='../../') print 'Creating new dependency list' so_list=[] walk_list=os.walk('../../stage') @@ -104,22 +98,21 @@ for entry in sorted_dep_list: exclude=True if exclude==False: filtered_dep_list.append(entry) +print 'Installing OpenStructure into package directory structure' +subprocess.call('make install',shell=True,cwd='../../') print 'Copy libraries in the package directory structure' -subprocess.call('mkdir '+directory_name+'/'+libdir,shell=True,cwd='../../') for entry in filtered_dep_list: subprocess.call('cp '+entry+' '+directory_name+'/'+libdir,shell=True,cwd='../../') print 'Copy python executable into package directory structure' subprocess.call('cp '+system_python_bin+ ' '+directory_name+'/bin/python',shell=True,cwd='../../') print 'Copy python libraries into package directory structure' -subprocess.call('cp -pRL '+system_python_libs+' '+directory_name+'/'+libdir,shell=True,cwd='../../') -subprocess.call('rm -fr '+directory_name+'/'+libdir+'/'+system_python_version+'/dist-packages',shell=True,cwd='../../') +subprocess.call('cp -pRL '+system_python_libs+' '+directory_name+'/'+libdir+'/python',shell=True,cwd='../../') +subprocess.call('rm -fr '+directory_name+'/'+libdir+'/python/dist-packages',shell=True,cwd='../../') if second_system_python_libs_flag==True: - subprocess.call('cp -pRL '+second_system_python_libs+'/sip* '+directory_name+'/'+libdir+'/'+system_python_version,shell=True,cwd='../../') - subprocess.call('cp -pRL '+second_system_python_libs+'/PyQt* '+directory_name+'/'+libdir+'/'+system_python_version,shell=True,cwd='../../') + subprocess.call('cp -pRL '+second_system_python_libs+'/sip* '+directory_name+'/'+libdir+'/python/',shell=True,cwd='../../') + subprocess.call('cp -pRL '+second_system_python_libs+'/PyQt* '+directory_name+'/'+libdir+'/python/',shell=True,cwd='../../') print 'Copy Qt 4 plugins into package directory structure' subprocess.call('cp -pRL '+qt4_plugins+' '+directory_name+'/bin/',shell=True,cwd='../../') -print 'Installing OpenStructure into package directory structure' -subprocess.call('make install',shell=True,cwd='../../') print 'Copying supplementary material into package directory structure' subprocess.call('cp -pRL stage/share/openstructure '+directory_name+'/share/',shell=True,cwd='../../') print 'Copying examples into package directory structure' @@ -140,11 +133,8 @@ print 'removing dokk and harmony examples from bundle' subprocess.call('rm -rf '+directory_name+'/share/openstructure/examples/code_fragments/dokk',shell=True,cwd='../../') subprocess.call('rm -rf '+directory_name+'/share/openstructure/examples/code_fragments/harmony',shell=True,cwd='../../') print 'De-hardcoding package python binary path from openstructure executables' -subprocess.call('rm scripts/ost.in',shell=True,cwd='../../') -subprocess.call('rm scripts/ost.in.pre*',shell=True,cwd='../../') -subprocess.call('rm scripts/dng.in',shell=True,cwd='../../') -subprocess.call('rm scripts/dng.in.pre*',shell=True,cwd='../../') -subprocess.call('mv scripts/ost.in.backup scripts/ost.in',shell=True,cwd='../../') -subprocess.call('mv scripts/dng.in.backup scripts/dng.in',shell=True,cwd='../../') +subprocess.call('rm scripts/ost_config.in',shell=True,cwd='../../') +subprocess.call('rm scripts/ost_config.in.pre*',shell=True,cwd='../../') +subprocess.call('mv scripts/ost_config.in.backup scripts/ost_config.in',shell=True,cwd='../../') subprocess.call('tar cfz '+directory_name+'.tgz '+directory_name,shell=True,cwd='../../') diff --git a/deployment/linux/create_qmean_bundle.py b/deployment/linux/create_qmean_bundle.py deleted file mode 100644 index e8743cb03106a2819475635a4353f5dcee39a1b0..0000000000000000000000000000000000000000 --- a/deployment/linux/create_qmean_bundle.py +++ /dev/null @@ -1,138 +0,0 @@ -import os -import shutil -import subprocess -import string -import sys - - -# custom parameters - -boost_string='\".so.1.40.0\"' -system_python_bin='/usr/bin/python2.6' -name_python_bin='python2.6' -system_python_libs='/usr/lib/python2.6' -second_system_python_libs_flag=True -second_system_python_libs='/usr/lib/pymodules/python2.6' -qt4_plugins='/usr/lib/qt4/plugins' -additional_label='ubuntu' -list_of_excluded_libraries=['ld-linux','libexpat','libgcc_s','libglib','cmov','libice','libSM','libX','libg','libGL.so','libfontconfig','libfreetype','libdrm','libxcb','libICE'] - -currdir=os.getcwd() -if currdir.find('deployment')==-1 or currdir.find('linux')==-1: - print '\n' - print 'ERROR: Please run this script from the deployment/linux directory' - print '\n' - sys.exit() -print '\n' -print 'WARNING: If this script does not run to completion, please run the reset_repository_qmean.py script before restarting' -print '\n' -print 'Detecting architecture and revision' -uname_output=subprocess.Popen('uname -a', shell=True, cwd='../../',stdout=subprocess.PIPE).stdout -uname_line=uname_output.readlines() -if uname_line[0].find('x86_64') !=-1: - libdir='lib64' - archstring='64bit' -else: - libdir='lib' - archstring='32bit' -svninfo_output=subprocess.Popen('svn info', shell=True, cwd='../../',stdout=subprocess.PIPE).stdout -svninfo_lines=svninfo_output.readlines() -svninfo_split=string.split(svninfo_lines[4]) -revstring=svninfo_split[1] -directory_name='qmean-'+archstring+'-'+additional_label+'-rev'+revstring -print 'Stripping subversion information to avoid accidental commit' -subprocess.call('rm -rf $(find . -name .svn)',shell=True,cwd='../../') -print 'Tweaking scripts for bundle use' -subprocess.call('mv scripts/ost.in scripts/ost.in.backup',shell=True,cwd='../../') -subprocess.call('sed "s/@PYTHON_BINARY@/\$DNG_ROOT\/bin\/'+name_python_bin+'/g" scripts/ost.in.backup > scripts/ost.in.preprepre',shell=True,cwd='../../') -subprocess.call('sed "s/\#export LD_LIBRARY_PATH/ export LD_LIBRARY_PATH/g" scripts/ost.in.prepreprepre > scripts/ost.in.preprepre',shell=True,cwd='../../') -subprocess.call('sed "s/\#export PYTHONHOME/ export PYTHONHOME/g" scripts/ost.in.preprepre > scripts/ost.in.prepre',shell=True,cwd='../../') -subprocess.call('sed "s/\#export PYTHONPATH/ export PYTHONPATH/g" scripts/ost.in.prepre > scripts/ost.in.pre',shell=True,cwd='../../') -subprocess.call('sed "s/\#export QT_PLUGIN_PATH/ export QT_PLUGIN_PATH/g" scripts/ost.in.pre > scripts/ost.in',shell=True,cwd='../../') -subprocess.call('mv modules/scratch/qmean/scripts/qmean.in modules/scratch/qmean/scripts/qmean.in.backup',shell=True,cwd='../../') -subprocess.call('sed "s/@PYTHON_BINARY@/\$DNG_ROOT\/bin\/'+name_python_bin+'/g" modules/scratch/qmean/scripts/qmean.in.backup > modules/scratch/qmean/scripts/qmean.in.prepreprepre',shell=True,cwd='../../') -subprocess.call('sed "s/\#export LD_LIBRARY_PATH/ export LD_LIBRARY_PATH/g" modules/scratch/qmean/scripts/qmean.in.prepreprepre > modules/scratch/qmean/scripts/qmean.in.preprepre',shell=True,cwd='../../') -subprocess.call('sed "s/\#export PYTHONHOME/ export PYTHONHOME/g" modules/scratch/qmean/scripts/qmean.in.preprepre > modules/scratch/qmean/scripts/qmean.in.prepre',shell=True,cwd='../../') -subprocess.call('sed "s/\#export PYTHONPATH/ export PYTHONPATH/g" modules/scratch/qmean/scripts/qmean.in.prepre > modules/scratch/qmean/scripts/qmean.in.pre',shell=True,cwd='../../') -subprocess.call('sed "s/\#export QT_PLUGIN_PATH/ export QT_PLUGIN_PATH/g" modules/scratch/qmean/scripts/qmean.in.pre > modules/scratch/qmean/scripts/qmean.in',shell=True,cwd='../../') -subprocess.call('mv scripts/dng.in scripts/dng.in.backup',shell=True,cwd='../../') -subprocess.call('sed "s/\#export LD_LIBRARY_PATH/ export LD_LIBRARY_PATH/g" scripts/dng.in.backup > scripts/dng.in.preprepre',shell=True,cwd='../../') -subprocess.call('sed "s/\#export PYTHONHOME/ export PYTHONHOME/g" scripts/dng.in.preprepre > scripts/dng.in.prepre',shell=True,cwd='../../') -subprocess.call('sed "s/\#export PYTHONPATH/ export PYTHONPATH/g" scripts/ost.in.prepre > scripts/ost.in.pre',shell=True,cwd='../../') -subprocess.call('sed "s/\#export QT_PLUGIN_PATH/ export QT_PLUGIN_PATH/g" scripts/dng.in.pre > scripts/dng.in',shell=True,cwd='../../') -print 'Downloading Chemlib dictionary' -subprocess.call('wget ftp://ftp.wwpdb.org/pub/pdb/data/monomers/components.cif', shell=True, cwd='../../') -print 'Compiling Openstructure/Qmean' -subprocess.call('cmake ./ -DCMAKE_BUILD_TYPE=Release -DPREFIX='+directory_name+' -DBoost_COMPILER='+boost_string+' -DONLY_QMEAN=ON -DENABLE_IMG=OFF -DENABLE_UI=OFF -DENABLE_GFX=OFF -DCOMPOUND_LIB=ChemLib/compounds.chemlib', shell=True,cwd='../../') -subprocess.call('make',shell=True,cwd='../../') -print 'Converting Chemlib dictionary' -subprocess.call('stage/bin/chemdict_tool create components.cif compounds.chemlib', shell=True, cwd='../../') -print '\nStaging Chemlib dictionary' -subprocess.call('cmake ./ -DCOMPOUND_LIB=compounds.chemlib',shell=True,cwd='../../') -subprocess.call('make',shell=True,cwd='../../') -print 'Removing obsolete packages and package directory' -subprocess.call('rm -fr qmean-*',shell=True,cwd='../../') -print 'Creating new package directory' -subprocess.call('mkdir '+directory_name,shell=True,cwd='../../') -subprocess.call('mkdir '+directory_name+'/bin',shell=True,cwd='../../') -so_list=[] -print 'Creating new dependency list' -walk_list=os.walk('../../stage') -for dir_entry in walk_list: - for file_entry in dir_entry[2]: - if file_entry.find('.so')==len(file_entry)-3 or file_entry=='gosty': - filepath=os.path.join(dir_entry[0],file_entry) - so_list.append(filepath) -dep_list=[] -for so_entry in so_list: - dep=subprocess.Popen('perl ./ldd-rec.pl '+so_entry,shell=True,stdout=subprocess.PIPE,cwd='./').stdout - dep_so_entry=dep.readlines() - for dep_entry in dep_so_entry: - dep_list.append(dep_entry[:-1]) -sorted_dep_list=sorted(list(set(dep_list))) -print 'Filtering system libraries from depenedency list' -filtered_dep_list=[] -for entry in sorted_dep_list: - exclude=False - for exclusion in list_of_excluded_libraries: - if entry.find(exclusion)!=-1: - exclude=True - if exclude==False: - filtered_dep_list.append(entry) -print 'Copy libraries in the package directory structure' -subprocess.call('mkdir '+directory_name+'/'+libdir,shell=True,cwd='../../') -for entry in filtered_dep_list: - subprocess.call('cp '+entry+' '+directory_name+'/'+libdir,shell=True,cwd='../../') -print 'Copy python executable into package directory structure' -subprocess.call('cp '+system_python_bin+ ' '+directory_name+'/bin',shell=True,cwd='../../') -print 'Copy python libraries into package directory structure' -subprocess.call('cp -pRL '+system_python_libs+' '+directory_name+'/'+libdir,shell=True,cwd='../../') -if second_system_python_libs_flag==True: - subprocess.call('cp -pRL '+second_system_python_libs+'/* '+directory_name+'/'+libdir+'/'+name_python_bin,shell=True,cwd='../../') -print 'Copy Qt 4 plugins into package directory structure' -subprocess.call('cp -pRL '+qt4_plugins+' '+directory_name+'/bin/',shell=True,cwd='../../') -print 'Installing OpenStructure into package directory structure' -subprocess.call('make install',shell=True,cwd='../../') -print 'Copy examples into package directory structure' -subprocess.call('cp -pRL examples '+directory_name+'/share/openstructure/',shell=True,cwd='../../') -print 'Removing headers from package directory structure' -subprocess.call('rm -fr '+directory_name+'/include',shell=True,cwd='../../') -print 'Copying supplementary material into package directory structure' -subprocess.call('cp -pRL stage/share/openstructure '+directory_name+'/share/',shell=True,cwd='../../') -print 'Copy qmean examples into package directory structure' -subprocess.call('cp -pRL modules/scratch/qmean/examples '+directory_name+'',shell=True,cwd='../../') -print 'Copy readme and license files into package directory structure' -subprocess.call('cp -pRL modules/scratch/qmean/LICENSE.txt '+directory_name+'',shell=True,cwd='../../') -subprocess.call('cp -pRL modules/scratch/qmean/README.txt '+directory_name+'',shell=True,cwd='../../') -print 'Resetting script to non-bundle versions' -subprocess.call('rm scripts/ost.in',shell=True,cwd='../../') -subprocess.call('rm scripts/ost.in.pre*',shell=True,cwd='../../') -subprocess.call('rm scripts/dng.in',shell=True,cwd='../../') -subprocess.call('rm modules/scratch/qmean/scripts/qmean.in',shell=True,cwd='../../') -subprocess.call('rm modules/scratch/qmean/scripts/qmean.in.pre*',shell=True,cwd='../../') -subprocess.call('rm scripts/dng.in.pre*',shell=True,cwd='../../') -subprocess.call('mv scripts/ost.in.backup scripts/ost.in',shell=True,cwd='../../') -subprocess.call('mv scripts/dng.in.backup scripts/dng.in',shell=True,cwd='../../') -subprocess.call('mv modules/scratch/qmean/scripts/qmean.in.backup modules/scratch/qmean/scripts/qmean.in',shell=True,cwd='../../') -subprocess.call('tar cfz '+directory_name+'.tgz '+directory_name,shell=True,cwd='../../') - diff --git a/deployment/linux/debian/README b/deployment/linux/debian/README new file mode 100644 index 0000000000000000000000000000000000000000..c3a5a886f2754202845d533c5399e6eeb416ae86 --- /dev/null +++ b/deployment/linux/debian/README @@ -0,0 +1,8 @@ +1. Checkout OpenStructure into a directory called strictly:'openstructure-<version>' (currently is 1.1d - 1.1 develop) +2. Remove all the .git* files and directories from the source +3. Create a compressed file with the source directory called strictly 'openstructure_<version>.orig.tar.gz' + (At the same level as the source directory) +4. Copy the 'debian' directory into the top level of the source directory +5. Go into the top level of the source directory +6. Build package with 'debuilder -uc -us' +7. You can find the built package at the same level as the source directory and the source zipped file diff --git a/deployment/linux/debian/debian/README.source b/deployment/linux/debian/debian/README.source new file mode 100644 index 0000000000000000000000000000000000000000..c6c09893537f7e95bd2a01b7fe343ed65798ecf3 --- /dev/null +++ b/deployment/linux/debian/debian/README.source @@ -0,0 +1,18 @@ +===============OPENSTRUCTURE molecular modelling framework =============== + + +OpenStructure is the next generation molecular modelling tailored at anybody + using 3D Structures or electron density maps. + +Please refer to www.openstructure.org for more information or try out + directly one of the binary packages available for download. + +Thank you for you interest and enjoy the straightforward way of handling +protein structure data! + +Please do not hesitate to contact us for feedback or troubleshooting: + +ost-users@maillist.unibas.ch + + +=============== The OpenStructure Team =================================== diff --git a/deployment/linux/debian/debian/changelog b/deployment/linux/debian/debian/changelog new file mode 100644 index 0000000000000000000000000000000000000000..9ecfb662316dd8c2d6a8e6ddcc17e4cf3573e526 --- /dev/null +++ b/deployment/linux/debian/debian/changelog @@ -0,0 +1,5 @@ +openstructure (1.1d-0ubuntu1) natty; urgency=low + + * Initial release + + -- Valerio Mariani <valerio.mariani@unibas.ch> Wed, 13 Jul 2011 15:41:35 +0200 diff --git a/deployment/linux/debian/debian/chemdict_tool.1 b/deployment/linux/debian/debian/chemdict_tool.1 new file mode 100644 index 0000000000000000000000000000000000000000..7cbb4e805d2f7e52bf0ae16701d208cc5946fff1 --- /dev/null +++ b/deployment/linux/debian/debian/chemdict_tool.1 @@ -0,0 +1,33 @@ +.\" DO NOT MODIFY THIS FILE! It was generated by help2man 1.38.4. +.TH CHEMDICT_TOOL: "1" "July 2011" "User Commands" +.SH NAME +chemdict_tool \- compound libary creation tool for OpenStructure +.SH SYNOPSIS +chemdict_tool action <compound\-dict> <db> (pdb|charmm|amber|opls) +.SH OPTIONS +Supported actions are: +.TP +create +\- creates a new db +.TP +update +\- update existing db +.SS "supported actions are:" +.TP +create +\- creates a new db +.TP +update +\- update existing db +.SH "SEE ALSO" +The full documentation for +.B usage: +is maintained as a Texinfo manual. If the +.B info +and +.B usage: +programs are properly installed at your site, the command +.IP +.B info usage: +.PP +should give you access to the complete manual. diff --git a/deployment/linux/debian/debian/compat b/deployment/linux/debian/debian/compat new file mode 100644 index 0000000000000000000000000000000000000000..7f8f011eb73d6043d2e6db9d2c101195ae2801f2 --- /dev/null +++ b/deployment/linux/debian/debian/compat @@ -0,0 +1 @@ +7 diff --git a/deployment/linux/debian/debian/control b/deployment/linux/debian/debian/control new file mode 100644 index 0000000000000000000000000000000000000000..43a9f02fdda663dcf358819cf3bb92381c501311 --- /dev/null +++ b/deployment/linux/debian/debian/control @@ -0,0 +1,23 @@ +Source: openstructure +Section: science +Priority: extra +Maintainer: Valerio Mariani <valerio.mariani@unibas.ch> +Build-Depends: debhelper (>= 7.0.50~),cmake,desktop-file-utils,libboost-all-dev,libeigen2-dev,qt4-dev-tools,libqt4-dev,libqt4-opengl-dev,python-qt4-dev,pyqt4-dev-tools,libfftw3-dev,libpng12-dev,libtiff4-dev,python-dev +Standards-Version: 3.9.1 +Homepage: http://www.openstructure.org + +Package: openstructure +Architecture: any +Depends: ${shlibs:Depends}, ${misc:Depends}, python-sip, python-qt4 +Description: Open-source computational structural biology framework + The Openstructure project aims to provide an open-source, modular, flexible, + molecular modelling and visualization environment. It is targeted at + interested method developers in the field of structural bioinformatics. + +Package: openstructure-dev +Architecture: any +Depends: ${shlibs:Depends}, ${misc:Depends}, openstructure +Description: Open-source computational structural biology framework + The Openstructure project aims to provide an open-source, modular, flexible, + molecular modelling and visualization environment. It is targeted at + interested method developers in the field of structural bioinformatics. diff --git a/deployment/linux/debian/debian/copyright b/deployment/linux/debian/debian/copyright new file mode 100644 index 0000000000000000000000000000000000000000..b93d7503fb504646b3023bcc25817335d2579868 --- /dev/null +++ b/deployment/linux/debian/debian/copyright @@ -0,0 +1,40 @@ +Format: http://dep.debian.net/deps/dep5 +Upstream-Name: openstructure +Source: http://www.openstructure.org + +Files: * +Copyright: 2008-2011 Torsten Schwede <torsten.schwede@unibas.ch> +License: LGPL-3.0 + +Files: debian/* +Copyright: 2011 Valerio Mariani <valerio.mariani@unibas.ch> +License: LGPL-3.0 + +License: LGPL-3.0 + This package is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 3 of the License, or (at your option) any later version. + . + This package is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + . + You should have received a copy of the GNU General Public License + along with this program. If not, see <http://www.gnu.org/licenses/>. + . + On Debian systems, the complete text of the GNU Lesser General + Public License can be found in "/usr/share/common-licenses/LGPL-3". + +Files: modules/db/src/sqlite3.h, modules/db/src/sqlite.c +Copyright: 2011 Valerio Mariani <valerio.mariani@unibas.ch> +License: None + 2001 September 15 + . + The author disclaims copyright to this source code. In place of + a legal notice, here is a blessing: + . + May you do good and not evil. + May you find forgiveness for yourself and forgive others. + May you share freely, never taking more than you give. diff --git a/deployment/linux/debian/debian/dng.1 b/deployment/linux/debian/debian/dng.1 new file mode 100644 index 0000000000000000000000000000000000000000..dbc68330d425affad81420e25645719ac07c8b24 --- /dev/null +++ b/deployment/linux/debian/debian/dng.1 @@ -0,0 +1,39 @@ +.\" DO NOT MODIFY THIS FILE! It was generated by help2man 1.38.4. +.TH DNG "1" "July 2011" "User Commands" +.SH NAME +dng \- GUI for OpenStructure +.SH SYNOPSIS +.B dng +[\fIoptions\fR] [\fIfiles to load\fR] +.SH OPTIONS +.TP +\fB\-h\fR, \fB\-\-help\fR +show this help message and exit +.TP +\fB\-v\fR VLEVEL, \fB\-\-verbosity_level\fR=\fIVLEVEL\fR +sets the verbosity level [default: 2] +.TP +\fB\-s\fR SCRIPT, \fB\-\-script\fR=\fISCRIPT\fR +executes a script (syntax: \fB\-s\fR SCRIPT [options] [args]) +Anything that follows this option is passed to the +script +.TP +\fB\-p\fR PDB_IDS, \fB\-\-pdb_id\fR=\fIPDB_IDS\fR +PDB file ID. The file will be retrieved from PDB +.TP +\fB\-b\fR BUILDER, \fB\-\-builder\fR=\fIBUILDER\fR +Type of builder used by the progam (either RULE_BASED +or HEURISTIC) [default: HEURISTIC] +.TP +\fB\-c\fR COMPLIB, \fB\-\-compound_library\fR=\fICOMPLIB\fR +Compound library for the RULE_BASED builder (only used +if \fB\-\-builder\fR option is set to RULE_BASED, otherwise +ignored [default: compounds.chemlib] +.TP +\fB\-q\fR QUERY, \fB\-\-query\fR=\fIQUERY\fR +Selection query to be highlighted automatically upon +loading (only used together with \fB\-p\fR option or when a +PDB file is loaded, otherwise ignored [default: None] +.TP +\fB\-S\fR, \fB\-\-stereo\fR +try to get a quad\-buffer stereo visual diff --git a/deployment/linux/debian/debian/openstructure.desktop b/deployment/linux/debian/debian/openstructure.desktop new file mode 100644 index 0000000000000000000000000000000000000000..b5ae761af421073b92e3ce58fa0c5100417a3ae8 --- /dev/null +++ b/deployment/linux/debian/debian/openstructure.desktop @@ -0,0 +1,8 @@ +[Desktop Entry] +Name=OpenStructure +GenericName=Open-Source Computational Structural Biology Framework +Exec=dng +Icon=openstructure +Terminal=false +Type=Application +Categories=Education;Science; diff --git a/deployment/linux/debian/debian/openstructure.manpages b/deployment/linux/debian/debian/openstructure.manpages new file mode 100644 index 0000000000000000000000000000000000000000..e73d09dbbec1bf1adaed4065f926ecbe8e872771 --- /dev/null +++ b/deployment/linux/debian/debian/openstructure.manpages @@ -0,0 +1,3 @@ +debian/ost.1 +debian/dng.1 +debian/chemdict_tool.1 diff --git a/deployment/linux/debian/debian/ost.1 b/deployment/linux/debian/debian/ost.1 new file mode 100644 index 0000000000000000000000000000000000000000..afd5f75dcb8eadc27a09ecacb147138c3451ac7a --- /dev/null +++ b/deployment/linux/debian/debian/ost.1 @@ -0,0 +1,18 @@ +.\" DO NOT MODIFY THIS FILE! It was generated by help2man 1.38.4. +.TH OST "1" "July 2011" "User Commands" +.SH NAME +ost: \- command-line console for OpenStructure +.SH SYNOPSIS +.B ost +[\fIost options\fR] [\fIscript to execute\fR] [\fIscript parameters\fR] +.SH OPTIONS +.TP +\fB\-i\fR, \fB\-\-interactive\fR +start interpreter interactively (must be first +parameter, ignored otherwise) +.TP +\fB\-h\fR, \fB\-\-help\fR +show this help message and exit +.TP +\fB\-v\fR VLEVEL, \fB\-\-verbosity_level\fR=\fIVLEVEL\fR +sets the verbosity level [default: 2] diff --git a/deployment/linux/debian/debian/postinst b/deployment/linux/debian/debian/postinst new file mode 100644 index 0000000000000000000000000000000000000000..a448189622f2efd26b94eb33f2759706a6d7bdbd --- /dev/null +++ b/deployment/linux/debian/debian/postinst @@ -0,0 +1,40 @@ +#!/bin/sh +# postinst script for openstructure +# +# see: dh_installdeb(1) + +set -e + +# summary of how this script can be called: +# * <postinst> `configure' <most-recently-configured-version> +# * <old-postinst> `abort-upgrade' <new version> +# * <conflictor's-postinst> `abort-remove' `in-favour' <package> +# <new-version> +# * <postinst> `abort-remove' +# * <deconfigured's-postinst> `abort-deconfigure' `in-favour' +# <failed-install-package> <version> `removing' +# <conflicting-package> <version> +# for details, see http://www.debian.org/doc/debian-policy/ or +# the debian-policy package + + +case "$1" in + configure) + ldconfig + ;; + + abort-upgrade|abort-remove|abort-deconfigure) + ;; + + *) + echo "postinst called with unknown argument \`$1'" >&2 + exit 1 + ;; +esac + +# dh_installdeb will replace this with shell code automatically +# generated by other debhelper scripts. + +#DEBHELPER# + +exit 0 diff --git a/deployment/linux/debian/debian/rules b/deployment/linux/debian/debian/rules new file mode 100755 index 0000000000000000000000000000000000000000..7b9d18ba98b725099155c5f3d87a78f20e2cba5c --- /dev/null +++ b/deployment/linux/debian/debian/rules @@ -0,0 +1,27 @@ +#!/usr/bin/make -f +# -*- makefile -*- +# Sample debian/rules that uses debhelper. +# This file was originally written by Joey Hess and Craig Small. +# As a special exception, when this file is copied by dh-make into a +# dh-make output file, you may use that output file without restriction. +# This special exception was added by Craig Small in version 0.37 of dh-make. + +# Uncomment this to turn on verbose mode. +export DH_VERBOSE=1 + +%: + dh $@ --buildsystem cmake +override_dh_auto_configure: + cmake ./ -DPREFIX=debian/openstructure/usr -DOPTIMIZE=ON -DCOMPOUND_LIB=compounds.chemlib +override_dh_auto_build: + make -j6 +override_dh_auto_install: + make install + rm debian/openstructure/usr/bin/ldt + mkdir -p debian/openstructure-dev/usr + mv debian/openstructure/usr/include debian/openstructure-dev/usr/ + mkdir -p debian/openstructure/usr/share/pixmaps/ + cp modules/gui/share/images/logo-small.png debian/openstructure/usr/share/pixmaps/openstructure.png + mkdir -p debian/openstructure/usr/share/applications/ + cp debian/openstructure.desktop debian/openstructure/usr/share/applications/ + desktop-file-validate debian/openstructure/usr/share/applications/openstructure.desktop diff --git a/deployment/linux/debian/debian/source/format b/deployment/linux/debian/debian/source/format new file mode 100644 index 0000000000000000000000000000000000000000..c3d9f2407417795889250717d7b519eadd8373e6 --- /dev/null +++ b/deployment/linux/debian/debian/source/format @@ -0,0 +1,2 @@ +3.0 (quilt) + diff --git a/deployment/linux/debian/debian/source/include-binaries b/deployment/linux/debian/debian/source/include-binaries new file mode 100644 index 0000000000000000000000000000000000000000..e2a64033aea5f1dda66b509afe7ee03c8d40095e --- /dev/null +++ b/deployment/linux/debian/debian/source/include-binaries @@ -0,0 +1 @@ +compounds.chemlib diff --git a/deployment/linux/fedora/openstructure.desktop b/deployment/linux/fedora/openstructure.desktop new file mode 100644 index 0000000000000000000000000000000000000000..5da5cfab6fa466c91de1e5be5cf5073448ad72dd --- /dev/null +++ b/deployment/linux/fedora/openstructure.desktop @@ -0,0 +1,8 @@ +[Desktop Entry] +Name=OpenStructure +GenericName=Open-Source Computational Structural Biology Framework +Exec=dng +Icon=openstructure +Terminal=false +Type=Application +Categories=Science; diff --git a/deployment/linux/fedora/openstructure.spec b/deployment/linux/fedora/openstructure.spec new file mode 100644 index 0000000000000000000000000000000000000000..3d27b5deac2b8e299e1ab1406900a722347866be --- /dev/null +++ b/deployment/linux/fedora/openstructure.spec @@ -0,0 +1,82 @@ +Name: openstructure +Version: 1.1 +Release: 0.1d%{?dist} +Summary: Open-source computational structural biology framework + + +# The entire source code is LGPLv3 except the following files: +# modules/db/src/sqlite3.h, modules/db/src/sqlite.c +# which have no license +License: LGPLv3 and unlicensed +URL: www.openstructure.org +# The source for this package was pulled from upstream's git. Use the +# following commands to generate the tarball: +# git clone https://dng.biozentrum.unibas.ch/git/ost.git openstructure-1.1d +# cp /import/bc2/home/schwede/GROUP/OpenStructure/compounds.chemlib \ +# openstructure-1.1d/ +# tar -cJvf openstructure-1.1d.tar.xz openstructure-1.1d +Source0: %{name}-%{version}d.tar.xz +Source1: %{name}.desktop + +BuildRequires: boost-devel,fftw-devel,eigen2-devel,libtiff-devel,libpng-devel,sip-devel,PyQt4-devel,cmake,desktop-file-utils +Requires: sip,PyQt4 + +%description +The Openstructure project aims to provide an open-source, modular, flexible, +molecular modelling and visualization environment. It is targeted at +interested method developers in the field of structural bioinformatics. + +%prep +%setup -n openstructure-1.1d + +%build +%cmake . -DPREFIX=%{buildroot}/usr -DOPTIMIZE=ON -DCOMPOUND_LIB=compounds.chemlib +make %{?_smp_mflags} + +%install +rm -rf %{buildroot} +make install +mkdir -p %{buildroot}/%{_defaultdocdir}/%{name}-%{version} +mkdir -p %{buildroot}/%{_datadir}/pixmaps +cp LICENSE.txt %{buildroot}/%{_defaultdocdir}/%{name}-%{version}/ +cp ReadMe.txt %{buildroot}/%{_defaultdocdir}/%{name}-%{version}/ +cp modules/gui/share/images/logo-small.png %{buildroot}/%{_datadir}/pixmaps/openstructure.png +rm %{buildroot}/%{_bindir}/ldt +desktop-file-install --dir=%{buildroot}/%{_datadir}/applications %{SOURCE1} + +%post -p /sbin/ldconfig + +%postun -p /sbin/ldconfig + +%files +%defattr(-,root,root,-) +%{_bindir}/* +%{_libdir}/libost* +%{_libdir}/openstructure +%{_datadir}/openstructure +%{_datadir}/applications/* +%{_datadir}/pixmaps/* + +%doc +%{_defaultdocdir}/%{name}-%{version}/LICENSE.txt +%{_defaultdocdir}/%{name}-%{version}/ReadMe.txt + +%changelog +* Wed Jul 20 2011 Valerio Mariani <valerio.mariani@unibas.ch> 1.1-1d +- Initial release + + + + +%package devel +Summary: Open-source computational structural biology framework +Requires: openstructure + +%description devel +The Openstructure project aims to provide an open-source, modular, flexible, +molecular modelling and visualization environment. It is targeted at +interested method developers in the field of structural bioinformatics. + +%files devel +%{_includedir}/* + diff --git a/deployment/linux/reset_repository.py b/deployment/linux/reset_repository.py index bf030685da06e5b319b0af7964b7c3bec0948f82..6ac0809e34a767ff7ff16febd6d392b95e31861f 100644 --- a/deployment/linux/reset_repository.py +++ b/deployment/linux/reset_repository.py @@ -8,7 +8,6 @@ if currdir.find('deployment')==-1 or currdir.find('linux')==-1: print '\n' sys.exit() -subprocess.call('rm -fr scripts/dng.in.pre* scripts/ost_cl.in.pre*',shell=True,cwd='../../') -subprocess.call('mv scripts/ost.in.backup scripts/ost.in',shell=True,cwd='../../') -subprocess.call('mv scripts/dng.in.backup scripts/dng.in',shell=True,cwd='../../') +subprocess.call('rm -fr scripts/ost_config.in.pre*',shell=True,cwd='../../') +subprocess.call('mv scripts/ost_config.in.backup scripts/ost_config.in',shell=True,cwd='../../') diff --git a/deployment/linux/reset_repository_qmean.py b/deployment/linux/reset_repository_qmean.py deleted file mode 100644 index 93ab7c531ababb26dcb0daaf06332b69ccb71965..0000000000000000000000000000000000000000 --- a/deployment/linux/reset_repository_qmean.py +++ /dev/null @@ -1,14 +0,0 @@ -import subprocess -import os - -currdir=os.getcwd() -if currdir.find('deployment')==-1 or currdir.find('linux')==-1: - print '\n' - print 'ERROR: Please run this script from the deployment/linux directory' - print '\n' - sys.exit() - -subprocess.call('rm -fr scripts/dng.in.pre* scripts/ost_cl.in.pre* modules/scratch/qmean/scripts/qmean.in.pre*',shell=True,cwd='../../') -subprocess.call('mv scripts/ost.in.backup scripts/ost.in',shell=True,cwd='../../') -subprocess.call('mv scripts/dng.in.backup scripts/dng.in',shell=True,cwd='../../') -subprocess.call('mv modules/scratch/qmean/scripts/qmean.in.backup scripts/dng.in modules/scratch/qmean/scripts/qmean.in',shell=True,cwd='../../') \ No newline at end of file diff --git a/modules/base/pymod/wrap_base.cc b/modules/base/pymod/wrap_base.cc index 1c305685bba1800c9f4b10d0efc42dcd5707b526..40ad33717f79c38e58c21624b87736f387016f3c 100644 --- a/modules/base/pymod/wrap_base.cc +++ b/modules/base/pymod/wrap_base.cc @@ -91,6 +91,7 @@ BOOST_PYTHON_MODULE(_ost_base) scope().attr("VERSION_MAJOR")=OST_VERSION_MAJOR; scope().attr("VERSION_MINOR")=OST_VERSION_MINOR; scope().attr("VERSION_PATCH")=OST_VERSION_PATCH; + scope().attr("WITH_NUMPY")= OST_NUMPY_SUPPORT_ENABLED; export_Logger(); export_Range(); export_Units(); diff --git a/modules/config/CMakeLists.txt b/modules/config/CMakeLists.txt index 65c9ca6bebf69a4def544c5c58dfc50be04ee98d..617aa51c5b87a2dc03b95d7a92730b097b31d371 100644 --- a/modules/config/CMakeLists.txt +++ b/modules/config/CMakeLists.txt @@ -1,3 +1,6 @@ +set(SUBST_DICT OST_VERSION_MAJOR=${OST_VERSION_MAJOR} OST_VERSION_MINOR=${OST_VERSION_MINOR} + OST_VERSION_PATCH=${OST_VERSION_PATCH}) + set(OST_CONFIG_HEADERS base.hh config.hh @@ -54,10 +57,17 @@ if (FFTW_USE_THREADS) else() set(fftw_use_threads 0) endif() +if (_DEBIAN_STYLE_LIBEXEC) + set(debian_style_libexec 1) +else() + set(debian_style_libexec 0) +endif() set(config_hh_generator "CMake") set(CONFIG_HH_FILE "${CMAKE_CURRENT_SOURCE_DIR}/config.hh") +set(VERSION_HH_FILE "${CMAKE_CURRENT_SOURCE_DIR}/version.hh") configure_file(config.hh.in ${CONFIG_HH_FILE}) +configure_file(version.hh.in ${VERSION_HH_FILE}) add_custom_target(ost_config) stage_headers("${OST_CONFIG_HEADERS}" "ost" "ost_config" "" "ost") diff --git a/modules/config/config.hh.in b/modules/config/config.hh.in index 88653c1e8df5bc5f75bf99dd6554c5a25c5ffaa6..a9e33adca707baed39710d3c75f63ca2b210bf0b 100644 --- a/modules/config/config.hh.in +++ b/modules/config/config.hh.in @@ -32,4 +32,6 @@ #define OST_SPNAV_ENABLED @spnav_enabled@ #define OST_FFT_USE_THREADS @fftw_use_threads@ #define OST_NUMPY_SUPPORT_ENABLED @numpy_support@ +#define OST_DEBIAN_STYLE_LIBEXEC @debian_style_libexec@ + #endif diff --git a/modules/config/version.hh b/modules/config/version.hh.in similarity index 85% rename from modules/config/version.hh rename to modules/config/version.hh.in index c2c019aed425009563f897d8c8ea9bd9e16a62f9..94948475f862b2876ccdd459638f8c781735f784 100644 --- a/modules/config/version.hh +++ b/modules/config/version.hh.in @@ -19,9 +19,9 @@ #ifndef OST_VERSION_HH_ #define OST_VERSION_HH_ -#define OST_VERSION_MAJOR 1 -#define OST_VERSION_MINOR 2 -#define OST_VERSION_PATCH 0 -#define OST_VERSION_STRING "1.2.0" +#define OST_VERSION_MAJOR @OST_VERSION_MAJOR@ +#define OST_VERSION_MINOR @OST_VERSION_MINOR@ +#define OST_VERSION_PATCH @OST_VERSION_PATCH@ +#define OST_VERSION_STRING "@OST_VERSION_STRING@" #endif /* OST_VERSION_HH_ */ diff --git a/modules/conop/doc/cleanup.rst b/modules/conop/doc/cleanup.rst new file mode 100644 index 0000000000000000000000000000000000000000..35b20e5705b248a995ec61c5e06604c53df0767f --- /dev/null +++ b/modules/conop/doc/cleanup.rst @@ -0,0 +1,8 @@ +:mod:`conop.cleanup <ost.conop.cleanup>` -- Sanitize structures +================================================================================ + +.. module:: ost.conop.ceanup + :synopsis: Contains functions to sanitize (cleanup) structures by using + information from the compound library. + +.. autofunction:: ost.conop.cleanup.Cleanup \ No newline at end of file diff --git a/modules/conop/doc/conop.rst b/modules/conop/doc/conop.rst index 8c3f413469872a1d95f9da98e37f4e21ffb24bfc..fb72db2645a92ea70f3db4f686c0f33a35c7e956 100644 --- a/modules/conop/doc/conop.rst +++ b/modules/conop/doc/conop.rst @@ -20,3 +20,4 @@ In this module aminoacid connectivity compoundlib + cleanup \ No newline at end of file diff --git a/modules/conop/pymod/CMakeLists.txt b/modules/conop/pymod/CMakeLists.txt index 5affa4b457d780b7368b34a097bec832d2c3f36c..97de72d7a52f1a74233a9782e746bd596620ffc7 100644 --- a/modules/conop/pymod/CMakeLists.txt +++ b/modules/conop/pymod/CMakeLists.txt @@ -7,4 +7,4 @@ set(OST_CONOP_PYMOD_SOURCES export_ring_finder.cc ) -pymod(NAME conop CPP ${OST_CONOP_PYMOD_SOURCES} PY __init__.py) \ No newline at end of file +pymod(NAME conop CPP ${OST_CONOP_PYMOD_SOURCES} PY __init__.py cleanup.py) diff --git a/modules/conop/pymod/__init__.py b/modules/conop/pymod/__init__.py index 44aaed354facbf286933d5e2ff19dd89bf7544e1..a534ea808bf883c616c7eb7165af5b71155fdc5b 100644 --- a/modules/conop/pymod/__init__.py +++ b/modules/conop/pymod/__init__.py @@ -18,6 +18,17 @@ #------------------------------------------------------------------------------ from _ost_conop import * +# The 20 standard amino acids in no particular order +STANDARD_AMINOACIDS=( + 'ALA', 'ARG', 'ASN', + 'ASP', 'GLN', 'GLU', + 'LYS', 'SER', 'CYS', + 'MET', 'TRP', 'TYR', + 'THR', 'VAL', 'ILE', + 'LEU', 'GLY', 'PRO', + 'HIS', 'PHE', +) + def ConnectAll(ent): ''' Uses the current default builder to connect the atoms of the entity, assign diff --git a/modules/conop/pymod/cleanup.py b/modules/conop/pymod/cleanup.py new file mode 100644 index 0000000000000000000000000000000000000000..9ecf9c7ef12b8bb4fce889a5fb8062aab2364eda --- /dev/null +++ b/modules/conop/pymod/cleanup.py @@ -0,0 +1,167 @@ +from ost import conop, mol + +def Cleanup(entity, strip_water=True, canonicalize=True, remove_ligands=True): + """ + This function returns a cleaned-up (simplified) version of the protein + structure. Different parameters affect the behaviour of the function. + + :param strip_water: Whether to remove water from the structure + :param canonicalize: Whether to strip off modifications of amino acids and map + them back to their parent standard amino acid, e.g. selenium methionine to + methionine.For more complex amino acids, where the relation between the + modified and the standard parent amino acid is not known, sidechain atoms + are removed. D-peptide-linking residues are completely removed as well. + :param remove_ligands: Whether to remove ligands from the structure + + :return: a cleaned version of the entity + """ + #setup + builder = conop.GetBuilder() + if not hasattr(builder, "compound_lib") : + raise RuntimeError( "Cannot cleanup structure, since the default builder doesn't use the compound library") + compound_lib = builder.compound_lib + clean_entity = entity.Copy() + ed = clean_entity.EditXCS() + #remove water residues + if strip_water: + _StripWater(clean_entity, ed) + #replace modified residues before removing ligands to avoid removing MSE and others + if canonicalize: + _CanonicalizeResidues(clean_entity, ed, compound_lib) + #remove all hetatoms that are not water + if remove_ligands: + _RemoveLigands(clean_entity, ed) + return clean_entity + + +def _StripWater(clean_entity, ed) : + """ + This function removes water residues from the structure + """ + for res in clean_entity.residues: + if res.IsValid(): + if res.chem_class == mol.WATER: + ed.DeleteResidue(res.handle) + ed.UpdateICS() + return + +def _RemoveLigands(clean_entity, ed) : + """ + This function removes ligands from the structure + """ + for res in clean_entity.residues: + if res.IsValid(): + #WHEN mmCIF WILL BE USED, CHANGE IsPeptideLinking() TO IsProtein() + if not res.IsPeptideLinking() and res.atoms[0].is_hetatom and res.chem_class != mol.WATER: + ed.DeleteResidue(res.handle) + ed.UpdateICS() + return + +def _CanonicalizeResidues(clean_entity, ed, compound_lib) : + """ + This function strips off modifications of amino acids and maps + them back to their parent standard amino acid, e.g. selenium methionine to + methionine.For more complex amino acids, where the relation between the + modified and the standard parent amino acid is not known, sidechain atoms + are removed. D-peptide-linking residues are completely removed as well. + """ + + for res in clean_entity.residues: + if res.IsValid() and res.IsPeptideLinking() : + parent_olc = res.one_letter_code + if parent_olc == "X" : + _DeleteSidechain(res, ed) + for atom in res.atoms: + atom.is_hetatom = False + else: + parent_tlc = conop.OneLetterCodeToResidueName(parent_olc) + parent_res = compound_lib.FindCompound(parent_tlc) + if not parent_res: + _DeleteSidechain(res, ed) + for atom in res.atoms: + atom.is_hetatom = False + print "Removing sidechain of %s, beacuse it has not been found in the compound library"% parent_tlc + else: + #collect atom's names + modif_atom_names = set([atom.name for atom in res.atoms + if atom.element != "H" and atom.element != "D" ]) + #if the res is the first or last take all the atoms from the parent res + if res.FindAtom("OXT").IsValid() : + parent_atom_names = set([atom.name for atom in parent_res.atom_specs + if atom.element != "H" and atom.element != "D" ]) + else: + parent_atom_names = set([atom.name for atom in parent_res.atom_specs + if atom.element != "H" and atom.element != "D" and not atom.is_leaving ]) + additional_parent_atoms = parent_atom_names - modif_atom_names + additional_modif_atoms = modif_atom_names - parent_atom_names + #WHEN mmCIF WILL BE USED, CHANGE IsPeptideLinking() TO IsProtein(), TO EXCLUDE LIGANDS FROM CANONICALISATION + if res.atoms[0].is_hetatom : + old_name = res.name + ed.RenameResidue(res, parent_tlc) + if additional_parent_atoms: + if additional_modif_atoms: + #replacement + _Replacement(res, ed, old_name) + else: + #deletion + _Deletion(res, ed) + elif additional_modif_atoms: + #addition + _Addition(res, ed, additional_modif_atoms) + else: + #unchanged, later check stereochemistry or H atoms + _Unchanged(res, ed) + #the res is a peptide but not a ligand (is a protein res) + else: + if additional_parent_atoms:# if the sidechain is incomplete + _DeleteSidechain(res, ed) + ed.UpdateICS() + return + +def _Replacement(res, ed, old_name) : + #TEMP ONLY MSE + if old_name == "MSE" : + for atom in res.atoms: + atom.is_hetatom = False + sel = res.FindAtom("SE") + if sel.IsValid() : + ed.InsertAtom( res, "SD", sel.pos, "S", sel.occupancy, sel.b_factor ) #S radius=~1;SE=~1.2 + ed.DeleteAtom( sel ) + else: + _DeleteSidechain(res, ed) + else: + _DeleteSidechain(res, ed) + return + +def _Deletion(res, ed) : + _DeleteSidechain(res, ed) + for atom in res.atoms : + atom.is_hetatom = False + return + +def _Addition(res, ed, additional_modif_atoms) : + for add_atom_name in additional_modif_atoms: + add_atom = res.FindAtom( add_atom_name ) + if add_atom.IsValid() : + ed.DeleteAtom( add_atom ) + for atom in res.atoms: + atom.is_hetatom = False + return + +def _Unchanged(res, ed) : + if res.chem_class == mol.D_PEPTIDE_LINKING: + ed.DeleteResidue(res) + else: + _DeleteSidechain(res, ed) + for atom in res.atoms : + atom.is_hetatom = False + return + +def _DeleteSidechain(res, ed) : + for atom in res.atoms: + if not atom.name in ['CA','CB','C','N','O']: + ed.DeleteAtom(atom) + return + +#visible functions +__all__ = [Cleanup] diff --git a/modules/conop/tests/CMakeLists.txt b/modules/conop/tests/CMakeLists.txt index aa06791bf0be4d64640499010893d9db179f3e33..1af92df10be705d46354506d72df5c0c645be732 100644 --- a/modules/conop/tests/CMakeLists.txt +++ b/modules/conop/tests/CMakeLists.txt @@ -4,6 +4,7 @@ set(OST_CONOP_UNIT_TESTS tests.cc test_builder.cc test_compound.py + test_cleanup.py ) ost_unittest(MODULE conop diff --git a/modules/conop/tests/sample_noligands.pdb b/modules/conop/tests/sample_noligands.pdb new file mode 100644 index 0000000000000000000000000000000000000000..7fd199276d45124bbe2b2bc6ddf7d47b780d9401 --- /dev/null +++ b/modules/conop/tests/sample_noligands.pdb @@ -0,0 +1,65 @@ +HETATM 1 N MSE A 1 16.152 35.832 19.337 1.00 68.79 N +ANISOU 1 N MSE A 1 9680 7396 9061 1038 -716 -25 N +HETATM 2 CA MSE A 1 16.961 36.379 20.419 1.00 66.57 C +ANISOU 2 CA MSE A 1 9387 7212 8694 1121 -806 40 C +HETATM 3 C MSE A 1 18.345 36.796 19.931 1.00 62.52 C +ANISOU 3 C MSE A 1 8685 6846 8225 1266 -870 -107 C +HETATM 4 O MSE A 1 19.030 36.049 19.227 1.00 60.36 O +ANISOU 4 O MSE A 1 8358 6511 8064 1396 -922 -219 O +HETATM 5 CB MSE A 1 17.100 35.372 21.563 1.00 69.52 C +ANISOU 5 CB MSE A 1 9961 7405 9049 1204 -927 192 C +HETATM 6 CG MSE A 1 17.608 35.983 22.861 1.00 69.50 C +ANISOU 6 CG MSE A 1 9977 7515 8914 1239 -1006 292 C +HETATM 7 SE MSE A 1 16.174 36.321 24.145 0.70149.62 SE +ANISOU 7 SE MSE A 1 20306 17658 18883 1013 -917 492 SE +HETATM 8 CE MSE A 1 16.439 38.231 24.424 1.00101.32 C +ANISOU 8 CE MSE A 1 13992 11855 12651 950 -853 413 C +ATOM 9 N GLY A 2 21.960 55.913 14.093 1.00 32.26 N +ANISOU 9 N GLY A 2 3786 4717 3755 -417 -110 -697 N +ATOM 10 CA GLY A 2 21.067 57.037 14.316 1.00 33.47 C +ANISOU 10 CA GLY A 2 4071 4728 3919 -478 -95 -611 C +ATOM 11 C GLY A 2 20.632 57.066 15.769 1.00 28.81 C +ANISOU 11 C GLY A 2 3536 4062 3349 -382 -126 -599 C +ATOM 12 O GLY A 2 19.474 57.360 16.089 1.00 26.62 O +ANISOU 12 O GLY A 2 3358 3653 3104 -343 -120 -528 O +HETATM 694 N MLY A 3 26.382 48.690 2.460 1.00 30.43 N +ANISOU 694 N MLY A 3 2388 5919 3254 -646 317 -1852 N +HETATM 695 CA MLY A 3 27.776 48.333 2.142 1.00 32.62 C +ANISOU 695 CA MLY A 3 2438 6444 3514 -645 358 -2093 C +HETATM 696 CB MLY A 3 28.523 49.535 1.556 1.00 34.25 C +ANISOU 696 CB MLY A 3 2578 6874 3563 -918 442 -2107 C +HETATM 697 CG MLY A 3 28.053 50.058 0.208 1.00 51.47 C +ANISOU 697 CG MLY A 3 4819 9152 5586 -1157 527 -2046 C +HETATM 698 CD MLY A 3 29.170 50.911 -0.420 1.00 65.96 C +ANISOU 698 CD MLY A 3 6527 11268 7265 -1416 622 -2140 C +HETATM 699 CE MLY A 3 28.648 51.881 -1.478 1.00 78.91 C +ANISOU 699 CE MLY A 3 8300 12955 8728 -1697 684 -1985 C +HETATM 700 NZ MLY A 3 27.996 53.093 -0.885 1.00 83.04 N +ANISOU 700 NZ MLY A 3 9040 13267 9244 -1780 633 -1724 N +HETATM 701 CH1 MLY A 3 27.490 53.898 -2.008 1.00 82.17 C +ANISOU 701 CH1 MLY A 3 9059 13197 8964 -2028 679 -1578 C +HETATM 702 CH2 MLY A 3 29.059 53.885 -0.248 1.00 83.95 C +ANISOU 702 CH2 MLY A 3 9084 13473 9342 -1885 652 -1769 C +HETATM 703 C MLY A 3 28.551 47.875 3.386 1.00 35.38 C +ANISOU 703 C MLY A 3 2698 6760 3986 -436 275 -2175 C +HETATM 704 O MLY A 3 29.262 46.867 3.369 1.00 36.09 O +ANISOU 704 O MLY A 3 2632 6928 4151 -274 255 -2373 O +HETATM 24 N DHA A 4 26.289 27.329 2.438 1.00 21.02 N +HETATM 25 CA DHA A 4 26.295 27.688 3.823 1.00 20.17 C +HETATM 26 CB DHA A 4 27.128 28.481 4.578 1.00 25.40 C +HETATM 27 C DHA A 4 25.128 27.215 4.536 1.00 14.98 C +HETATM 28 O DHA A 4 24.918 27.318 5.770 1.00 15.17 O +ATOM 1454 N CYS A 5 35.381 45.298 39.476 1.00 31.23 N +ATOM 1455 CA CYS A 5 35.559 43.873 39.703 1.00 26.90 C +ATOM 1456 C CYS A 5 34.291 43.354 40.319 1.00 28.31 C +ATOM 1457 OXT CYS A 5 33.569 44.119 40.933 1.00 32.71 O +ATOM 1458 CB CYS A 5 36.760 43.592 40.596 1.00 27.44 C +ATOM 1460 H CYS A 5 34.717 45.766 40.024 1.00 0.00 H +HETATM 1345 N DAL A 6 16.130 53.915 24.417 1.00 8.63 N +HETATM 1346 CA DAL A 6 16.958 55.083 24.235 1.00 24.17 C +HETATM 1347 CB DAL A 6 16.321 56.394 24.733 1.00 30.20 C +HETATM 1348 C DAL A 6 17.335 55.218 22.790 1.00 32.54 C +HETATM 1349 O DAL A 6 16.693 54.552 21.946 1.00 27.41 O +HETATM 1350 OXT DAL A 6 18.286 55.960 22.546 1.00 18.81 O +HETATM 36 O HOH A 19 0.180 48.781 4.764 1.00 23.28 O +END diff --git a/modules/conop/tests/sample_nowater.pdb b/modules/conop/tests/sample_nowater.pdb new file mode 100644 index 0000000000000000000000000000000000000000..0f8c440aa83c10dec2cfffe71cbe524a15d0af15 --- /dev/null +++ b/modules/conop/tests/sample_nowater.pdb @@ -0,0 +1,71 @@ +HETATM 1 N MSE A 1 16.152 35.832 19.337 1.00 68.79 N +ANISOU 1 N MSE A 1 9680 7396 9061 1038 -716 -25 N +HETATM 2 CA MSE A 1 16.961 36.379 20.419 1.00 66.57 C +ANISOU 2 CA MSE A 1 9387 7212 8694 1121 -806 40 C +HETATM 3 C MSE A 1 18.345 36.796 19.931 1.00 62.52 C +ANISOU 3 C MSE A 1 8685 6846 8225 1266 -870 -107 C +HETATM 4 O MSE A 1 19.030 36.049 19.227 1.00 60.36 O +ANISOU 4 O MSE A 1 8358 6511 8064 1396 -922 -219 O +HETATM 5 CB MSE A 1 17.100 35.372 21.563 1.00 69.52 C +ANISOU 5 CB MSE A 1 9961 7405 9049 1204 -927 192 C +HETATM 6 CG MSE A 1 17.608 35.983 22.861 1.00 69.50 C +ANISOU 6 CG MSE A 1 9977 7515 8914 1239 -1006 292 C +HETATM 7 SE MSE A 1 16.174 36.321 24.145 0.70149.62 SE +ANISOU 7 SE MSE A 1 20306 17658 18883 1013 -917 492 SE +HETATM 8 CE MSE A 1 16.439 38.231 24.424 1.00101.32 C +ANISOU 8 CE MSE A 1 13992 11855 12651 950 -853 413 C +ATOM 9 N GLY A 2 21.960 55.913 14.093 1.00 32.26 N +ANISOU 9 N GLY A 2 3786 4717 3755 -417 -110 -697 N +ATOM 10 CA GLY A 2 21.067 57.037 14.316 1.00 33.47 C +ANISOU 10 CA GLY A 2 4071 4728 3919 -478 -95 -611 C +ATOM 11 C GLY A 2 20.632 57.066 15.769 1.00 28.81 C +ANISOU 11 C GLY A 2 3536 4062 3349 -382 -126 -599 C +ATOM 12 O GLY A 2 19.474 57.360 16.089 1.00 26.62 O +ANISOU 12 O GLY A 2 3358 3653 3104 -343 -120 -528 O +HETATM 694 N MLY A 3 26.382 48.690 2.460 1.00 30.43 N +ANISOU 694 N MLY A 3 2388 5919 3254 -646 317 -1852 N +HETATM 695 CA MLY A 3 27.776 48.333 2.142 1.00 32.62 C +ANISOU 695 CA MLY A 3 2438 6444 3514 -645 358 -2093 C +HETATM 696 CB MLY A 3 28.523 49.535 1.556 1.00 34.25 C +ANISOU 696 CB MLY A 3 2578 6874 3563 -918 442 -2107 C +HETATM 697 CG MLY A 3 28.053 50.058 0.208 1.00 51.47 C +ANISOU 697 CG MLY A 3 4819 9152 5586 -1157 527 -2046 C +HETATM 698 CD MLY A 3 29.170 50.911 -0.420 1.00 65.96 C +ANISOU 698 CD MLY A 3 6527 11268 7265 -1416 622 -2140 C +HETATM 699 CE MLY A 3 28.648 51.881 -1.478 1.00 78.91 C +ANISOU 699 CE MLY A 3 8300 12955 8728 -1697 684 -1985 C +HETATM 700 NZ MLY A 3 27.996 53.093 -0.885 1.00 83.04 N +ANISOU 700 NZ MLY A 3 9040 13267 9244 -1780 633 -1724 N +HETATM 701 CH1 MLY A 3 27.490 53.898 -2.008 1.00 82.17 C +ANISOU 701 CH1 MLY A 3 9059 13197 8964 -2028 679 -1578 C +HETATM 702 CH2 MLY A 3 29.059 53.885 -0.248 1.00 83.95 C +ANISOU 702 CH2 MLY A 3 9084 13473 9342 -1885 652 -1769 C +HETATM 703 C MLY A 3 28.551 47.875 3.386 1.00 35.38 C +ANISOU 703 C MLY A 3 2698 6760 3986 -436 275 -2175 C +HETATM 704 O MLY A 3 29.262 46.867 3.369 1.00 36.09 O +ANISOU 704 O MLY A 3 2632 6928 4151 -274 255 -2373 O +HETATM 24 N DHA A 4 26.289 27.329 2.438 1.00 21.02 N +HETATM 25 CA DHA A 4 26.295 27.688 3.823 1.00 20.17 C +HETATM 26 CB DHA A 4 27.128 28.481 4.578 1.00 25.40 C +HETATM 27 C DHA A 4 25.128 27.215 4.536 1.00 14.98 C +HETATM 28 O DHA A 4 24.918 27.318 5.770 1.00 15.17 O +ATOM 1454 N CYS A 5 35.381 45.298 39.476 1.00 31.23 N +ATOM 1455 CA CYS A 5 35.559 43.873 39.703 1.00 26.90 C +ATOM 1456 C CYS A 5 34.291 43.354 40.319 1.00 28.31 C +ATOM 1457 OXT CYS A 5 33.569 44.119 40.933 1.00 32.71 O +ATOM 1458 CB CYS A 5 36.760 43.592 40.596 1.00 27.44 C +ATOM 1460 H CYS A 5 34.717 45.766 40.024 1.00 0.00 H +HETATM 1345 N DAL A 6 16.130 53.915 24.417 1.00 8.63 N +HETATM 1346 CA DAL A 6 16.958 55.083 24.235 1.00 24.17 C +HETATM 1347 CB DAL A 6 16.321 56.394 24.733 1.00 30.20 C +HETATM 1348 C DAL A 6 17.335 55.218 22.790 1.00 32.54 C +HETATM 1349 O DAL A 6 16.693 54.552 21.946 1.00 27.41 O +HETATM 1350 OXT DAL A 6 18.286 55.960 22.546 1.00 18.81 O +HETATM 29 C1 GOL A 17 3.793 59.768 8.209 1.00 31.00 C +HETATM 30 O1 GOL A 17 3.244 58.473 8.337 1.00 27.42 O +HETATM 31 C2 GOL A 17 4.701 60.020 9.406 1.00 26.81 C +HETATM 32 O2 GOL A 17 5.573 58.919 9.512 1.00 26.44 O +HETATM 33 C3 GOL A 17 5.505 61.287 9.156 1.00 24.74 C +HETATM 34 O3 GOL A 17 6.429 61.468 10.222 1.00 31.06 O +HETATM 35 CL CL A 18 11.844 59.221 16.755 0.79 32.84 CL +END diff --git a/modules/conop/tests/sample_test_cleanup.pdb b/modules/conop/tests/sample_test_cleanup.pdb new file mode 100644 index 0000000000000000000000000000000000000000..cce7fe04d4fe753d68c9e73620fea8617ce07059 --- /dev/null +++ b/modules/conop/tests/sample_test_cleanup.pdb @@ -0,0 +1,72 @@ +HETATM 1 N MSE A 1 16.152 35.832 19.337 1.00 68.79 N +ANISOU 1 N MSE A 1 9680 7396 9061 1038 -716 -25 N +HETATM 2 CA MSE A 1 16.961 36.379 20.419 1.00 66.57 C +ANISOU 2 CA MSE A 1 9387 7212 8694 1121 -806 40 C +HETATM 3 C MSE A 1 18.345 36.796 19.931 1.00 62.52 C +ANISOU 3 C MSE A 1 8685 6846 8225 1266 -870 -107 C +HETATM 4 O MSE A 1 19.030 36.049 19.227 1.00 60.36 O +ANISOU 4 O MSE A 1 8358 6511 8064 1396 -922 -219 O +HETATM 5 CB MSE A 1 17.100 35.372 21.563 1.00 69.52 C +ANISOU 5 CB MSE A 1 9961 7405 9049 1204 -927 192 C +HETATM 6 CG MSE A 1 17.608 35.983 22.861 1.00 69.50 C +ANISOU 6 CG MSE A 1 9977 7515 8914 1239 -1006 292 C +HETATM 7 SE MSE A 1 16.174 36.321 24.145 0.70149.62 SE +ANISOU 7 SE MSE A 1 20306 17658 18883 1013 -917 492 SE +HETATM 8 CE MSE A 1 16.439 38.231 24.424 1.00101.32 C +ANISOU 8 CE MSE A 1 13992 11855 12651 950 -853 413 C +ATOM 9 N GLY A 2 21.960 55.913 14.093 1.00 32.26 N +ANISOU 9 N GLY A 2 3786 4717 3755 -417 -110 -697 N +ATOM 10 CA GLY A 2 21.067 57.037 14.316 1.00 33.47 C +ANISOU 10 CA GLY A 2 4071 4728 3919 -478 -95 -611 C +ATOM 11 C GLY A 2 20.632 57.066 15.769 1.00 28.81 C +ANISOU 11 C GLY A 2 3536 4062 3349 -382 -126 -599 C +ATOM 12 O GLY A 2 19.474 57.360 16.089 1.00 26.62 O +ANISOU 12 O GLY A 2 3358 3653 3104 -343 -120 -528 O +HETATM 694 N MLY A 3 26.382 48.690 2.460 1.00 30.43 N +ANISOU 694 N MLY A 3 2388 5919 3254 -646 317 -1852 N +HETATM 695 CA MLY A 3 27.776 48.333 2.142 1.00 32.62 C +ANISOU 695 CA MLY A 3 2438 6444 3514 -645 358 -2093 C +HETATM 696 CB MLY A 3 28.523 49.535 1.556 1.00 34.25 C +ANISOU 696 CB MLY A 3 2578 6874 3563 -918 442 -2107 C +HETATM 697 CG MLY A 3 28.053 50.058 0.208 1.00 51.47 C +ANISOU 697 CG MLY A 3 4819 9152 5586 -1157 527 -2046 C +HETATM 698 CD MLY A 3 29.170 50.911 -0.420 1.00 65.96 C +ANISOU 698 CD MLY A 3 6527 11268 7265 -1416 622 -2140 C +HETATM 699 CE MLY A 3 28.648 51.881 -1.478 1.00 78.91 C +ANISOU 699 CE MLY A 3 8300 12955 8728 -1697 684 -1985 C +HETATM 700 NZ MLY A 3 27.996 53.093 -0.885 1.00 83.04 N +ANISOU 700 NZ MLY A 3 9040 13267 9244 -1780 633 -1724 N +HETATM 701 CH1 MLY A 3 27.490 53.898 -2.008 1.00 82.17 C +ANISOU 701 CH1 MLY A 3 9059 13197 8964 -2028 679 -1578 C +HETATM 702 CH2 MLY A 3 29.059 53.885 -0.248 1.00 83.95 C +ANISOU 702 CH2 MLY A 3 9084 13473 9342 -1885 652 -1769 C +HETATM 703 C MLY A 3 28.551 47.875 3.386 1.00 35.38 C +ANISOU 703 C MLY A 3 2698 6760 3986 -436 275 -2175 C +HETATM 704 O MLY A 3 29.262 46.867 3.369 1.00 36.09 O +ANISOU 704 O MLY A 3 2632 6928 4151 -274 255 -2373 O +HETATM 24 N DHA A 4 26.289 27.329 2.438 1.00 21.02 N +HETATM 25 CA DHA A 4 26.295 27.688 3.823 1.00 20.17 C +HETATM 26 CB DHA A 4 27.128 28.481 4.578 1.00 25.40 C +HETATM 27 C DHA A 4 25.128 27.215 4.536 1.00 14.98 C +HETATM 28 O DHA A 4 24.918 27.318 5.770 1.00 15.17 O +ATOM 1454 N CYS A 5 35.381 45.298 39.476 1.00 31.23 N +ATOM 1455 CA CYS A 5 35.559 43.873 39.703 1.00 26.90 C +ATOM 1456 C CYS A 5 34.291 43.354 40.319 1.00 28.31 C +ATOM 1457 OXT CYS A 5 33.569 44.119 40.933 1.00 32.71 O +ATOM 1458 CB CYS A 5 36.760 43.592 40.596 1.00 27.44 C +ATOM 1460 H CYS A 5 34.717 45.766 40.024 1.00 0.00 H +HETATM 1345 N DAL A 6 16.130 53.915 24.417 1.00 8.63 N +HETATM 1346 CA DAL A 6 16.958 55.083 24.235 1.00 24.17 C +HETATM 1347 CB DAL A 6 16.321 56.394 24.733 1.00 30.20 C +HETATM 1348 C DAL A 6 17.335 55.218 22.790 1.00 32.54 C +HETATM 1349 O DAL A 6 16.693 54.552 21.946 1.00 27.41 O +HETATM 1350 OXT DAL A 6 18.286 55.960 22.546 1.00 18.81 O +HETATM 29 C1 GOL A 17 3.793 59.768 8.209 1.00 31.00 C +HETATM 30 O1 GOL A 17 3.244 58.473 8.337 1.00 27.42 O +HETATM 31 C2 GOL A 17 4.701 60.020 9.406 1.00 26.81 C +HETATM 32 O2 GOL A 17 5.573 58.919 9.512 1.00 26.44 O +HETATM 33 C3 GOL A 17 5.505 61.287 9.156 1.00 24.74 C +HETATM 34 O3 GOL A 17 6.429 61.468 10.222 1.00 31.06 O +HETATM 35 CL CL A 18 11.844 59.221 16.755 0.79 32.84 CL +HETATM 36 O HOH A 19 0.180 48.781 4.764 1.00 23.28 O +END diff --git a/modules/conop/tests/test_cleanup.py b/modules/conop/tests/test_cleanup.py new file mode 100644 index 0000000000000000000000000000000000000000..ee6ab57cae413a550e1cc6abdbc7875a1d7d3210 --- /dev/null +++ b/modules/conop/tests/test_cleanup.py @@ -0,0 +1,162 @@ +import unittest +from ost import geom, conop +from ost.conop import cleanup + +class TestCleanUp(unittest.TestCase): + + def setUp(self): + self.comp_lib=conop.GetBuilder().compound_lib + self.ent = io.LoadPDB("sample_test_cleanup.pdb") + self.ent_no_wat = io.LoadPDB("sample_nowater.pdb") + self.ent_no_lig = io.LoadPDB("sample_noligands.pdb") + + def testStripWater(self): + self.new_ent = cleanup.Cleanup(self.ent, strip_water=True, canonicalize=False, remove_ligands=False) + self.assertEqual( self.new_ent.residue_count, self.ent_no_wat.residue_count ) + self.assertTrue( self.new_ent.residues[0].IsValid() ) + self.assertEqual( self.new_ent.residues[0].qualified_name, self.ent_no_wat.residues[0].qualified_name) + self.assertTrue( self.new_ent.residues[1].IsValid() ) + self.assertEqual( self.new_ent.residues[1].qualified_name, self.ent_no_wat.residues[1].qualified_name) + self.assertTrue( self.new_ent.residues[2].IsValid() ) + self.assertEqual( self.new_ent.residues[2].qualified_name, self.ent_no_wat.residues[2].qualified_name) + self.assertTrue( self.new_ent.residues[3].IsValid() ) + self.assertEqual( self.new_ent.residues[3].qualified_name, self.ent_no_wat.residues[3].qualified_name) + self.assertTrue( self.new_ent.residues[4].IsValid() ) + self.assertEqual( self.new_ent.residues[4].qualified_name, self.ent_no_wat.residues[4].qualified_name) + self.assertTrue( self.new_ent.residues[5].IsValid() ) + self.assertEqual( self.new_ent.residues[5].qualified_name, self.ent_no_wat.residues[5].qualified_name) + self.assertTrue( self.new_ent.residues[6].IsValid() ) + self.assertEqual( self.new_ent.residues[6].qualified_name, self.ent_no_wat.residues[6].qualified_name) + self.assertTrue( self.new_ent.residues[7].IsValid() ) + self.assertEqual( self.new_ent.residues[7].qualified_name, self.ent_no_wat.residues[7].qualified_name) + + def testCanonicalize(self): + self.new_ent = cleanup.Cleanup(self.ent, strip_water=False, canonicalize=True, remove_ligands=False) + #standard residue must be the same + self.gly = self.ent.residues[1] + self.new_gly = self.new_ent.residues[1] + self.assertTrue(self.new_gly.IsValid()) + self.assertTrue(self.new_gly.IsPeptideLinking()) + self.assertEqual(self.gly.atom_count, self.new_gly.atom_count) + #TEMP del sidechain of incomplete residue and OXT if present + self.new_cys = self.new_ent.residues[4] + self.new_cys_atoms = set([atm.name for atm in self.new_cys.atoms]) + self.assertEqual( len(self.new_cys_atoms), 4, msg = repr(self.new_cys_atoms)) + self.assertTrue( "CB" in self.new_cys_atoms) + self.assertTrue( "CA" in self.new_cys_atoms) + self.assertTrue( "C" in self.new_cys_atoms) + self.assertFalse( "OXT" in self.new_cys_atoms) + self.assertTrue( "N" in self.new_cys_atoms) + #test replacement of atoms + self.mse = self.ent.residues[0] +# self.assertTrue( self.mse.IsValid()) +# self.assertTrue( self.mse.IsPeptideLinking()) + self.sel = self.mse.FindAtom("SE") +# self.assertTrue( self.sel.IsValid()) + self.met = self.new_ent.residues[0] + self.assertTrue(self.met.IsValid()) + self.assertEqual(self.mse.atom_count, self.met.atom_count) + self.assertEqual(self.met.name, "MET") + self.assertEqual(self.met.one_letter_code, "M") + self.assertTrue(self.met.IsPeptideLinking()) + self.sul = self.met.FindAtom("SD") + self.assertTrue(self.sul.IsValid()) + self.assertTrue(geom.Equal(self.sul.pos,self.sel.pos), msg = "sul:%s sel:%s"%(str(self.sul.pos), str(self.sel.pos)) ) + self.assertEqual(self.sul.element, "S") +# self.AssertTrue( sul.mass == conop.Conopology.Instance().GetDefaultAtomMass("S")) +# self.AssertTrue( sul.radius == conop.Conopology.Instance().GetDefaultAtomRadius("S")) + for atm in self.met.atoms: + self.assertFalse( atm.is_hetatom) + #test addition + self.mly = self.ent.residues[2] +# self.assertTrue( self.mly.IsValid()) +# self.assertTrue( self.mly.IsPeptideLinking()) + self.new_lys = self.new_ent.residues[2] + self.assertTrue(self.new_lys.IsValid()) + self.assertTrue(self.new_lys.IsPeptideLinking()) + self.assertEqual(self.new_lys.name, "LYS") + self.assertEqual(self.new_lys.one_letter_code, "K") + self.new_lys_atoms = set([atm.name for atm in self.new_lys.atoms]) + self.canon_lys = self.comp_lib.FindCompound("LYS") + self.canon_lys_atoms = set([atom.name for atom in self.canon_lys.atom_specs + if atom.element != "H" and atom.element != "D" and not atom.is_leaving ]) + self.assertEqual(self.canon_lys_atoms, self.new_lys_atoms) + self.assertFalse(self.canon_lys_atoms - self.new_lys_atoms) + self.assertFalse(self.new_lys_atoms - self.canon_lys_atoms) #test the reverse + for atm in self.new_lys.atoms: + self.assertFalse( atm.is_hetatom) + #deletions + self.dha = self.ent.residues[3] +# self.assertTrue( self.dha.IsValid()) +# self.assertTrue( self.dha.IsPeptideLinking()) + self.new_ser = self.new_ent.residues[3] + self.assertTrue(self.new_ser.IsValid()) + self.assertTrue(self.new_ser.IsPeptideLinking()) + self.assertEqual(self.new_ser.name, "SER") + self.assertEqual(self.new_ser.one_letter_code, "S") + self.new_ser_atoms = set([atm.name for atm in self.new_ser.atoms]) + self.canon_ser = self.comp_lib.FindCompound("SER") + self.canon_ser_atoms = set([atom.name for atom in self.canon_ser.atom_specs + if atom.element != "H" and atom.element != "D" and not atom.is_leaving ]) + #TEMP + self.assertEqual( len(self.new_ser_atoms), 5) + self.assertTrue( "CB" in self.new_ser_atoms) + self.assertTrue( "CA" in self.new_ser_atoms) + self.assertTrue( "C" in self.new_ser_atoms) + self.assertTrue( "O" in self.new_ser_atoms) + self.assertTrue( "N" in self.new_ser_atoms) + #AFTER TEMP + #self.assertEqual( self.canon_ser_atoms, self.new_ser_atoms) + #self.assertFalse(self.canon_ser_atoms - self.new_ser_atoms) + #self.assertFalse(self.new_ser_atoms - self.canon_ser_atoms) #test the reverse + for atm in self.new_ser.atoms: + self.assertFalse( atm.is_hetatom) + #test deletion of whole residue + self.assertEqual(self.ent.residues[5].chem_class, "D_PEPTIDE_LINKING") + self.assertNotEqual(self.new_ent.residues[5].name, "DAL") + self.assertNotEqual(self.ent.residue_count, self.new_ent.residue_count) + + def testRemoveLigands(self): + self.new_ent = cleanup.Cleanup(self.ent, strip_water=False, canonicalize=False, remove_ligands=True) + self.assertEqual(self.new_ent.residue_count, self.ent_no_lig.residue_count ) + #MSE + self.assertTrue(self.new_ent.residues[0].IsValid() ) + self.assertEqual(self.new_ent.residues[0].qualified_name, self.ent_no_lig.residues[0].qualified_name) + self.assertTrue(self.new_ent.residues[0].IsPeptideLinking()) + self.assertTrue(self.new_ent.residues[0].atoms[0].is_hetatom) + #GLY + self.assertTrue(self.new_ent.residues[1].IsValid() ) + self.assertEqual(self.new_ent.residues[1].qualified_name, self.ent_no_lig.residues[1].qualified_name) + self.assertTrue(self.new_ent.residues[1].IsPeptideLinking()) + self.assertFalse(self.new_ent.residues[1].atoms[0].is_hetatom) + #MLY + self.assertTrue(self.new_ent.residues[2].IsValid() ) + self.assertEqual(self.new_ent.residues[2].qualified_name, self.ent_no_lig.residues[2].qualified_name) + self.assertTrue(self.new_ent.residues[2].IsPeptideLinking()) + self.assertTrue(self.new_ent.residues[2].atoms[0].is_hetatom) + #DHA + self.assertTrue(self.new_ent.residues[3].IsValid() ) + self.assertEqual(self.new_ent.residues[3].qualified_name, self.ent_no_lig.residues[3].qualified_name) + self.assertTrue(self.new_ent.residues[3].IsPeptideLinking()) + self.assertTrue(self.new_ent.residues[3].atoms[0].is_hetatom) + #CYS + self.assertTrue(self.new_ent.residues[4].IsValid() ) + self.assertEqual(self.new_ent.residues[4].qualified_name, self.ent_no_lig.residues[4].qualified_name) + self.assertTrue(self.new_ent.residues[4].IsPeptideLinking()) + self.assertFalse(self.new_ent.residues[4].atoms[0].is_hetatom) + #DAL + self.assertTrue(self.new_ent.residues[5].IsValid() ) + self.assertEqual(self.new_ent.residues[5].qualified_name, self.ent_no_lig.residues[5].qualified_name) + self.assertTrue(self.new_ent.residues[5].IsPeptideLinking()) + self.assertTrue(self.new_ent.residues[5].atoms[0].is_hetatom) + #HOH + self.assertTrue(self.new_ent.residues[6].IsValid() ) + self.assertEqual(self.new_ent.residues[6].qualified_name, self.ent_no_lig.residues[6].qualified_name) + self.assertFalse(self.new_ent.residues[6].IsPeptideLinking()) # here assertFalse instead of assertTrue + self.assertTrue(self.new_ent.residues[6].atoms[0].is_hetatom) + +if not hasattr(conop.GetBuilder(), 'compound_lib'): + print 'Default builder without compound lib. Ignoring test_cleanup.py tests' + sys.exit() +suite = unittest.TestLoader().loadTestsFromTestCase(TestCleanUp) +unittest.TextTestRunner().run(suite) diff --git a/modules/geom/pymod/export_mat2.cc b/modules/geom/pymod/export_mat2.cc index fa1e382c9c62b7bc7ef789303d41cc88bcca6316..8905a47466622acc71b60f69ad1210dd11a06cba 100644 --- a/modules/geom/pymod/export_mat2.cc +++ b/modules/geom/pymod/export_mat2.cc @@ -33,6 +33,16 @@ String mat2_repr(const geom::Mat2& m) { << m(1,0) << ", " << m(1,1) << ")"; return ss.str(); } + +list mat2_data(const geom::Mat2& m) +{ + list nrvo; + for(size_t k=0;k<4;++k) { + nrvo.append(m.Data()[k]); + } + return nrvo; +} + void export_Mat2() { using namespace geom; @@ -54,5 +64,6 @@ void export_Mat2() .def(self_ns::str(self)) .def("__getitem__",Mat2_getitem) .def("__setitem__",Mat2_setitem) + .add_property("data",mat2_data) ; } diff --git a/modules/geom/pymod/export_mat3.cc b/modules/geom/pymod/export_mat3.cc index 4d86381a4db04b747f6834f6e56d5b3890c0de3c..bf92d2e4e5c11f34ad692953f913902237206c4d 100644 --- a/modules/geom/pymod/export_mat3.cc +++ b/modules/geom/pymod/export_mat3.cc @@ -63,6 +63,14 @@ String mat3_repr(const geom::Mat3& m) return ss.str(); } +list mat3_data(const geom::Mat3& m) +{ + list nrvo; + for(size_t k=0;k<9;++k) { + nrvo.append(m.Data()[k]); + } + return nrvo; +} void export_Mat3() { @@ -88,6 +96,7 @@ void export_Mat3() .def("__setitem__",Mat3_setitem) .def("__setitem__",Mat3_setslice) .def("GetCol", &Mat3::GetCol) - .def("GetRow", &Mat3::GetRow) + .def("GetRow", &Mat3::GetRow) + .add_property("data",mat3_data) ; } diff --git a/modules/geom/pymod/export_mat4.cc b/modules/geom/pymod/export_mat4.cc index 7a5805dc6c45305fcebc5742428065d9d49f2afe..3bb555b2cfe0783346c0cf3de9a3c1626dc7fa36 100644 --- a/modules/geom/pymod/export_mat4.cc +++ b/modules/geom/pymod/export_mat4.cc @@ -85,6 +85,14 @@ String mat4_repr(const geom::Mat4& m) { return ss.str(); } +list mat4_data(const geom::Mat4& m) +{ + list nrvo; + for(size_t k=0;k<16;++k) { + nrvo.append(m.Data()[k]); + } + return nrvo; +} void export_Mat4() { @@ -115,5 +123,6 @@ void export_Mat4() .def("PasteRotation",&Mat4::PasteRotation) .def("ExtractTranslation",&Mat4::ExtractTranslation) .def("PasteTranslation",&Mat4::PasteTranslation) + .add_property("data",mat4_data) ; } diff --git a/modules/geom/pymod/export_vec2.cc b/modules/geom/pymod/export_vec2.cc index eec194418d780663aab9ecfe8e09388067c7f28f..456d26db370fdad9e364cfaa9d98fa74a4dd28d1 100644 --- a/modules/geom/pymod/export_vec2.cc +++ b/modules/geom/pymod/export_vec2.cc @@ -35,6 +35,15 @@ String vec2_repr(const geom::Vec2& v) return ss.str(); } +list vec2_data(const geom::Vec2& v) +{ + list nrvo; + for(size_t k=0;k<2;++k) { + nrvo.append(v.Data()[k]); + } + return nrvo; +} + void export_Vec2() { using namespace geom; @@ -66,6 +75,7 @@ void export_Vec2() .def("GetY", &Vec2::GetY) .add_property("x", &Vec2::GetX, &Vec2::SetX) .add_property("y", &Vec2::GetY, &Vec2::SetY) + .add_property("data",vec2_data) ; class_<Vec2List>("Vec2List", init<>()) .def(vector_indexing_suite<Vec2List>()) diff --git a/modules/geom/pymod/export_vec3.cc b/modules/geom/pymod/export_vec3.cc index 623671de519d14f73d7843115a5d5b18e74c8da8..9a9b8f47c0850448a80a8033eb67c5df007b86e2 100644 --- a/modules/geom/pymod/export_vec3.cc +++ b/modules/geom/pymod/export_vec3.cc @@ -38,6 +38,15 @@ String vec3_repr(const geom::Vec3& v) return ss.str(); } +list vec3_data(const geom::Vec3& v) +{ + list nrvo; + for(size_t k=0;k<3;++k) { + nrvo.append(v.Data()[k]); + } + return nrvo; +} + void export_Vec3() { using namespace geom; @@ -71,6 +80,7 @@ void export_Vec3() .add_property("x", &Vec3::GetX, &Vec3::SetX) .add_property("y", &Vec3::GetY, &Vec3::SetY) .add_property("z", &Vec3::GetZ, &Vec3::SetZ) + .add_property("data",vec3_data) ; def("Normalize", &NormalizeV3); @@ -82,5 +92,7 @@ void export_Vec3() .add_property("center", &Vec3List::GetCenter) .add_property("inertia", &Vec3List::GetInertia) .add_property("principal_axes", &Vec3List::GetPrincipalAxes) + .def("GetODRLine", &Vec3List::GetODRLine) + .def("FitCylinder", &Vec3List::FitCylinder) ; } diff --git a/modules/geom/pymod/export_vec4.cc b/modules/geom/pymod/export_vec4.cc index bb3d80f90cc62205ec40e6fd22a736d05c0b1d20..4ebe1bbd108c95db0709622f544b9d79ee285c55 100644 --- a/modules/geom/pymod/export_vec4.cc +++ b/modules/geom/pymod/export_vec4.cc @@ -34,6 +34,15 @@ String vec4_repr(const geom::Vec4& v) return ss.str(); } +list vec4_data(const geom::Vec4& v) +{ + list nrvo; + for(size_t k=0;k<4;++k) { + nrvo.append(v.Data()[k]); + } + return nrvo; +} + void export_Vec4() { using namespace geom; @@ -61,6 +70,11 @@ void export_Vec4() .def(self_ns::str(self)) .def("__getitem__",Vec4_getitem) .def("__setitem__",Vec4_setitem) + .add_property("x", &Vec4::GetX, &Vec4::SetX) + .add_property("y", &Vec4::GetY, &Vec4::SetY) + .add_property("z", &Vec4::GetZ, &Vec4::SetZ) + .add_property("w", &Vec4::GetW, &Vec4::SetW) + .add_property("data",vec4_data) ; } diff --git a/modules/geom/pymod/export_vecmat2_op.cc b/modules/geom/pymod/export_vecmat2_op.cc index 4215e25fdf4cbc28f0dfdc09f5820cb1adc5ea91..cf1f0ac0b4df0579caa5638238d3301c3a83b16f 100644 --- a/modules/geom/pymod/export_vecmat2_op.cc +++ b/modules/geom/pymod/export_vecmat2_op.cc @@ -35,6 +35,8 @@ Mat2 (*Mat2Transpose)(const Mat2& m) = &Trans Real (*Vec2Angle)(const Vec2& v1, const Vec2& v2) = &Angle; Vec2 (*Vec2Normalize)(const Vec2& v1) = &Normalize; Vec2 (*Vec2Rotate)(const Vec2& v1,Real ang) = &Rotate; +Vec2 (*Vec2Min)(const Vec2&, const Vec2&) = &Min; +Vec2 (*Vec2Max)(const Vec2&, const Vec2&) = &Max; void export_VecMat2_op() { @@ -53,4 +55,6 @@ void export_VecMat2_op() def("Angle",Vec2Angle); def("Normalize",Vec2Normalize); def("Rotate",Vec2Rotate); + def("Min",Vec2Min); + def("Max",Vec2Max); } diff --git a/modules/geom/pymod/export_vecmat3_op.cc b/modules/geom/pymod/export_vecmat3_op.cc index fe4444b75a176651a700c032895d04a926fc2257..048cdd170b4ca4e45c724db50f21d7a93fdcabd6 100644 --- a/modules/geom/pymod/export_vecmat3_op.cc +++ b/modules/geom/pymod/export_vecmat3_op.cc @@ -36,6 +36,8 @@ Mat3 (*Mat3Invert)(const Mat3& m) = &Inver Mat3 (*Mat3Transpose)(const Mat3& m) = &Transpose; Real (*Mat3Comp)(const Mat3& m, unsigned int i, unsigned int j) = &Comp; Real (*Mat3Minor)(const Mat3& m, unsigned int i, unsigned int j) = &Minor; +Vec3 (*Vec3Min)(const Vec3&, const Vec3&) = &Min; +Vec3 (*Vec3Max)(const Vec3&, const Vec3&) = &Max; void export_VecMat3_op() @@ -60,4 +62,6 @@ void export_VecMat3_op() def("EulerTransformation",EulerTransformation); def("AxisRotation",AxisRotation); def("OrthogonalVector",OrthogonalVector); + def("Min",Vec3Min); + def("Max",Vec3Max); } diff --git a/modules/geom/pymod/export_vecmat4_op.cc b/modules/geom/pymod/export_vecmat4_op.cc index 9d91f48bbf9c3e8f6378e6822fdeeeefcd10fd16..af64cef7476c00ee2c31db423ec40af4d3674aa9 100644 --- a/modules/geom/pymod/export_vecmat4_op.cc +++ b/modules/geom/pymod/export_vecmat4_op.cc @@ -36,6 +36,8 @@ Mat4 (*Mat4Transpose)(const Mat4& m) = &Trans Real (*Mat4Comp)(const Mat4& m, unsigned int i, unsigned int j) = &Comp; Real (*Mat4Minor)(const Mat4& m, unsigned int i, unsigned int j) = &Minor; Real (*Vec4Angle)(const Vec4& v1, const Vec4& v2) = &Angle; +Vec4 (*Vec4Min)(const Vec4&, const Vec4&) = &Min; +Vec4 (*Vec4Max)(const Vec4&, const Vec4&) = &Max; void export_VecMat4_op() @@ -55,4 +57,6 @@ void export_VecMat4_op() def("Comp",Mat4Comp); def("Minor",Mat4Minor); def("Angle",Vec4Angle); + def("Min",Vec4Min); + def("Max",Vec4Max); } diff --git a/modules/geom/src/composite3.cc b/modules/geom/src/composite3.cc index 686e843e150c15729acd330cd8bc8d4112249c7f..751901b303d3b25f2b863c6767a7b21ff3343948 100644 --- a/modules/geom/src/composite3.cc +++ b/modules/geom/src/composite3.cc @@ -224,25 +224,12 @@ Vec3 Rotation3::GetRotationAxis() const } Real Rotation3::GetRotationAngle() const { - return 2.0*acos(q_.GetAngle()); + //return 2.0*acos(q_.GetAngle()); + return q_.GetAngle(); } Mat3 Rotation3::GetRotationMatrix() const { - Real ww = q_.GetAngle()*q_.GetAngle(); - Real wx = q_.GetAngle()*q_.GetAxis().GetX(); - Real wy = q_.GetAngle()*q_.GetAxis().GetY(); - Real wz = q_.GetAngle()*q_.GetAxis().GetZ(); - Real xx = q_.GetAxis().GetX()*q_.GetAxis().GetX(); - Real xy = q_.GetAxis().GetX()*q_.GetAxis().GetY(); - Real xz = q_.GetAxis().GetX()*q_.GetAxis().GetZ(); - Real yy = q_.GetAxis().GetY()*q_.GetAxis().GetY(); - Real yz = q_.GetAxis().GetY()*q_.GetAxis().GetZ(); - Real zz = q_.GetAxis().GetZ()*q_.GetAxis().GetZ(); - - - return Mat3((ww+xx-yy-zz), 2.0*(-wz+xy), 2.0*(wy+xz), - 2.0*(wz+xy), (ww-xx+yy-zz), 2.0*(-wx+yz), - 2.0*(-wy+xz), 2.0*(wx+yz),(ww-xx-yy+zz)); + return q_.ToRotationMatrix(); } void Rotation3::SetOrigin(const Vec3& o) @@ -299,7 +286,8 @@ Quat Rotation3::generate_from_eulers(Real phi, Real theta, Real psi) } Quat Rotation3::generate_from_axis_angle(const Vec3& axis, Real angle) { - return Quat(cos(angle/2.0),sin(angle/2.0)*Normalize(axis)); + //return Quat(cos(angle/2.0),sin(angle/2.0)*Normalize(axis)); + return Quat(angle, axis); } /* diff --git a/modules/geom/src/composite3_op.cc b/modules/geom/src/composite3_op.cc index 09fb2c72e7430c2fc938534ff4167052485a4b24..672896f0d9aaec18fad77a24aa8065c7c43e34e4 100644 --- a/modules/geom/src/composite3_op.cc +++ b/modules/geom/src/composite3_op.cc @@ -178,5 +178,50 @@ bool IsInSphere(const Sphere& s, const Vec3& v){ return Length(s.GetOrigin()-v)<=s.GetRadius(); } +Line3 Vec3List::FitCylinder(){ + Line3 axis=this->GetODRLine(),axis_old; + Real radius,res_sum_old,res_sum,delta=0.01,prec=0.001,err; + unsigned long n_step=1000, n_res=this->size(); + Vec3 v,gradient; + radius=0.0; + for (Vec3List::const_iterator i=this->begin(),e=this->end(); i!=e; ++i) { + radius+=geom::Distance(axis,(*i)); + } + radius/=Real(n_res); + res_sum=0.0; + for (Vec3List::const_iterator i=this->begin(),e=this->end(); i!=e; ++i) { + res_sum+=pow(Distance(axis,(*i))-radius,2.); + } + unsigned long k=0; + err=2.0*prec; + while (err>prec and k<n_step) { + res_sum_old=res_sum; + axis_old=axis; + for (Vec3List::const_iterator i=this->begin(),e=this->end(); i!=e; ++i) { + radius+=Distance(axis,(*i)); + } + radius/=Real(n_res); + for (int j=0; j!=3; ++j){ + res_sum=0.0; + v=Vec3(0.0,0.0,0.0); + v[j]=delta; + axis=Line3(axis_old.GetOrigin(),axis_old.GetOrigin()+axis_old.GetDirection()+v); + for (Vec3List::const_iterator i=this->begin(),e=this->end(); i!=e; ++i) { + res_sum+=pow(Distance(axis,(*i))-radius,2.); + } + gradient[j]=res_sum-res_sum_old; + } + gradient=Normalize(gradient); + axis=Line3(axis_old.GetOrigin(),axis_old.GetOrigin()+axis_old.GetDirection()-delta*gradient); + res_sum=0.0; + for (Vec3List::const_iterator i=this->begin(),e=this->end(); i!=e; ++i) { + res_sum+=pow(Distance(axis,(*i))-radius,2.); + } + err=fabs((res_sum-res_sum_old)/float(n_res)); + k++; + } + return axis; +} + } // ns diff --git a/modules/geom/src/quat.cc b/modules/geom/src/quat.cc index b923a668008fbe908f55bd1a10a584598ea930de..f9b852cae7799478c8f0ca3bfb599c3b80821421 100644 --- a/modules/geom/src/quat.cc +++ b/modules/geom/src/quat.cc @@ -287,7 +287,8 @@ Vec3 Quat::GetAxis() const Real Quat::GetAngle() const { - Real ww = std::acos(w/Length(Vec3(x,y,z))); + //Real ww = std::acos(w/Length(Vec3(x,y,z))); + Real ww = 2.0*std::acos(w); return ww; } diff --git a/modules/geom/src/vec3.cc b/modules/geom/src/vec3.cc index 84467ced5a4ddf66dd5ae23e1de054c7cb8e175d..bcc62d42ad0bb0814581f96b9750730e4a84ce7c 100644 --- a/modules/geom/src/vec3.cc +++ b/modules/geom/src/vec3.cc @@ -68,5 +68,12 @@ Vec3 Vec3List::GetCenter() const return center/=this->size(); } +Line3 Vec3List::GetODRLine() +{ + Vec3 center=this->GetCenter(); + Vec3 direction=this->GetPrincipalAxes().GetRow(2); + return Line3(center,center+direction); +} + } diff --git a/modules/geom/src/vec3.hh b/modules/geom/src/vec3.hh index db2b8bb7097dc76d0b74c7906a0ea4a63bda5929..2a27d500a8a0c5ca9c66127de47f0cf37f48f932 100644 --- a/modules/geom/src/vec3.hh +++ b/modules/geom/src/vec3.hh @@ -34,7 +34,7 @@ namespace geom { // fw decl class Vec2; class Vec4; - +class Line3; /// \brief Three dimensional vector class, using Real precision. class DLLEXPORT_OST_GEOM Vec3: @@ -193,6 +193,7 @@ inline std::ostream& operator<<(std::ostream& os, const Vec3& v) #include <ost/geom/vec2.hh> #include <ost/geom/vec4.hh> #include <ost/geom/mat3.hh> +#include <ost/geom/composite3.hh> namespace geom { @@ -216,6 +217,9 @@ public: Vec3 GetCenter() const; Mat3 GetPrincipalAxes() const; + Line3 GetODRLine(); + Line3 FitCylinder(); + }; diff --git a/modules/geom/tests/CMakeLists.txt b/modules/geom/tests/CMakeLists.txt index 7a7dace6b3ed006ba13997889693a4b3910949f8..42d7f4c43b393411b5c7edeaecec9bc1e8bc2ca4 100644 --- a/modules/geom/tests/CMakeLists.txt +++ b/modules/geom/tests/CMakeLists.txt @@ -11,7 +11,7 @@ set(GEOM_UNITTESTS test_vec3.cc test_vec4.cc tests.cc - test_repr.py + test_geom.py ) ost_unittest(MODULE geom diff --git a/modules/geom/tests/test_geom.py b/modules/geom/tests/test_geom.py new file mode 100644 index 0000000000000000000000000000000000000000..e25081bf1f0f305cf7928bd897566ade46c9c9e3 --- /dev/null +++ b/modules/geom/tests/test_geom.py @@ -0,0 +1,84 @@ +#------------------------------------------------------------------------------ +# This file is part of the OpenStructure project <www.openstructure.org> +# +# Copyright (C) 2008-2011 by the OpenStructure authors +# +# This library is free software; you can redistribute it and/or modify it under +# the terms of the GNU Lesser General Public License as published by the Free +# Software Foundation; either version 3.0 of the License, or (at your option) +# any later version. +# This library is distributed in the hope that it will be useful, but WITHOUT +# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS +# FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more +# details. +# +# You should have received a copy of the GNU Lesser General Public License +# along with this library; if not, write to the Free Software Foundation, Inc., +# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA +#------------------------------------------------------------------------------ + +import unittest +if __name__== '__main__': + import sys + sys.path.insert(0,"../../../stage/lib64/openstructure/") + sys.path.insert(0,"../../../stage/lib/openstructure/") + +import ost +import ost.geom as geom + +class TestGeom(unittest.TestCase): + def runTest(self): + self.test_repr() + self.test_data() + + def test_repr(self): + v=geom.Vec2(1,2) + v2=eval(repr(v)) + self.assertTrue(geom.Equal(v, v2)) + + v=geom.Vec3(1,2,3) + v2=eval(repr(v)) + self.assertTrue(geom.Equal(v, v2)) + + v=geom.Vec4(1,2,3,4) + v2=eval(repr(v)) + self.assertTrue(geom.Equal(v, v2)) + + m=geom.Mat2(1,2,3,4) + m2=eval(repr(m)) + self.assertTrue(geom.Equal(m, m2)) + + m=geom.Mat3(1,2,3,4,5,6,7,8,9) + m2=eval(repr(m)) + self.assertTrue(geom.Equal(m, m2)) + + m=geom.Mat4(1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16) + m2=eval(repr(m)) + self.assertTrue(geom.Equal(m, m2)) + + def test_data(self): + self.assertEqual(geom.Vec2(1,2).data,[1,2]) + self.assertEqual(geom.Vec3(1,2,3).data,[1,2,3]) + self.assertEqual(geom.Vec4(1,2,3,4).data,[1,2,3,4]) + self.assertEqual(geom.Mat2(1,2, + 3,4).data, + [1,2, + 3,4]) + self.assertEqual(geom.Mat3(1,2,3, + 4,5,6, + 7,8,9).data, + [1,2,3, + 4,5,6, + 7,8,9]) + self.assertEqual(geom.Mat4(1,2,3,4, + 5,6,7,8, + 9,10,11,12, + 13,14,15,16).data, + [1,2,3,4, + 5,6,7,8, + 9,10,11,12, + 13,14,15,16]) + +if __name__== '__main__': + unittest.main() + diff --git a/modules/geom/tests/test_repr.py b/modules/geom/tests/test_repr.py deleted file mode 100644 index e69358f20f783c7f8b731de7f13deb569105a0fa..0000000000000000000000000000000000000000 --- a/modules/geom/tests/test_repr.py +++ /dev/null @@ -1,39 +0,0 @@ -import unittest -from ost import geom - -class TestRepr(unittest.TestCase): - def testReprVec2(self): - v=geom.Vec2(1,2) - v2=eval(repr(v)) - assert geom.Equal(v, v2) - - def testReprVec3(self): - v=geom.Vec3(1,2,3) - v2=eval(repr(v)) - assert geom.Equal(v, v2) - - def testReprVec4(self): - v=geom.Vec4(1,2,3,4) - v2=eval(repr(v)) - assert geom.Equal(v, v2) - - def testReprMat2(self): - m=geom.Mat2(1,2,3,4) - m2=eval(repr(m)) - assert geom.Equal(m, m2) - - def testReprMat3(self): - m=geom.Mat3(1,2,3,4,5,6,7,8,9) - m2=eval(repr(m)) - assert geom.Equal(m, m2) - - def testReprMat4(self): - m=geom.Mat4(1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16) - m2=eval(repr(m)) - assert geom.Equal(m, m2) - -if __name__ == "__main__": - try: - unittest.main() - except Exception, e: - print e \ No newline at end of file diff --git a/modules/gfx/pymod/CMakeLists.txt b/modules/gfx/pymod/CMakeLists.txt index 210cce509623565695582e20969f818e8f2e042d..a3d8b251dda72f07f6e7394ad4fb3d0996fb4bd4 100644 --- a/modules/gfx/pymod/CMakeLists.txt +++ b/modules/gfx/pymod/CMakeLists.txt @@ -14,13 +14,14 @@ set(OST_GFX_PYMOD_SOURCES export_gradient.cc export_color_ops.cc export_glwin_base.cc + export_exporter.cc ) if (ENABLE_IMG) set(OST_GFX_PYMOD_SOURCES ${OST_GFX_PYMOD_SOURCES} export_map.cc) endif() -pymod(NAME gfx CPP ${OST_GFX_PYMOD_SOURCES} PY __init__.py) +pymod(NAME gfx CPP ${OST_GFX_PYMOD_SOURCES} PY __init__.py py_gfx_obj.py) set(GRADIENT_FILE gradients.xml diff --git a/modules/gfx/pymod/__init__.py b/modules/gfx/pymod/__init__.py index ab6f3d27baf4440029f9abc7262c1fd974354774..be887c4ab071e3c4f2da12a771e7e1edad6b8b30 100644 --- a/modules/gfx/pymod/__init__.py +++ b/modules/gfx/pymod/__init__.py @@ -17,6 +17,7 @@ # 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA #------------------------------------------------------------------------------ from _ost_gfx import * +from py_gfx_obj import PyGfxObj WHITE=Color(1.0,1.0,1.0) BLACK=Color(0.0,0.0,0.0) @@ -202,7 +203,7 @@ def _primlist_add_point(self,pos,color=None): color=WHITE self._add_point(pos,color) -def _primlist_add_line(self,pos1,pos2,color=None,color1=None,color2=None): +def _primlist_add_line(self,pos1,pos2,color1=None,color2=None,color=None): pos1=_to_vec3(pos1) pos2=_to_vec3(pos2) if not color: @@ -210,7 +211,7 @@ def _primlist_add_line(self,pos1,pos2,color=None,color1=None,color2=None): if not color1: color1=color if not color2: - color2=color + color2=color1 self._add_line(pos1,pos2,color1,color2) def _primlist_add_sphere(self,cen,radius=1.0,color=None): @@ -219,7 +220,7 @@ def _primlist_add_sphere(self,cen,radius=1.0,color=None): color=WHITE self._add_sphere(pos,radius,color) -def _primlist_add_cyl(self,pos1,pos2,radius=None,radius1=None,radius2=None,color=None,color1=None,color2=None): +def _primlist_add_cyl(self,pos1,pos2,radius1=None,radius2=None,radius=None,color1=None,color2=None,color=None,): pos1=_to_vec3(pos1) pos2=_to_vec3(pos2) if radius is None: @@ -227,13 +228,13 @@ def _primlist_add_cyl(self,pos1,pos2,radius=None,radius1=None,radius2=None,color if radius1 is None: radius1=radius if radius2 is None: - radius2=radius + radius2=radius1 if not color: color=WHITE if not color1: color1=color if not color2: - color2=color + color2=color1 self._add_cyl(pos1,pos2,radius1,radius2,color1,color2) def _primlist_add_text(self,text,pos,color=None,point_size=None): @@ -243,7 +244,7 @@ def _primlist_add_text(self,text,pos,color=None,point_size=None): if not point_size: point_size=1.0 self._add_text(text,pos,color,point_size) - + PrimList.AddPoint=_primlist_add_point PrimList.AddLine=_primlist_add_line PrimList.AddSphere=_primlist_add_sphere diff --git a/modules/gfx/pymod/export_entity.cc b/modules/gfx/pymod/export_entity.cc index 0767825bdb12415a5eca9477e5ea5f56e20b7015..6202bd1cc4d353d61b673c78d68b402ecbc7b137 100644 --- a/modules/gfx/pymod/export_entity.cc +++ b/modules/gfx/pymod/export_entity.cc @@ -338,12 +338,14 @@ void export_Entity() .def("BlurSnapshot", &Entity::BlurSnapshot) .def("SetBlurFactors",&Entity::SetBlurFactors) .def("SetBlur",&Entity::SetBlur) - .def("GetBoundingBox",&Entity::GetBoundingBox) + .def("GetBoundingBox",&Entity::GetBoundingBox) + .add_property("bounding_box",&Entity::GetBoundingBox) .def("SetSelection",&Entity::SetSelection) .def("GetSelection",&Entity::GetSelection) .add_property("selection", &Entity::GetSelection, &set_selection) .def("GetView", &Entity::GetView) + .add_property("view",&Entity::GetView) .def("UpdateView", &Entity::UpdateView) .def("SetQuery", set_query) .def("SetQueryView",&Entity::SetQueryView) @@ -356,7 +358,6 @@ void export_Entity() .def("SetRenderMode", set_rm3, (arg("mode"), arg("sel"), arg("keep")=false)) .def("SetEnableRenderMode", &Entity::SetEnableRenderMode) .def("IsRenderModeEnabled", &Entity::IsRenderModeEnabled) - .add_property("view", &Entity::GetView) .def("SetVisible", set_vis1, (arg("view"), arg("flag")=true)) .def("SetVisible", set_vis2, (arg("sel"), arg("flag")=true)) .def("ColorBy", color_by_01) diff --git a/modules/gfx/pymod/export_exporter.cc b/modules/gfx/pymod/export_exporter.cc new file mode 100644 index 0000000000000000000000000000000000000000..655fe54f77282e2d6656142addf51e18006d7f7c --- /dev/null +++ b/modules/gfx/pymod/export_exporter.cc @@ -0,0 +1,38 @@ +//------------------------------------------------------------------------------ +// This file is part of the OpenStructure project <www.openstructure.org> +// +// Copyright (C) 2008-2011 by the OpenStructure authors +// +// This library is free software; you can redistribute it and/or modify it under +// the terms of the GNU Lesser General Public License as published by the Free +// Software Foundation; either version 3.0 of the License, or (at your option) +// any later version. +// This library is distributed in the hope that it will be useful, but WITHOUT +// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS +// FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more +// details. +// +// You should have received a copy of the GNU Lesser General Public License +// along with this library; if not, write to the Free Software Foundation, Inc., +// 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA +//------------------------------------------------------------------------------ +#include <boost/python.hpp> +using namespace boost::python; + +#include <ost/gfx/exporter.hh> +#include <ost/gfx/gost_exporter.hh> +#include <ost/gfx/collada_exporter.hh> + +using namespace ost; +using namespace ost::gfx; + +void export_Exporter() +{ + class_<Exporter, boost::noncopyable>("Exporter", no_init); + + class_<GostExporter, bases<Exporter>, boost::noncopyable>("GostExporter", init<const std::string&>()) + ; + + class_<ColladaExporter, bases<Exporter>, boost::noncopyable>("ColladaExporter", init<const std::string&, optional<float> >()) + ; +} diff --git a/modules/gfx/pymod/export_gfx_obj.cc b/modules/gfx/pymod/export_gfx_obj.cc index 70458055914d2e74f399c318eae2b398e98a2943..f9caac28c0d4c9181e29dd1aa01ca5ca84d04cd6 100644 --- a/modules/gfx/pymod/export_gfx_obj.cc +++ b/modules/gfx/pymod/export_gfx_obj.cc @@ -58,6 +58,63 @@ namespace { LOG_INFO("AALines(bool) is deprecated, use SetAALines(bool) instead"); b->SetAALines(f); } + + class GfxObjWrap: public GfxObj, public wrapper<GfxObj> + { + public: + GfxObjWrap(const std::string& name): + GfxObj(name) + {} + + virtual geom::AlignedCuboid GetBoundingBox() const + { + if(override f = this->get_override("GetBoundingBox")) { + return f(); + } else { + return GfxObj::GetBoundingBox(); + } + } + + geom::AlignedCuboid default_GetBoundingBox() const { + return GfxObj::GetBoundingBox(); + } + + virtual void CustomRenderGL(RenderPass pass) { + if(override f = this->get_override("_CustomRenderGL")) { + f(pass); + } else { + GfxObj::CustomRenderGL(pass); + } + } + + void default_CustomRenderGL(RenderPass pass) { + GfxObj::CustomRenderGL(pass); + } + + virtual void CustomPreRenderGL(bool rebuild) { + if(override f = this->get_override("_CustomPreRenderGL")) { + f(rebuild); + } else { + GfxObj::CustomPreRenderGL(rebuild); + } + } + + void default_CustomPreRenderGL(bool rebuild) { + GfxObj::CustomPreRenderGL(rebuild); + } + + virtual void InitGL() { + if(override f = this->get_override("_InitGL")) { + f(); + } else { + GfxObj::InitGL(); + } + } + + void default_InitGL() { + GfxObj::InitGL(); + } + }; } void export_GfxObj() @@ -77,26 +134,38 @@ void export_GfxObj() .def("ContextSwitch", &GfxObjBase::ContextSwitch) .def("SetRenderMode", &GfxObjBase::SetRenderMode) .def("GetRenderMode", &GfxObjBase::GetRenderMode) - .def("GetCenter",&GfxObjBase::GetCenter) + .def("GetCenter",&GfxObjBase::GetCenter) + .add_property("center", &GfxObjBase::GetCenter) .def("SetLineWidth", &GfxObjBase::SetLineWidth) .def("SetPolyMode",&GfxObjBase::SetPolyMode) - .def("AALines",set_aalines) + .def("AALines",set_aalines) /* deprecated */ .def("SetAALines",&GfxObjBase::SetAALines) .def("SetLineHalo",&GfxObjBase::SetLineHalo) - .def("Outline",set_outline) + .def("Outline",set_outline) /* deprecated */ .def("SetOutline",&GfxObjBase::SetOutline) + .def("GetOutline",&GfxObjBase::GetOutline) + .add_property("outline",&GfxObjBase::GetOutline,&GfxObjBase::SetOutline) .def("SetOutlineMode",&GfxObjBase::SetOutlineMode) + .add_property("outline_mode",&GfxObjBase::GetOutlineMode,&GfxObjBase::SetOutlineMode) .def("SetOutlineWidth",&GfxObjBase::SetOutlineWidth) + .add_property("outline_width",&GfxObjBase::GetOutlineWidth,&GfxObjBase::SetOutlineWidth) .def("SetOutlineExpandFactor",&GfxObjBase::SetOutlineExpandFactor) + .add_property("outline_expand_factor",&GfxObjBase::GetOutlineExpandFactor,&GfxObjBase::SetOutlineExpandFactor) .def("SetOutlineExpandColor",&GfxObjBase::SetOutlineExpandColor) + .add_property("outline_expand_color",&GfxObjBase::GetOutlineExpandColor,&GfxObjBase::SetOutlineExpandColor) + .add_property("outline_color",&GfxObjBase::GetOutlineExpandColor,&GfxObjBase::SetOutlineExpandColor) .def("SetOpacity",&GfxObjBase::SetOpacity) .def("GetOpacity",&GfxObjBase::GetOpacity) - .add_property("center", &GfxObjBase::GetCenter) + .add_property("opacity",&GfxObjBase::GetOpacity,&GfxObjBase::SetOpacity) COLOR_BY_DEF() ; - //register_ptr_to_python<GfxObjBaseP>(); - class_<GfxObj, boost::shared_ptr<GfxObj>, bases<GfxObjBase>, boost::noncopyable>("GfxObj",no_init) + enum_<RenderPass>("RenderPass") + .value("STANDARD_RENDER_PASS",STANDARD_RENDER_PASS) + .value("TRANSPARENT_RENDER_PASS",TRANSPARENT_RENDER_PASS) + ; + + class_<GfxObjWrap, boost::shared_ptr<GfxObj>, bases<GfxObjBase>, boost::noncopyable>("GfxObj",init<const std::string&>()) .def("GetTF", &GfxObj::GetTF, return_value_policy<copy_const_reference>()) .def("SetTF", &GfxObj::SetTF) .def("FlagRebuild",&GfxObj::FlagRebuild) @@ -108,7 +177,10 @@ void export_GfxObj() .def("GetAALines",&GfxObj::GetAALines) .def("GetLineWidth",&GfxObj::GetLineWidth) .def("GetLineHalo",&GfxObj::GetLineHalo) - ; - //register_ptr_to_python<GfxObjP>(); + .def("GetBoundingBox",&GfxObj::GetBoundingBox, &GfxObjWrap::default_GetBoundingBox) + .def("_CustomRenderGL",&GfxObj::CustomRenderGL, &GfxObjWrap::default_CustomRenderGL) + .def("_CustomPreRenderGL",&GfxObj::CustomPreRenderGL, &GfxObjWrap::default_CustomPreRenderGL) + .def("_InitGL",&GfxObj::InitGL, &GfxObjWrap::default_InitGL) + ; } diff --git a/modules/gfx/pymod/export_gradient.cc b/modules/gfx/pymod/export_gradient.cc index e24cc9cee5fec611fc536b8c0ab5a4e95c3712a1..6cb26cee020a295eb56111aa4101d189470eadc3 100644 --- a/modules/gfx/pymod/export_gradient.cc +++ b/modules/gfx/pymod/export_gradient.cc @@ -26,7 +26,7 @@ using namespace ost; using namespace ost::gfx; namespace { - Gradient* make_gradient(const dict& d) + Gradient* make_gradient_d(const dict& d) { std::auto_ptr<Gradient> grad(new Gradient); list keys = d.keys(); @@ -57,13 +57,42 @@ namespace { } return grad.release(); } + + Gradient* make_gradient_l(const list& l) + { + std::auto_ptr<Gradient> grad(new Gradient); + float mf = len(l)<2 ? 0.0 : 1.0/static_cast<float>(len(l)-1); + for(int i=0;i<len(l);++i) { + float mark = static_cast<float>(i)*mf; + Color col; + object val = l[i]; + extract<Color> cex(val); + if(cex.check()) { + // use gfx.Color + col=cex(); + } else { + // try simple sequence + if(len(val)!=3) { + throw std::runtime_error("expected values of gfx.Color or float triplets"); + } + try { + col=gfx::Color(extract<float>(val[0]),extract<float>(val[1]),extract<float>(val[2])); + } catch (...) { + throw std::runtime_error("expected values of gfx.Color or float triplets"); + } + } + grad->SetColorAt(mark,col); + } + return grad.release(); + } } void export_gradient() { class_<Gradient>("Gradient", init<>()) .def(init<const String&>()) - .def("__init__", make_constructor(make_gradient)) + .def("__init__", make_constructor(make_gradient_d)) + .def("__init__", make_constructor(make_gradient_l)) .def("SetColorAt", &Gradient::SetColorAt) .def("GetColorAt", &Gradient::GetColorAt) .def("GetStops", &Gradient::GetStops) diff --git a/modules/gfx/pymod/export_primitives.cc b/modules/gfx/pymod/export_primitives.cc index 91ce753ed91df2006caf3928438d4ed1937032cc..01b328d7288116ab8c6dcd9e7d86c5c3ad97fb07 100644 --- a/modules/gfx/pymod/export_primitives.cc +++ b/modules/gfx/pymod/export_primitives.cc @@ -25,8 +25,7 @@ using namespace ost::gfx; void export_primitives() { - class_<Primitive, boost::shared_ptr<Primitive>, - bases<GfxNode>, boost::noncopyable>("Primitive", no_init) + class_<Primitive, bases<GfxNode>, boost::noncopyable>("Primitive", no_init) .def("HasOutline", &Primitive::HasOutline) .def("HasFill", &Primitive::HasFill) .def("SetFill", &Primitive::SetFill) @@ -40,10 +39,10 @@ void export_primitives() .def("GetOutlineColor", &Primitive::GetOutlineColor, return_value_policy<copy_const_reference>()) ; - class_<Cuboid, boost::shared_ptr<Cuboid>, bases<Primitive>, + class_<Cuboid, bases<Primitive>, boost::noncopyable>("Cuboid", init<const String&, const geom::Cuboid>()) ; - class_<Quad, boost::shared_ptr<Quad>, bases<Primitive>, + class_<Quad, bases<Primitive>, boost::noncopyable>("Quad", init<const String&, const geom::Vec3&, const geom::Vec3&, const geom::Vec3&, const geom::Vec3&>()) diff --git a/modules/gfx/pymod/export_primlist.cc b/modules/gfx/pymod/export_primlist.cc index b8326509d8ed7065f120ab4760a541b5766e207b..bb986d7e14c1580555d2bb3b4db2fb497c1c9fcc 100644 --- a/modules/gfx/pymod/export_primlist.cc +++ b/modules/gfx/pymod/export_primlist.cc @@ -25,8 +25,90 @@ using namespace boost::python; using namespace ost; using namespace ost::gfx; +#if OST_NUMPY_SUPPORT_ENABLED +#include <numpy/arrayobject.h> +#endif + +namespace { + void add_mesh(PrimList& p, object ova, object ona, object oca, object oia) + { +#if OST_NUMPY_SUPPORT_ENABLED + if(!PyArray_Check(ova.ptr())) { + throw std::runtime_error("ova is not a numpy array"); + } + PyArrayObject* va=reinterpret_cast<PyArrayObject*>(ova.ptr()); + if(!PyArray_ISCONTIGUOUS(va)) { + throw std::runtime_error("expected vertex array to be contiguous"); + } + if(!PyArray_TYPE(va)==NPY_FLOAT) { + throw std::runtime_error("expected vertex array to be of dtype=float32"); + } + size_t v_size=PyArray_SIZE(va); + if(v_size%3!=0) { + throw std::runtime_error("expected vertex array size to be divisible by 3"); + } + size_t v_count=v_size/3; + float* vp=reinterpret_cast<float*>(PyArray_DATA(va)); + float* np=0; + float* cp=0; + if(ona!=object()) { + if(!PyArray_Check(ona.ptr())) { + throw std::runtime_error("ona is not a numpy array"); + } + PyArrayObject* na=reinterpret_cast<PyArrayObject*>(ona.ptr()); + if(!PyArray_ISCONTIGUOUS(na)) { + throw std::runtime_error("expected normal array to be contiguous"); + } + if(!PyArray_TYPE(na)==NPY_FLOAT) { + throw std::runtime_error("expected normal array to be of dtype=float32"); + } + if(PyArray_SIZE(na)!=v_size) { + throw std::runtime_error("expected normal array size to match vertex array size"); + } + np=reinterpret_cast<float*>(PyArray_DATA(na)); + } + if(oca!=object()) { + if(!PyArray_Check(oca.ptr())) { + throw std::runtime_error("oca is not a numpy array"); + } + PyArrayObject* ca=reinterpret_cast<PyArrayObject*>(oca.ptr()); + if(!PyArray_ISCONTIGUOUS(ca)) { + throw std::runtime_error("expected color array to be contiguous"); + } + if(!PyArray_TYPE(ca)==NPY_FLOAT) { + throw std::runtime_error("expected color array to be of dtype=float32"); + } + if(PyArray_SIZE(ca)!=v_count*4) { + throw std::runtime_error("expected color array size to equal vertex-count x 4"); + } + cp=reinterpret_cast<float*>(PyArray_DATA(ca)); + } + if(!PyArray_Check(oia.ptr())) { + throw std::runtime_error("oia is not a numpy array"); + } + PyArrayObject* ia=reinterpret_cast<PyArrayObject*>(oia.ptr()); + if(!PyArray_ISCONTIGUOUS(ia)) { + throw std::runtime_error("expected vertex array to be contiguous"); + } + if(!PyArray_TYPE(ia)==NPY_UINT) { + throw std::runtime_error("expected vertex array to be of dtype=uint32"); + } + size_t i_size=PyArray_SIZE(ia); + unsigned int* ip=reinterpret_cast<unsigned int*>(PyArray_DATA(ia)); + + p.AddMesh(vp,np,cp,v_count,ip,i_size/3); +#else + throw std::runtime_error("AddMesh requires compiled-in numpy support"); +#endif + } +} + void export_primlist() { +#if OST_NUMPY_SUPPORT_ENABLED + import_array(); // magic handshake for numpy module +#endif + class_<PrimList, bases<GfxObj>, boost::shared_ptr<PrimList>, boost::noncopyable>("PrimList", init<const String& >()) .def("Clear",&PrimList::Clear) .def("_add_line",&PrimList::AddLine) @@ -34,6 +116,7 @@ void export_primlist() .def("_add_sphere",&PrimList::AddSphere) .def("_add_cyl",&PrimList::AddCyl) .def("_add_text",&PrimList::AddText) + .def("AddMesh",add_mesh) .def("SetColor",&PrimList::SetColor) .def("SetDiameter",&PrimList::SetDiameter) .def("SetRadius",&PrimList::SetRadius) diff --git a/modules/gfx/pymod/export_scene.cc b/modules/gfx/pymod/export_scene.cc index f5692fad5b197d02c94f024add51392e78f72b2b..8b73a3391ec8a0a8ac5f4e41357b17738320d1d2 100644 --- a/modules/gfx/pymod/export_scene.cc +++ b/modules/gfx/pymod/export_scene.cc @@ -21,6 +21,7 @@ using namespace boost::python; #include <ost/gfx/gfx_object.hh> #include <ost/gfx/scene.hh> +#include <ost/gfx/exporter.hh> using namespace ost; using namespace ost::gfx; @@ -63,6 +64,7 @@ void export_Scene() void (Scene::* export1)(const String&, uint, uint, bool) = &Scene::Export; void (Scene::* export2)(const String&, bool) = &Scene::Export; + void (Scene::* export3)(Exporter*) const = &Scene::Export; void (Scene::*remove1)(const GfxNodeP&) = &Scene::Remove; void (Scene::*remove2)(const String&) = &Scene::Remove; void (Scene::*center_on1)(const String&) = &Scene::CenterOn; @@ -116,6 +118,7 @@ void export_Scene() .def("SetFogColor",&Scene::SetFogColor) .def("GetFogColor",&Scene::GetFogColor) .add_property("fogcol", &Scene::GetFogColor, &Scene::SetFogColor) + .add_property("fog_color", &Scene::GetFogColor, &Scene::SetFogColor) .def("SetFOV",&Scene::SetFOV) .def("GetFOV",&Scene::GetFOV) .add_property("fov", &Scene::GetFOV, &Scene::SetFOV) @@ -159,8 +162,9 @@ void export_Scene() .def("SetLightProp",set_light_prop1) .def("SetLightProp",set_light_prop2) .def("Apply", apply) - .def("Export",export1, arg("transparent")=true) - .def("Export",export2, arg("transparent")=true) + .def("Export",export1, arg("transparent")=false) + .def("Export",export2, arg("transparent")=false) + .def("Export",export3) .def("ExportPov",&Scene::ExportPov, scene_export_pov_overloads()) .def("PushView",&Scene::PushView) @@ -169,14 +173,25 @@ void export_Scene() .def("BlurSnapshot",&Scene::BlurSnapshot) .def("RemoveAll", &Scene::RemoveAll) .def("SetShadow",&Scene::SetShadow) + .add_property("shadow",&Scene::GetShadow,&Scene::SetShadow) .def("SetShadowQuality",&Scene::SetShadowQuality) + .add_property("shadow_quality",&Scene::GetShadowQuality,&Scene::SetShadowQuality) .def("SetShadowWeight",&Scene::SetShadowWeight) + .add_property("shadow_weight",&Scene::GetShadowWeight,&Scene::SetShadowWeight) .def("SetDepthDarkening",&Scene::SetDepthDarkening) .def("SetDepthDarkeningWeight",&Scene::SetDepthDarkeningWeight) .def("SetAmbientOcclusion",&Scene::SetAmbientOcclusion) + .add_property("ambient_occlusion",&Scene::GetAmbientOcclusion,&Scene::SetAmbientOcclusion) + .add_property("ao",&Scene::GetAmbientOcclusion,&Scene::SetAmbientOcclusion) .def("SetAmbientOcclusionWeight",&Scene::SetAmbientOcclusionWeight) + .add_property("ambient_occlusion_weight",&Scene::GetAmbientOcclusionWeight,&Scene::SetAmbientOcclusionWeight) + .add_property("ao_weight",&Scene::GetAmbientOcclusionWeight,&Scene::SetAmbientOcclusionWeight) .def("SetAmbientOcclusionMode",&Scene::SetAmbientOcclusionMode) + .add_property("ambient_occlusion_mode",&Scene::GetAmbientOcclusionMode,&Scene::SetAmbientOcclusionMode) + .add_property("ao_mode",&Scene::GetAmbientOcclusionMode,&Scene::SetAmbientOcclusionMode) .def("SetAmbientOcclusionQuality",&Scene::SetAmbientOcclusionQuality) + .add_property("ambient_occlusion_quality",&Scene::GetAmbientOcclusionQuality,&Scene::SetAmbientOcclusionQuality) + .add_property("ao_quality",&Scene::GetAmbientOcclusionQuality,&Scene::SetAmbientOcclusionQuality) .def("AttachObserver",&Scene::AttachObserver) .def("StartOffscreenMode",&Scene::StartOffscreenMode) .def("StopOffscreenMode",&Scene::StopOffscreenMode) @@ -185,5 +200,7 @@ void export_Scene() .add_property("root_node", &Scene::GetRootNode) .def("SetBeaconOff",&Scene::SetBeaconOff) .def("__getitem__",scene_getitem) + .add_property("show_center",&Scene::GetShowCenter, &Scene::SetShowCenter) + .add_property("fix_center",&Scene::GetFixCenter, &Scene::SetFixCenter) ; } diff --git a/modules/gfx/pymod/py_gfx_obj.py b/modules/gfx/pymod/py_gfx_obj.py new file mode 100644 index 0000000000000000000000000000000000000000..ac91e9073a47b061ee57145e0d3d7b6b6a51dcc5 --- /dev/null +++ b/modules/gfx/pymod/py_gfx_obj.py @@ -0,0 +1,79 @@ +#------------------------------------------------------------------------------ +# This file is part of the OpenStructure project <www.openstructure.org> +# +# Copyright (C) 2008-2011 by the OpenStructure authors +# +# This library is free software; you can redistribute it and/or modify it under +# the terms of the GNU Lesser General Public License as published by the Free +# Software Foundation; either version 3.0 of the License, or (at your option) +# any later version. +# This library is distributed in the hope that it will be useful, but WITHOUT +# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS +# FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more +# details. +# +# You should have received a copy of the GNU Lesser General Public License +# along with this library; if not, write to the Free Software Foundation, Inc., +# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA +#------------------------------------------------------------------------------ +import traceback +from _ost_gfx import * + +class PyGfxObj(GfxObj): + def __init__(self,name): + """ + requires a unique name not yet utilized in the Scene; + do not place OpenGL calls in the ctor, use InitGL for + that purpose + """ + GfxObj.__init__(self,name) + self._valid_flag=False + + def _InitGL(self): + try: + self.InitGL() + self._valid_flag=True + except: + traceback.print_exc() + + def InitGL(self): + """ + called once for each OpenGL context (usually one time), + allows one-time OpenGL initialization to be implemented, + such as vbo allocation + """ + pass + + + def _CustomPreRenderGL(self,rebuild): + if not self._valid_flag: + return + try: + self.CustomPreRenderGL(rebuild) + except: + self._valid_flag=False + traceback.print_exc() + + def CustomPreRenderGL(self,rebuild): + """ + called just before CustomRenderGL is called; the flag + indicates that a rebuild is required or was requested + """ + pass + + + def _CustomRenderGL(self,render_pass): + if not self._valid_flag: + return + try: + self.CustomRenderGL(render_pass) + except: + self._valid_flag=False + traceback.print_exc() + + def CustomRenderGL(self,render_pass): + """ + called for each scene refresh + """ + pass + diff --git a/modules/gfx/pymod/wrap_gfx.cc b/modules/gfx/pymod/wrap_gfx.cc index 0198d3a0fb27ae5869ff572b9335e6580737b8e9..28229edf12ada259a25443f363d43db51199291d 100644 --- a/modules/gfx/pymod/wrap_gfx.cc +++ b/modules/gfx/pymod/wrap_gfx.cc @@ -37,6 +37,8 @@ extern void export_primlist(); extern void export_primitives(); extern void export_color(); extern void export_gradient(); +extern void export_Exporter(); + #if OST_IMG_ENABLED extern void export_Map(); #endif @@ -135,6 +137,8 @@ BOOST_PYTHON_MODULE(_ost_gfx) ; #endif + export_primitives(); + export_Exporter(); } diff --git a/modules/gfx/src/CMakeLists.txt b/modules/gfx/src/CMakeLists.txt index 4f23812fd1120c170b45ff54ace477657314d9f2..9309a6af7ebec7fed643e303a732bf1b0c53b4ab 100644 --- a/modules/gfx/src/CMakeLists.txt +++ b/modules/gfx/src/CMakeLists.txt @@ -1,6 +1,7 @@ set(OST_GFX_HEADERS render_pass.hh bitmap_io.hh +collada_exporter.hh color.hh entity.hh entity_fw.hh @@ -37,6 +38,9 @@ module_config.hh primitives.hh povray_fw.hh povray.hh +exporter.hh +exporter_fw.hh +gost_exporter.hh ) set(OST_GFX_COLOR_OPS_HEADERS @@ -89,6 +93,7 @@ endif() set(OST_GFX_SOURCES bitmap_io.cc +collada_exporter.cc color.cc primitives.cc entity.cc @@ -108,6 +113,7 @@ vertex_array.cc vertex_array_helper.cc material.cc povray.cc +gost_exporter.cc texture.cc color_ops/color_op.cc color_ops/by_element_color_op.cc diff --git a/modules/gfx/src/collada_exporter.cc b/modules/gfx/src/collada_exporter.cc new file mode 100644 index 0000000000000000000000000000000000000000..902334f851fc0df651f58f380e3c3771e8ae1e96 --- /dev/null +++ b/modules/gfx/src/collada_exporter.cc @@ -0,0 +1,279 @@ +//------------------------------------------------------------------------------ +// This file is part of the OpenStructure project <www.openstructure.org> +// +// Copyright (C) 2008-2011 by the OpenStructure authors +// +// This library is free software; you can redistribute it and/or modify it under +// the terms of the GNU Lesser General Public License as published by the Free +// Software Foundation; either version 3.0 of the License, or (at your option) +// any later version. +// This library is distributed in the hope that it will be useful, but WITHOUT +// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS +// FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more +// details. +// +// You should have received a copy of the GNU Lesser General Public License +// along with this library; if not, write to the Free Software Foundation, Inc., +// 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA +//------------------------------------------------------------------------------ + +/* + Author: Ansgar Philippsen +*/ + +#include <sstream> +#include <boost/format.hpp> + +#include "collada_exporter.hh" +#include "scene.hh" + +namespace ost { namespace gfx { + +ColladaExporter::ColladaExporter(const std::string& file, float scale): + file_(file), + out_(file_.c_str()), + scale_(scale), + obj_() +{ + out_ << "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n"; + out_ << "<COLLADA version=\"1.4.0\" xmlns=\"http://www.collada.org/2005/11/COLLADASchema\">\n"; +} + +ColladaExporter::~ColladaExporter() +{ + out_ << "</COLLADA>\n"; +} + +void ColladaExporter::SceneStart(const Scene* scene) +{ + out_ << " <library_cameras>\n"; + out_ << " <camera id=\"Camera-Camera\" name=\"Camera-Camera\">\n"; + out_ << " <optics>\n"; + out_ << " <technique_common>\n"; + out_ << " <perspective>\n"; + out_ << " <yfov>" << scene->GetFOV() << "</yfov>\n"; + out_ << " <znear>" << scene->GetNear() << "</znear>\n"; + out_ << " <zfar>" << scene->GetFar() << "</zfar>\n"; + out_ << " </perspective>\n"; + out_ << " </technique_common>\n"; + out_ << " </optics>\n"; + out_ << " </camera>\n"; + out_ << " </library_cameras>\n"; + + out_ << " <library_geometries>\n" << std::endl; +} + +void ColladaExporter::SceneEnd(const Scene* scene) +{ + out_ << " </library_geometries>\n" << std::endl; + + out_ << " <library_visual_scenes>\n"; + out_ << " <visual_scene id=\"Scene\" name=\"Scene\">\n"; + + out_ << " <node id=\"Camera\" name=\"Camera\">\n"; + out_ << " <instance_camera url=\"#Camera-Camera\"/>\n"; + out_ << " </node>\n"; + + out_ << " <node id=\"Root\" name=\"Root\">\n"; + out_ << " <matrix>\n"; + geom::Mat4 tm=scene->GetTransform().GetMatrix(); + out_ << " " << tm(0,0) << " " << tm(0,1) << " " << tm(0,2) << " " << tm(0,3) << "\n"; + out_ << " " << tm(1,0) << " " << tm(1,1) << " " << tm(1,2) << " " << tm(1,3) << "\n"; + out_ << " " << tm(2,0) << " " << tm(2,1) << " " << tm(2,2) << " " << tm(2,3) << "\n"; + out_ << " " << tm(3,0) << " " << tm(3,1) << " " << tm(3,2) << " " << tm(3,3) << "\n"; + out_ << " </matrix>\n"; + for(std::vector<std::string>::const_iterator oit=obj_.begin();oit!=obj_.end();++oit) { + out_ << " <node id=\"" << *oit << "\" name=\"" << *oit <<"\">\n"; + out_ << " <instance_geometry url=\"#" << *oit << "\"/>\n"; + out_ << " </node>\n"; + } + out_ << " </node>\n"; + out_ << " </visual_scene>\n"; + out_ << " </library_visual_scenes>\n"; + + out_ << " <scene>\n"; + out_ << " <instance_visual_scene url=\"#Scene\"/>\n"; + out_ << " </scene>\n"; +} + +void ColladaExporter::NodeStart(const std::string& name, NodeType t) +{ + if(name!="Scene") { + obj_.push_back(name); + out_ << "<geometry id=\"" << name << "\" name=\"" << name << "\">\n"; + out_ << " <mesh>\n"; + } +} + +void ColladaExporter::NodeEnd(const std::string& name) +{ + if(name!="Scene") { + out_ << " </mesh>\n"; + out_ << "</geometry>\n"; + } +} + +void ColladaExporter::WriteVertexData(const float* vdata, + const float* ndata, + const float* cdata, + const float* tdata, + size_t stride2, size_t count) +{ + std::string name=obj_.back(); + size_t stride=stride2/sizeof(float); + + out_ << " <source id=\"" << name+"-Positions" << "\">\n"; + out_ << " <float_array count=\"" << count*3 << "\" id=\"" << name+"-Positions-array" << "\">\n"; + if(vdata) { + const float* src=vdata; + for(unsigned int i=0;i<count;++i) { + out_ << scale_*src[0] << " "; + out_ << scale_*src[1] << " "; + out_ << scale_*src[2] << " "; + src+=stride; + } + } else { + for(unsigned int i=0;i<count;++i) { + out_ << "0.0 0.0 0.0 "; + } + } + out_ << " </float_array>\n"; + out_ << " <technique_common>\n"; + out_ << " <accessor count=\"" << count << "\" source=\"#" << name + "-Positions-array" << "\" stride=\"3\">\n"; + out_ << " <param name=\"X\" type=\"float\"/>\n"; + out_ << " <param name=\"Y\" type=\"float\"/>\n"; + out_ << " <param name=\"Z\" type=\"float\"/>\n"; + out_ << " </accessor>\n"; + out_ << " </technique_common>\n"; + out_ << " </source>\n"; + + // normals, lots of code duplication for now + out_ << " <source id=\"" << name+"-Normals" << "\">\n"; + out_ << " <float_array count=\"" << count*3 << "\" id=\"" << name+"-Normals-array" << "\">\n"; + if(ndata) { + const float* src=ndata; + for(unsigned int i=0;i<count;++i) { + out_ << src[0] << " "; + out_ << src[1] << " "; + out_ << src[2] << " "; + src+=stride; + } + } else { + for(unsigned int i=0;i<count;++i) { + out_ << "0.0 0.0 0.0 "; + } + } + out_ << " </float_array>\n"; + out_ << " <technique_common>\n"; + out_ << " <accessor count=\"" << count << "\" source=\"#" << name + "-Normals-array" << "\" stride=\"3\">\n"; + out_ << " <param name=\"X\" type=\"float\"/>\n"; + out_ << " <param name=\"Y\" type=\"float\"/>\n"; + out_ << " <param name=\"Z\" type=\"float\"/>\n"; + out_ << " </accessor>\n"; + out_ << " </technique_common>\n"; + out_ << " </source>\n"; + + // colors, again lots of code duplication + out_ << " <source id=\"" << name+"-Colors" << "\">\n"; + //out_ << " <float_array count=\"" << count*4 << "\" id=\"" << name+"-Colors-array" << "\">\n"; + out_ << " <float_array count=\"" << count*3 << "\" id=\"" << name+"-Colors-array" << "\">\n"; + if(cdata) { + const float* src=cdata; + for(unsigned int i=0;i<count;++i) { + out_ << src[0] << " "; + out_ << src[1] << " "; + out_ << src[2] << " "; + //out_ << src[3] << " "; + src+=stride; + } + } else { + for(unsigned int i=0;i<count;++i) { + out_ << "0.0 0.0 0.0 "; + } + } + out_ << " </float_array>\n"; + out_ << " <technique_common>\n"; + //out_ << " <accessor count=\"" << count << "\" source=\"#" << name + "-Colors-array" << "\" stride=\"4\">\n"; + out_ << " <accessor count=\"" << count << "\" source=\"#" << name + "-Colors-array" << "\" stride=\"3\">\n"; + out_ << " <param name=\"R\" type=\"float\"/>\n"; + out_ << " <param name=\"G\" type=\"float\"/>\n"; + out_ << " <param name=\"B\" type=\"float\"/>\n"; + //out_ << " <param name=\"A\" type=\"float\"/>\n"; + out_ << " </accessor>\n"; + out_ << " </technique_common>\n"; + out_ << " </source>\n"; + + out_ << " <vertices id=\"" << name+"-Vertex" << "\">\n"; + out_ << " <input semantic=\"POSITION\" source =\"#" << name+"-Positions" << "\"/>\n"; + //out_ << " <input semantic=\"NORMAL\" source =\"#" << name+"-Normals" << "\"/>\n"; + //out_ << " <input semantic=\"COLOR\" source =\"#" << name+"-Colors" << "\"/>\n"; + out_ << " </vertices>\n"; +} + +void ColladaExporter::WritePointData(const unsigned int* i, size_t count) +{ +} + +void ColladaExporter::WriteLineData(const unsigned int* ij, size_t count) +{ +} + +void ColladaExporter::WriteTriData(const unsigned int* ijk, size_t count) +{ + std::string name=obj_.back(); + + out_ << " <triangles count=\"" << count << "\">\n"; + out_ << " <input offset=\"0\" semantic=\"VERTEX\" source =\"#" << name+"-Vertex" << "\"/>\n"; + out_ << " <input offset=\"1\" semantic=\"NORMAL\" source =\"#" << name+"-Normals" << "\"/>\n"; + out_ << " <input offset=\"2\" semantic=\"COLOR\" source =\"#" << name+"-Colors" << "\"/>\n"; + out_ << " <p>\n"; + for(unsigned int c=0;c<count*3;c+=3) { + out_ << ijk[c+0] << " "; + out_ << ijk[c+0] << " "; + out_ << ijk[c+0] << " "; + out_ << ijk[c+1] << " "; + out_ << ijk[c+1] << " "; + out_ << ijk[c+1] << " "; + out_ << ijk[c+2] << " "; + out_ << ijk[c+2] << " "; + out_ << ijk[c+2] << " "; + } + out_ << " </p>\n"; + out_ << " </triangles>\n"; +} + +void ColladaExporter::WriteQuadData(const unsigned int* ijkl, size_t count) +{ + std::string name=obj_.back(); + + out_ << " <triangles count=\"" << count << "\">\n"; + out_ << " <input offset=\"0\" semantic=\"VERTEX\" source =\"#" << name+"-Vertex" << "\"/>\n"; + out_ << " <input offset=\"1\" semantic=\"NORMAL\" source =\"#" << name+"-Normals" << "\"/>\n"; + out_ << " <input offset=\"2\" semantic=\"COLOR\" source =\"#" << name+"-Colors" << "\"/>\n"; + out_ << " <p>\n"; + for(unsigned int c=0;c<count*4;c+=4) { + out_ << ijkl[c+0] << " "; + out_ << ijkl[c+0] << " "; + out_ << ijkl[c+0] << " "; + out_ << ijkl[c+1] << " "; + out_ << ijkl[c+1] << " "; + out_ << ijkl[c+1] << " "; + out_ << ijkl[c+2] << " "; + out_ << ijkl[c+2] << " "; + out_ << ijkl[c+2] << " "; + // + out_ << ijkl[c+0] << " "; + out_ << ijkl[c+0] << " "; + out_ << ijkl[c+0] << " "; + out_ << ijkl[c+2] << " "; + out_ << ijkl[c+2] << " "; + out_ << ijkl[c+2] << " "; + out_ << ijkl[c+3] << " "; + out_ << ijkl[c+3] << " "; + out_ << ijkl[c+3] << " "; + } + out_ << " </p>\n"; + out_ << " </triangles>\n"; +} + +}} // ns diff --git a/modules/gfx/src/collada_exporter.hh b/modules/gfx/src/collada_exporter.hh new file mode 100644 index 0000000000000000000000000000000000000000..c0192a10097e6cb0d2b48801431a3be2437509d5 --- /dev/null +++ b/modules/gfx/src/collada_exporter.hh @@ -0,0 +1,62 @@ +//------------------------------------------------------------------------------ +// This file is part of the OpenStructure project <www.openstructure.org> +// +// Copyright (C) 2008-2011 by the OpenStructure authors +// +// This library is free software; you can redistribute it and/or modify it under +// the terms of the GNU Lesser General Public License as published by the Free +// Software Foundation; either version 3.0 of the License, or (at your option) +// any later version. +// This library is distributed in the hope that it will be useful, but WITHOUT +// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS +// FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more +// details. +// +// You should have received a copy of the GNU Lesser General Public License +// along with this library; if not, write to the Free Software Foundation, Inc., +// 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA +//------------------------------------------------------------------------------ +#ifndef OST_GFX_COLLADA_EXPORTER_HH +#define OST_GFX_COLLADA_EXPORTER_HH + +/* + Author: Ansgar Philippsen +*/ + +#include <string> +#include <fstream> +#include <vector> + +#include "module_config.hh" +#include "exporter.hh" + +namespace ost { namespace gfx { + +class DLLEXPORT_OST_GFX ColladaExporter: public Exporter +{ +public: + ColladaExporter(const std::string& collada_file, float scale=1.0); + virtual ~ColladaExporter(); + + // exporter interface + virtual void SceneStart(const Scene* scene); + virtual void SceneEnd(const Scene* scene); + virtual void NodeStart(const std::string& name, NodeType t); + virtual void NodeEnd(const std::string& name); + virtual void WriteVertexData(const float* v, const float* n, const float* c, const float* t, + size_t stride, size_t count); + virtual void WritePointData(const unsigned int* i, size_t count); + virtual void WriteLineData(const unsigned int* ij, size_t count); + virtual void WriteTriData(const unsigned int* ijk, size_t count); + virtual void WriteQuadData(const unsigned int* ijkl, size_t count); + +private: + std::string file_; + std::ofstream out_; + float scale_; + std::vector<std::string> obj_; +}; + +}} // ns + +#endif diff --git a/modules/gfx/src/color.cc b/modules/gfx/src/color.cc index f99de522b962df1c1ce030b74c97a551fb0cd492..f40e69c53629e136a661b380424d4e075419ae50 100644 --- a/modules/gfx/src/color.cc +++ b/modules/gfx/src/color.cc @@ -81,9 +81,9 @@ geom::Vec3 HSVtoRGB(const geom::Vec3& hsv) geom::Vec3 RGBtoHSV(const geom::Vec3& rgb) { geom::Vec3 hsv; - double var_R = ( rgb[0] / 255.0 ); - double var_G = ( rgb[1] / 255.0 ); - double var_B = ( rgb[2] / 255.0 ); + double var_R = ( rgb[0] ); + double var_G = ( rgb[1] ); + double var_B = ( rgb[2] ); double var_Min = std::min(std::min( var_R, var_G), var_B ); double var_Max = std::max(std::max( var_R, var_G), var_B ); @@ -107,13 +107,18 @@ geom::Vec3 RGBtoHSV(const geom::Vec3& rgb) } else if ( var_B == var_Max ){ hsv[0] = ( 2.0 / 3.0 ) + del_G - del_R; } - if ( hsv[0] < 0 ){ - hsv[0] += 1; + if ( hsv[0] < 0.0 ){ + hsv[0] += 1.0; } - if ( hsv[0] > 1 ){ - hsv[0] -= 1; + if ( hsv[0] > 1.0 ){ + hsv[0] -= 1.0; } } + + hsv[0]=hsv[0]*360.0; + hsv[1]=hsv[1]*100.0; + hsv[2]=hsv[2]*100.0; + return hsv; } } // anon ns @@ -126,6 +131,11 @@ geom::Vec3 Color::ToHSV() Color HSV(double h, double s, double v) { + if(h>1.0 || s>1.0 || v>1.0) { + h=h/360.0; + s=s/100.0; + v=v/100.0; + } geom::Vec3 rgb=HSVtoRGB(geom::Vec3(h,s,v)); return Color(rgb[0],rgb[1],rgb[2]); } diff --git a/modules/gfx/src/color.hh b/modules/gfx/src/color.hh index 1fdee9fa64eb146ee45e8a4882e833dc43ee4b0e..533381dbc07d06880f2f2b3ab00a2b1a3e72c0f3 100644 --- a/modules/gfx/src/color.hh +++ b/modules/gfx/src/color.hh @@ -85,6 +85,13 @@ private: float rgba[4]; }; +/*! + \brief HSV color spec + + h: Hue from 0 to 360 (0=red, 120=green, 240=blue) + s: Saturation from 0 (no color) to 100 (full color) + v: Value from 0 (no light, black) to 100 (full light) +*/ Color DLLEXPORT_OST_GFX HSV(double h, double s, double v); DLLEXPORT_OST_GFX std::ostream& operator<<(std::ostream&, const Color& c); diff --git a/modules/gfx/src/entity.cc b/modules/gfx/src/entity.cc index b5f0f6b75c4e6d516caa1bcffa28c26fbbe45ac8..dff4bfa1fb8465036438a59ebdf8f72dc2a3277b 100644 --- a/modules/gfx/src/entity.cc +++ b/modules/gfx/src/entity.cc @@ -54,6 +54,7 @@ #if OST_SHADER_SUPPORT_ENABLED #include "shader.hh" #endif +#include "exporter.hh" namespace ost { @@ -401,6 +402,23 @@ void Entity::CustomRenderPov(PovState& pov) } } +void Entity::Export(Exporter* ex) +{ + ex->NodeStart(GetName(),Exporter::OBJ); + // in the simplest case, just export va + if(rebuild_ || refresh_) { + PreRenderGL(true); + } + + for (RendererMap::iterator it=renderer_.begin(); it!=renderer_.end(); ++it) { + if(it->second->IsEnabled() && it->second->HasDataToRender()){ + it->second->Export(ex); + } + } + + ex->NodeEnd(GetName()); +} + mol::AtomHandle Entity::PickAtom(const geom::Line3& line, Real line_width) { mol::AtomHandle picked_atom; diff --git a/modules/gfx/src/entity.hh b/modules/gfx/src/entity.hh index 7e6d595fa27f0e34c7d4e7eff73732f28dbca6a6..7663fe3782fe053df4eb7f0428d6401da26905c9 100644 --- a/modules/gfx/src/entity.hh +++ b/modules/gfx/src/entity.hh @@ -324,6 +324,8 @@ public: void SetSeqHack(bool b); bool GetSeqHack() const; + virtual void Export(Exporter* ex); + protected: virtual void CustomPreRenderGL(bool flag); diff --git a/modules/gfx/src/exporter.hh b/modules/gfx/src/exporter.hh new file mode 100644 index 0000000000000000000000000000000000000000..20b0601aee6a110a4c713a687db50d4834c5978c --- /dev/null +++ b/modules/gfx/src/exporter.hh @@ -0,0 +1,56 @@ +//------------------------------------------------------------------------------ +// This file is part of the OpenStructure project <www.openstructure.org> +// +// Copyright (C) 2008-2011 by the OpenStructure authors +// +// This library is free software; you can redistribute it and/or modify it under +// the terms of the GNU Lesser General Public License as published by the Free +// Software Foundation; either version 3.0 of the License, or (at your option) +// any later version. +// This library is distributed in the hope that it will be useful, but WITHOUT +// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS +// FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more +// details. +// +// You should have received a copy of the GNU Lesser General Public License +// along with this library; if not, write to the Free Software Foundation, Inc., +// 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA +//------------------------------------------------------------------------------ +#ifndef OST_GFX_EXPORTER_HH +#define OST_GFX_EXPORTER_HH + +#include <ost/gfx/module_config.hh> + +namespace ost { namespace gfx { + +class Scene; + +class DLLEXPORT_OST_GFX Exporter +{ +public: + enum NodeType { + ROOT=1, + GROUP=2, + OBJ=3 + }; + + virtual ~Exporter() {} + virtual void SceneStart(const Scene* scene) {} + virtual void SceneEnd(const Scene* scene) {} + + virtual void NodeStart(const std::string& name, NodeType t) {} + virtual void NodeEnd(const std::string& name) {} + + // this indicates beginning of new data, including a reset of the indices + // may occur more than once for a given node + virtual void WriteVertexData(const float* v, const float* n, const float* c, const float* t, + size_t stride, size_t count) {} + virtual void WritePointData(const unsigned int* i, size_t count) {} + virtual void WriteLineData(const unsigned int* ij, size_t count) {} + virtual void WriteTriData(const unsigned int* ijk, size_t count) {} + virtual void WriteQuadData(const unsigned int* ijkl, size_t count) {} +}; + +}} // ns + +#endif diff --git a/modules/gfx/src/exporter_fw.hh b/modules/gfx/src/exporter_fw.hh new file mode 100644 index 0000000000000000000000000000000000000000..499248014e24d9df5374569c7a66d5227a4c8443 --- /dev/null +++ b/modules/gfx/src/exporter_fw.hh @@ -0,0 +1,28 @@ +//------------------------------------------------------------------------------ +// This file is part of the OpenStructure project <www.openstructure.org> +// +// Copyright (C) 2008-2011 by the OpenStructure authors +// +// This library is free software; you can redistribute it and/or modify it under +// the terms of the GNU Lesser General Public License as published by the Free +// Software Foundation; either version 3.0 of the License, or (at your option) +// any later version. +// This library is distributed in the hope that it will be useful, but WITHOUT +// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS +// FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more +// details. +// +// You should have received a copy of the GNU Lesser General Public License +// along with this library; if not, write to the Free Software Foundation, Inc., +// 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA +//------------------------------------------------------------------------------ +#ifndef OST_GFX_EXPORTER_FW_HH +#define OST_GFX_EXPORTER_FW_HH + +namespace ost { namespace gfx { + + class Exporter; + +}} // ns + +#endif diff --git a/modules/gfx/src/gfx_node.cc b/modules/gfx/src/gfx_node.cc index e7f038a2668e2d4fdd162e00f29e4acd37592881..8d417aeec6660d3ecf3aa689cf68d3e90c781fa7 100644 --- a/modules/gfx/src/gfx_node.cc +++ b/modules/gfx/src/gfx_node.cc @@ -18,9 +18,11 @@ //------------------------------------------------------------------------------ #include <boost/bind.hpp> #include <ost/dyn_cast.hh> + #include "gfx_node.hh" #include "gfx_object.hh" #include "scene.hh" +#include "exporter.hh" namespace ost { namespace gfx { @@ -101,6 +103,16 @@ void GfxNode::RenderPov(PovState& pov) } } +void GfxNode::Export(Exporter* ex) +{ + if(!IsVisible()) return; + ex->NodeStart(GetName(),Exporter::GROUP); + for(GfxNodeVector::iterator it=node_vector_.begin();it!=node_vector_.end();++it) { + (*it)->Export(ex); + } + ex->NodeEnd(GetName()); +} + String GfxNode::GetName() const { return name_; diff --git a/modules/gfx/src/gfx_node.hh b/modules/gfx/src/gfx_node.hh index b211ca8a9ccb7cda837e109a338ac79d33201301..6cff8388518b96924eec6802dad40e5631cf8c4c 100644 --- a/modules/gfx/src/gfx_node.hh +++ b/modules/gfx/src/gfx_node.hh @@ -34,6 +34,7 @@ #include "gfx_object_fw.hh" #include "gfx_node_visitor.hh" #include "povray_fw.hh" +#include "exporter_fw.hh" namespace ost { namespace gfx { @@ -56,10 +57,11 @@ class DLLEXPORT_OST_GFX GfxNode: public boost::enable_shared_from_this<GfxNode> // render all child leaves and nodes virtual void RenderGL(RenderPass pass); - // render all child leaves and nodes into POVray state virtual void RenderPov(PovState& pov); + virtual void Export(Exporter* ex); + // visitor interface virtual void Apply(GfxNodeVisitor& v, GfxNodeVisitor::Stack st); diff --git a/modules/gfx/src/gfx_object.cc b/modules/gfx/src/gfx_object.cc index 8a45e784b52cb9f18ba77fe354d9262bc355bc9c..1f0486017c6139adc74134f712d72409486744cd 100644 --- a/modules/gfx/src/gfx_object.cc +++ b/modules/gfx/src/gfx_object.cc @@ -33,6 +33,7 @@ #include "povray.hh" #include "impl/mapped_property.hh" +#include "exporter.hh" #if OST_IMG_ENABLED # include <ost/img/alg/stat.hh> @@ -180,6 +181,9 @@ void GfxObj::RenderGL(RenderPass pass) } } +void GfxObj::InitGL() +{ +} void GfxObj::RenderPov(PovState& pov) { @@ -195,6 +199,20 @@ void GfxObj::RenderPov(PovState& pov) } } + +void GfxObj::Export(Exporter* ex) +{ + if(IsVisible()) { + ex->NodeStart(GetName(),Exporter::OBJ); + // in the simplest case, just export va + if(rebuild_ || refresh_) { + PreRenderGL(true); + } + va_.Export(ex); + ex->NodeEnd(GetName()); + } +} + void GfxObj::Apply(GfxNodeVisitor& v, GfxNodeVisitor::Stack st) { v.VisitObject(this,st); @@ -322,18 +340,33 @@ void GfxObj::SetOutlineWidth(float f) Scene::Instance().RequestRedraw(); } +float GfxObj::GetOutlineWidth() const +{ + return va_.GetOutlineWidth(); +} + void GfxObj::SetOutlineExpandFactor(float f) { va_.SetOutlineExpandFactor(f); Scene::Instance().RequestRedraw(); } +float GfxObj::GetOutlineExpandFactor() const +{ + return va_.GetOutlineExpandFactor(); +} + void GfxObj::SetOutlineExpandColor(const Color& c) { va_.SetOutlineExpandColor(c); Scene::Instance().RequestRedraw(); } +Color GfxObj::GetOutlineExpandColor() const +{ + return va_.GetOutlineExpandColor(); +} + void GfxObj::SetOpacity(float o) { opacity_=o; diff --git a/modules/gfx/src/gfx_object.hh b/modules/gfx/src/gfx_object.hh index b59009ba2a07700da07618bc95ac71a4c7496552..d241be75e19f15158d173554f01384b26cdab15f 100644 --- a/modules/gfx/src/gfx_object.hh +++ b/modules/gfx/src/gfx_object.hh @@ -40,6 +40,7 @@ #include "gfx_prim.hh" #include "vertex_array.hh" #include "input.hh" +#include "exporter_fw.hh" namespace ost { namespace gfx { @@ -56,7 +57,8 @@ public: virtual void DeepSwap(GfxObj& go); virtual void RenderGL(RenderPass pass); virtual void RenderPov(PovState& pov); - virtual void Apply(GfxNodeVisitor& v,GfxNodeVisitor::Stack st); + virtual void Export(Exporter* ex); + virtual void Apply(GfxNodeVisitor& v, GfxNodeVisitor::Stack st); virtual int GetType() const; // @@ -75,10 +77,15 @@ public: virtual void SetAALines(bool f); virtual void SetLineHalo(float f); virtual void SetOutline(bool f); + virtual bool GetOutline() const {return outline_flag_;}; virtual void SetOutlineMode(int m); + virtual int GetOutlineMode() const {return outline_mode_;} virtual void SetOutlineWidth(float f); + virtual float GetOutlineWidth() const; virtual void SetOutlineExpandFactor(float f); + virtual float GetOutlineExpandFactor() const; virtual void SetOutlineExpandColor(const Color& c); + virtual Color GetOutlineExpandColor() const; virtual void SetOpacity(float f); virtual float GetOpacity() const {return opacity_;} virtual void ColorBy(const mol::EntityView& ev, @@ -113,6 +120,15 @@ public: */ virtual void CustomRenderGL(RenderPass pass); + // implemented in derived classes to deal with initialization etc + // called just before CustomRenderGL is called + // the boolean flag indicated that a re-build was requested + virtual void CustomPreRenderGL(bool rebuild); + + // implemented in derived classes for first GL initialization + // which should be done here, not in the ctor + virtual void InitGL(); + // implemented in derived classes for the actual POVray export virtual void CustomRenderPov(PovState& pov); @@ -181,7 +197,6 @@ public: protected: void PreRenderGL(bool flag); - virtual void CustomPreRenderGL(bool flag); private: GfxObj(const GfxObj& o); diff --git a/modules/gfx/src/gfx_object_base.hh b/modules/gfx/src/gfx_object_base.hh index 7884c7de4744c6a0598ec9b1c35578c72b9d0c1a..eb6c7c21743805e237377bc64e15ced0d61f3885 100644 --- a/modules/gfx/src/gfx_object_base.hh +++ b/modules/gfx/src/gfx_object_base.hh @@ -91,14 +91,26 @@ class DLLEXPORT_OST_GFX GfxObjBase: public GfxNode /// \brief turn outline rendering on or off virtual void SetOutline(bool f) = 0; - /// \brief set outline mode + /// \brief get state of outline rendering + virtual bool GetOutline() const = 0; + /// \brief set outline mode, 1, 2 or 3 virtual void SetOutlineMode(int m) = 0; - /// \brief set outline width (modes 1 + 2) + /// \brief get current outline mode + virtual int GetOutlineMode() const = 0; + /// \brief set outline width in pixels (modes 1 + 2) + /// this does not scale with resolution virtual void SetOutlineWidth(float f) = 0; - /// \brief set outline tweak factor (mode 3) + /// \brief get current outline width + virtual float GetOutlineWidth() const = 0; + /// \brief set outline expansion factor (mode 3) + /// this scales with resolution virtual void SetOutlineExpandFactor(float f) = 0; + /// \brief get current outline expand factor (mode 3) + virtual float GetOutlineExpandFactor() const = 0; /// \brief set outline color (mode 3) virtual void SetOutlineExpandColor(const Color& c) = 0; + /// \brief get current outline color (mode 3) + virtual Color GetOutlineExpandColor() const = 0; /// \brief set opacity (1 = no transparency) virtual void SetOpacity(float f) = 0; diff --git a/modules/gfx/src/gost_exporter.cc b/modules/gfx/src/gost_exporter.cc new file mode 100644 index 0000000000000000000000000000000000000000..79a6e9b28390f1ce2d1890e88d824de48856e358 --- /dev/null +++ b/modules/gfx/src/gost_exporter.cc @@ -0,0 +1,277 @@ +//------------------------------------------------------------------------------ +// This file is part of the OpenStructure project <www.openstructure.org> +// +// Copyright (C) 2008-2011 by the OpenStructure authors +// +// This library is free software; you can redistribute it and/or modify it under +// the terms of the GNU Lesser General Public License as published by the Free +// Software Foundation; either version 3.0 of the License, or (at your option) +// any later version. +// This library is distributed in the hope that it will be useful, but WITHOUT +// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS +// FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more +// details. +// +// You should have received a copy of the GNU Lesser General Public License +// along with this library; if not, write to the Free Software Foundation, Inc., +// 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA +//------------------------------------------------------------------------------ + +/* + Author: Ansgar Philippsen +*/ + +#include <sstream> + +#include "gost_exporter.hh" +#include "scene.hh" + +namespace ost { namespace gfx { + + namespace { + enum TYPE { + GOST_UNKNOWN=0, + GOST_SCENE=1, + GOST_START_NODE=2, + GOST_END_NODE=3, + GOST_DATA=4, + GOST_FRAME=5 + }; + + enum NODE_TYPE { + GOST_ROOT=1, + GOST_GROUP=2, + GOST_OBJ=3 + }; + + enum DATA_TYPE { + GOST_VDATA=1, + GOST_NDATA=2, + GOST_CDATA=3, + GOST_TDATA=4, + GOST_PINDEX=5, + GOST_LINDEX=6, + GOST_TINDEX=7, + GOST_QINDEX=8 + }; + } + +GostExporter::GostExporter(const std::string& fname): + file_(0) +{ + file_=fopen(fname.c_str(),"w"); + if(!file_) { + std::ostringstream m; + m << "Could not open '" << fname << "' for writing"; + throw Error(m.str()); + } + char headr[]={'G','O','S','T','1','0'}; + fwrite(headr,sizeof(char),6,file_); +} + +GostExporter::~GostExporter() +{ + fclose(file_); + file_=0; +} + +void GostExporter::SceneStart(const Scene* scene) +{ + int type=GOST_SCENE; + int subtype=0; + size_t size=0; + + fwrite(&type,sizeof(int),1,file_); + fwrite(&subtype,sizeof(int),1,file_); + fwrite(&size,sizeof(size_t),1,file_); +} + +void GostExporter::SceneEnd(const Scene* scene) +{} + +void GostExporter::NodeStart(const std::string& name, NodeType t) +{ + int type=GOST_START_NODE; + int subtype=0; + if(t==Exporter::ROOT) subtype=GOST_ROOT; + else if(t==Exporter::GROUP) subtype=GOST_GROUP; + else if(t==Exporter::OBJ) subtype=GOST_OBJ; + size_t size=name.size(); + + fwrite(&type,sizeof(int),1,file_); + fwrite(&subtype,sizeof(int),1,file_); + fwrite(&size,sizeof(size_t),1,file_); + fwrite(name.c_str(),sizeof(char), size,file_); +} + +void GostExporter::NodeEnd(const std::string& name) +{ + int type=GOST_END_NODE; + int subtype=0; + size_t size=0; + + fwrite(&type,sizeof(int),1,file_); + fwrite(&subtype,sizeof(int),1,file_); + fwrite(&size,sizeof(size_t),1,file_); +} + +void GostExporter::WriteVertexData(const float* vdata, const float* ndata, + const float* cdata, const float* tdata, + size_t stride2, size_t count) +{ + std::vector<float> buffer(count*4); + int type=GOST_DATA; + int subtype=0; + size_t size=0; + size_t stride=stride2/sizeof(float); + + if(vdata) { + // positions + subtype=GOST_VDATA; + size=sizeof(float)*3*count+sizeof(size_t); + float* dest=&buffer[0]; + const float* src=vdata; + for(size_t i=0;i<count;++i) { + dest[0]=src[0]; + dest[1]=src[1]; + dest[2]=src[2]; + src+=stride; + dest+=3; + } + fwrite(&type,sizeof(int),1,file_); + fwrite(&subtype,sizeof(int),1,file_); + fwrite(&size,sizeof(size_t),1,file_); + // + fwrite(&count,sizeof(size_t),1,file_); + fwrite(&buffer[0],sizeof(float),3*count,file_); + } + + if(ndata) { + // normals + subtype=GOST_NDATA; + size=sizeof(float)*count*3+sizeof(size_t); + float* dest=&buffer[0]; + const float* src=ndata; + for(size_t i=0;i<count;++i) { + dest[0]=src[0]; + dest[1]=src[1]; + dest[2]=src[2]; + src+=stride; + dest+=3; + } + fwrite(&type,sizeof(int),1,file_); + fwrite(&subtype,sizeof(int),1,file_); + fwrite(&size,sizeof(size_t),1,file_); + // + fwrite(&count,sizeof(size_t),1,file_); + fwrite(&buffer[0],sizeof(float),3*count,file_); + } + + if(cdata) { + // colors + subtype=GOST_CDATA; + size=sizeof(float)*count*4+sizeof(size_t); + float* dest=&buffer[0]; + const float* src=cdata; + for(size_t i=0;i<count;++i) { + dest[0]=src[0]; + dest[1]=src[1]; + dest[2]=src[2]; + dest[3]=src[3]; + src+=stride; + dest+=4; + } + fwrite(&type,sizeof(int),1,file_); + fwrite(&subtype,sizeof(int),1,file_); + fwrite(&size,sizeof(size_t),1,file_); + // + fwrite(&count,sizeof(size_t),1,file_); + fwrite(&buffer[0],sizeof(float),4*count,file_); + } + + if(tdata) { + // texture coordinates + subtype=GOST_TDATA; + size=sizeof(float)*count*2+sizeof(size_t); + float* dest=&buffer[0]; + const float* src=tdata; + for(size_t i=0;i<count;++i) { + dest[0]=src[0]; + dest[1]=src[1]; + src+=stride; + dest+=2; + } + fwrite(&type,sizeof(int),1,file_); + fwrite(&subtype,sizeof(int),1,file_); + fwrite(&size,sizeof(size_t),1,file_); + // + fwrite(&count,sizeof(size_t),1,file_); + fwrite(&buffer[0],sizeof(float),2*count,file_); + } +} + +void GostExporter::WritePointData(const unsigned int* i, size_t count) +{ + int type=GOST_DATA; + int subtype=GOST_PINDEX; + size_t size=sizeof(unsigned int)*count+sizeof(size_t); + fwrite(&type,sizeof(int),1,file_); + fwrite(&subtype,sizeof(int),1,file_); + fwrite(&size,sizeof(size_t),1,file_); + // + fwrite(&count,sizeof(size_t),1,file_); + fwrite(i,sizeof(unsigned int),count,file_); +} + +void GostExporter::WriteLineData(const unsigned int* ij, size_t count) +{ + int type=GOST_DATA; + int subtype=GOST_LINDEX; + size_t size=sizeof(unsigned int)*2*count+sizeof(size_t); + fwrite(&type,sizeof(int),1,file_); + fwrite(&subtype,sizeof(int),1,file_); + fwrite(&size,sizeof(size_t),1,file_); + // + fwrite(&count,sizeof(size_t),1,file_); + fwrite(ij,sizeof(unsigned int),2*count,file_); +} + +void GostExporter::WriteTriData(const unsigned int* ijk, size_t count) +{ + int type=GOST_DATA; + int subtype=GOST_TINDEX; + size_t size=sizeof(unsigned int)*3*count+sizeof(size_t); + fwrite(&type,sizeof(int),1,file_); + fwrite(&subtype,sizeof(int),1,file_); + fwrite(&size,sizeof(size_t),1,file_); + // + fwrite(&count,sizeof(size_t),1,file_); + fwrite(ijk,sizeof(unsigned int),3*count,file_); +} + +void GostExporter::WriteQuadData(const unsigned int* ijkl, size_t count) +{ + int type=GOST_DATA; + int subtype=GOST_QINDEX; + size_t size=sizeof(unsigned int)*4*count+sizeof(size_t); + fwrite(&type,sizeof(int),1,file_); + fwrite(&subtype,sizeof(int),1,file_); + fwrite(&size,sizeof(size_t),1,file_); + // + fwrite(&count,sizeof(size_t),1,file_); + fwrite(ijkl,sizeof(unsigned int),4*count,file_); +} + +void GostExporter::SetFrame(size_t frame) +{ + int type=GOST_FRAME; + int subtype=0; + size_t size=sizeof(size_t); + fwrite(&type,sizeof(int),1,file_); + fwrite(&subtype,sizeof(int),1,file_); + fwrite(&size,sizeof(size_t),1,file_); + // + fwrite(&frame,sizeof(size_t),1,file_); +} + +}} // ns diff --git a/modules/gfx/src/gost_exporter.hh b/modules/gfx/src/gost_exporter.hh new file mode 100644 index 0000000000000000000000000000000000000000..03f47680eeabba9fe36236ff057b5e13f4385c9c --- /dev/null +++ b/modules/gfx/src/gost_exporter.hh @@ -0,0 +1,54 @@ +//------------------------------------------------------------------------------ +// This file is part of the OpenStructure project <www.openstructure.org> +// +// Copyright (C) 2008-2011 by the OpenStructure authors +// +// This library is free software; you can redistribute it and/or modify it under +// the terms of the GNU Lesser General Public License as published by the Free +// Software Foundation; either version 3.0 of the License, or (at your option) +// any later version. +// This library is distributed in the hope that it will be useful, but WITHOUT +// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS +// FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more +// details. +// +// You should have received a copy of the GNU Lesser General Public License +// along with this library; if not, write to the Free Software Foundation, Inc., +// 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA +//------------------------------------------------------------------------------ +#ifndef OST_GFX_GOST_EXPORTER_HH +#define OST_GFX_GOST_EXPORTER_HH + +#include <cstdio> + +#include "exporter.hh" + +namespace ost { namespace gfx { + +class DLLEXPORT_OST_GFX GostExporter: public Exporter +{ +public: + GostExporter(const std::string& fname); + virtual ~GostExporter(); + + // exporter interface + virtual void SceneStart(const Scene* scene); + virtual void SceneEnd(const Scene* scene); + virtual void NodeStart(const std::string& name, NodeType t); + virtual void NodeEnd(const std::string& name); + virtual void WriteVertexData(const float* v, const float* n, const float* c, const float* t, + size_t stride, size_t count); + virtual void WritePointData(const unsigned int* i, size_t count); + virtual void WriteLineData(const unsigned int* ij, size_t count); + virtual void WriteTriData(const unsigned int* ijk, size_t count); + virtual void WriteQuadData(const unsigned int* ijkl, size_t count); + + // gost interface + void SetFrame(size_t f); +private: + FILE* file_; +}; + +}} // ns + +#endif diff --git a/modules/gfx/src/impl/entity_renderer.cc b/modules/gfx/src/impl/entity_renderer.cc index 3464d1292297e3161e3aaed4a1130974b7763fb1..fb22e24a375988bdcb36bf8b9b1b9b0e34695fef 100644 --- a/modules/gfx/src/impl/entity_renderer.cc +++ b/modules/gfx/src/impl/entity_renderer.cc @@ -156,6 +156,11 @@ void EntityRenderer::RenderPov(PovState& pov, const std::string& name) va_.RenderPov(pov,name); } +void EntityRenderer::Export(Exporter* ex) +{ + va_.Export(ex); +} + bool EntityRenderer::HasSelection() const { return (sel_.IsValid() && sel_.GetAtomCount()>0); diff --git a/modules/gfx/src/impl/entity_renderer.hh b/modules/gfx/src/impl/entity_renderer.hh index ceed73fa4d8d2f41a739c949a6e978ae29b18fbc..14c0332c3b5a15d0d0f101b19aad3e9363d03047 100644 --- a/modules/gfx/src/impl/entity_renderer.hh +++ b/modules/gfx/src/impl/entity_renderer.hh @@ -39,8 +39,9 @@ #include <ost/gfx/module_config.hh> #include <ost/gfx/render_pass.hh> #include <ost/gfx/vertex_array.hh> +#include <ost/gfx/exporter_fw.hh> + #include <ost/gfx/render_options/render_options.hh> -#include <ost/gfx/impl/mapped_property.hh> #include <ost/gfx/color_ops/color_op.hh> #include <ost/gfx/color_ops/by_element_color_op.hh> @@ -51,7 +52,9 @@ #if OST_IMG_ENABLED #include <ost/gfx/color_ops/map_handle_color_op.hh> #endif //OST_IMG_ENABLED -#include <ost/gfx/impl/entity_renderer_fw.hh> + +#include "mapped_property.hh" +#include "entity_renderer_fw.hh" namespace ost { namespace gfx { namespace impl { @@ -123,6 +126,9 @@ public: ///\brief povray rendering call virtual void RenderPov(PovState& pov, const std::string& name); + ///\brief scene exporter interface + virtual void Export(Exporter* ex); + virtual bool CanSetOptions(RenderOptionsPtr& render_options)=0; virtual void SetOptions(RenderOptionsPtr& render_options)=0; diff --git a/modules/gfx/src/prim_list.cc b/modules/gfx/src/prim_list.cc index 6113aecfb45e02867496f1c6129a92d9da8db2a1..a9debc0edd67dfa55d9a4057fb9ad0b77bdf4d2f 100644 --- a/modules/gfx/src/prim_list.cc +++ b/modules/gfx/src/prim_list.cc @@ -38,7 +38,8 @@ PrimList::PrimList(const String& name): texts_(), sphere_detail_(4), arc_detail_(4), - simple_va_() + simple_va_(), + vas_() {} void PrimList::Clear() @@ -48,13 +49,14 @@ void PrimList::Clear() spheres_.clear(); cyls_.clear(); texts_.clear(); + vas_.clear(); Scene::Instance().RequestRedraw(); this->FlagRebuild(); } geom::AlignedCuboid PrimList::GetBoundingBox() const { - if(points_.empty() && lines_.empty() && spheres_.empty() && cyls_.empty()) { + if(points_.empty() && lines_.empty() && spheres_.empty() && cyls_.empty() && texts_.empty() && vas_.empty()) { return geom::AlignedCuboid(geom::Vec3(-1,-1,-1),geom::Vec3(1,1,1)); } geom::Vec3 minc(std::numeric_limits<float>::max(), @@ -101,6 +103,11 @@ void PrimList::ProcessLimits(geom::Vec3& minc, geom::Vec3& maxc, minc=geom::Min(minc,tpos); maxc=geom::Max(maxc,tpos); } + for(std::vector<IndexedVertexArray>::const_iterator it=vas_.begin();it!=vas_.end();++it) { + geom::AlignedCuboid bb=it->GetBoundingBox(); + minc=geom::Min(minc,bb.GetMin()); + maxc=geom::Max(maxc,bb.GetMax()); + } minc-=1.0; maxc+=1.0; } @@ -152,12 +159,15 @@ void PrimList::CustomRenderGL(RenderPass pass) va_.RenderGL(); simple_va_.RenderGL(); render_text(); + for(std::vector<IndexedVertexArray>::iterator it=vas_.begin();it!=vas_.end();++it) { + it->RenderGL(); + } } } void PrimList::CustomRenderPov(PovState& pov) { - if(points_.empty() && lines_.empty()) return; + if(points_.empty() && lines_.empty() && spheres_.empty() && cyls_.empty()) return; pov.write_merge_or_union(GetName()); for(SpherePrimList::const_iterator it=points_.begin();it!=points_.end();++it) { @@ -262,6 +272,42 @@ void PrimList::SetColor(const Color& c) FlagRebuild(); } +void PrimList::AddMesh(float* v, float* n, float* c, size_t nv, unsigned int* i, size_t ni) +{ + static float dummy_normal[]={0.0,0.0,1.0}; + static float dummy_color[]={1.0,1.0,1.0,1.0}; + vas_.push_back(IndexedVertexArray()); + IndexedVertexArray& va=vas_.back(); + va.SetLighting(true); + va.SetTwoSided(true); + va.SetColorMaterial(true); + va.SetCullFace(false); + float* vv=v; + float* nn=n; + if(!n) { + nn=dummy_normal; + va.SetLighting(false); + } + float* cc=c; + if(!c) { + cc=dummy_color; + } + for(size_t k=0;k<nv;++k) { + va.Add(geom::Vec3(vv[0],vv[1],vv[2]), + geom::Vec3(nn[0],nn[1],nn[2]), + Color(cc[0],cc[1],cc[2],cc[3])); + vv+=3; + if(n) nn+=3; + if(c) cc+=4; + } + unsigned int* ii=i; + for(size_t k=0;k<ni;++k) { + va.AddTri(ii[0],ii[1],ii[2]); + ii+=3; + } + Scene::Instance().RequestRedraw(); + FlagRebuild(); +} //////////////////////////////// // private methods diff --git a/modules/gfx/src/prim_list.hh b/modules/gfx/src/prim_list.hh index 4e8a4c297ea044eda07d2cc199a4988b3d7e4e23..395e53e2ad22ce359b37281caead22cad1a423e9 100644 --- a/modules/gfx/src/prim_list.hh +++ b/modules/gfx/src/prim_list.hh @@ -139,6 +139,24 @@ class DLLEXPORT_OST_GFX PrimList: public GfxObj // TODO: add point and line pixel width + /*! + \brief add triangle mesh + + v : pointer to nv*3 floats for the positions (mandatory) + n : pointer to nv*3 floats for the normals (may be NULL) + c : pointer to nv*4 floats for the colors (may be NULL) + nv: number of vertices, normals, and colors + i : pointer to ni*3 vertex indices + ni: number of index triplets + + Python interface, using numpy arrays: + + AddMesh(vertex_array, normal_array, color_array, index_array) + + where normal_array and color_array may be None + */ + void AddMesh(float* v, float* n, float* c, size_t nv, unsigned int* i, size_t ni); + protected: virtual void CustomPreRenderGL(bool flag); @@ -152,6 +170,8 @@ class DLLEXPORT_OST_GFX PrimList: public GfxObj unsigned int arc_detail_; IndexedVertexArray simple_va_; + + std::vector<IndexedVertexArray> vas_; void prep_simple_va(); void prep_va(); diff --git a/modules/gfx/src/scene.cc b/modules/gfx/src/scene.cc index 8b991110743b0235d45abc68f9182344a31033cd..1bd5e460742f0a774bd7e7d46eba5974b4804dd7 100644 --- a/modules/gfx/src/scene.cc +++ b/modules/gfx/src/scene.cc @@ -42,6 +42,7 @@ #include "gl_helper.hh" #include <ost/config.hh> + #include "scene.hh" #include "input.hh" #include "gfx_node.hh" @@ -49,6 +50,7 @@ #include "gfx_test_object.hh" #include "bitmap_io.hh" #include "entity.hh" +#include "exporter.hh" #include "povray.hh" #include "offscreen_buffer.hh" @@ -107,7 +109,8 @@ Scene::Scene(): light_amb_(0.1,0.1,0.1), light_diff_(0.9,0.9,0.9), light_spec_(0.5,0.5,0.5), - axis_flag_(false), + cor_flag_(false), + fix_cor_flag_(true), fog_flag_(true), fog_color_(0.0,0.0,0.0,0.0), auto_autoslab_(true), @@ -194,6 +197,15 @@ void Scene::SetShadowQuality(int q) #endif } +int Scene::GetShadowQuality() const +{ +#if OST_SHADER_SUPPORT_ENABLED + return impl::SceneFX::Instance().shadow_quality; +#else + return 0; +#endif +} + void Scene::SetShadowWeight(float w) { #if OST_SHADER_SUPPORT_ENABLED @@ -202,6 +214,15 @@ void Scene::SetShadowWeight(float w) #endif } +float Scene::GetShadowWeight() const +{ +#if OST_SHADER_SUPPORT_ENABLED + return impl::SceneFX::Instance().shadow_weight; +#else + return 0.0; +#endif +} + void Scene::SetDepthDarkening(bool f) { #if OST_SHADER_SUPPORT_ENABLED @@ -247,6 +268,15 @@ void Scene::SetAmbientOcclusionWeight(float f) #endif } +float Scene::GetAmbientOcclusionWeight() const +{ +#if OST_SHADER_SUPPORT_ENABLED + return impl::SceneFX::Instance().amb_occl_factor; +#else + return 1.0; +#endif +} + void Scene::SetAmbientOcclusionMode(uint m) { #if OST_SHADER_SUPPORT_ENABLED @@ -256,6 +286,15 @@ void Scene::SetAmbientOcclusionMode(uint m) #endif } +uint Scene::GetAmbientOcclusionMode() const +{ +#if OST_SHADER_SUPPORT_ENABLED + return impl::SceneFX::Instance().amb_occl_mode; +#else + return 0; +#endif +} + void Scene::SetAmbientOcclusionQuality(uint m) { #if OST_SHADER_SUPPORT_ENABLED @@ -265,6 +304,15 @@ void Scene::SetAmbientOcclusionQuality(uint m) #endif } +uint Scene::GetAmbientOcclusionQuality() const +{ +#if OST_SHADER_SUPPORT_ENABLED + return impl::SceneFX::Instance().amb_occl_quality; +#else + return 0; +#endif +} + void Scene::SetShadingMode(const std::string& smode) { #if OST_SHADER_SUPPORT_ENABLED @@ -309,12 +357,18 @@ void Scene::SetBeaconOff() namespace { -void set_light_dir(Vec3 ld) -{ - GLfloat l_pos[]={0.0, 0.0, 0.0, 0.0}; - l_pos[0]=-ld[0]; l_pos[1]=-ld[1]; l_pos[2]=-ld[2]; - glLightfv(GL_LIGHT0, GL_POSITION, l_pos); -} + void set_light_dir(Vec3 ld) + { + GLfloat l_pos[]={0.0, 0.0, 0.0, 0.0}; + l_pos[0]=-ld[0]; l_pos[1]=-ld[1]; l_pos[2]=-ld[2]; + glLightfv(GL_LIGHT0, GL_POSITION, l_pos); + } + + struct GfxObjInitGL: public GfxNodeVisitor { + virtual void VisitObject(GfxObj* o, const Stack& st) { + o->InitGL(); + } + }; } @@ -355,7 +409,8 @@ void Scene::InitGL(bool full) glClearDepth(1.0); // background - SetBackground(background_); + glClearColor(background_.Red(),background_.Green(),background_.Blue(),background_.Alpha()); + fog_color_=background_; // polygon orientation setting glFrontFace(GL_CCW); @@ -457,8 +512,14 @@ void Scene::InitGL(bool full) glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP); glTexEnvf(GL_TEXTURE_ENV,GL_TEXTURE_ENV_MODE, GL_REPLACE); + LOG_DEBUG("Scene: calling gl init for all objects"); + GfxObjInitGL initgl; + this->Apply(initgl); + LOG_DEBUG("Scene: gl init done"); gl_init_=true; + + if(!def_shading_mode_.empty()) SetShadingMode(def_shading_mode_); } void Scene::RequestRedraw() @@ -773,9 +834,13 @@ void Scene::Add(const GfxNodeP& n, bool redraw) LOG_DEBUG("Scene: graphical object added @" << n.get() << std::endl); - if(root_node_->GetChildCount()==0) { - GfxObjP go = boost::dynamic_pointer_cast<GfxObj>(n); - if(go) { + GfxObjP go = boost::dynamic_pointer_cast<GfxObj>(n); + + if(go) { + if(gl_init_) { + go->InitGL(); + } + if(root_node_->GetChildCount()==0) { SetCenter(go->GetCenter()); } do_autoslab_=true; @@ -954,10 +1019,18 @@ void Scene::OnInput(const InputEvent& e) gluUnProject(wx+2.0,wy+2.0,wz,mm,pm,vp,&ox,&oy,&oz); Vec2 fxy = Vec2(ox,oy); - if(e.GetCommand()==INPUT_COMMAND_TRANSX) { - transform_.ApplyXAxisTranslation(e.GetDelta()*fxy[0]); + if(fix_cor_flag_) { + if(e.GetCommand()==INPUT_COMMAND_TRANSX) { + transform_.SetCenter(transform_.GetCenter()+Transpose(transform_.GetRot())*Vec3(-fxy[0]*e.GetDelta(),0.0,0.0)); + } else { + transform_.SetCenter(transform_.GetCenter()+Transpose(transform_.GetRot())*Vec3(0.0,-fxy[1]*e.GetDelta(),0.0)); + } } else { - transform_.ApplyYAxisTranslation(e.GetDelta()*fxy[1]); + if(e.GetCommand()==INPUT_COMMAND_TRANSX) { + transform_.ApplyXAxisTranslation(e.GetDelta()*fxy[0]); + } else { + transform_.ApplyYAxisTranslation(e.GetDelta()*fxy[1]); + } } } else if(e.GetCommand()==INPUT_COMMAND_TRANSZ) { float currz=transform_.GetTrans()[2]; @@ -1573,6 +1646,13 @@ void Scene::ExportPov(const std::string& fname, const std::string& wdir) pov.write_postamble(); } +void Scene::Export(Exporter* ex) const +{ + ex->SceneStart(this); + root_node_->Export(ex); + ex->SceneEnd(this); +} + void Scene::ResetProjection() { LOG_TRACE("Scene: projection matrix " << fov_ << " " << znear_ << " " << zfar_); @@ -1740,6 +1820,12 @@ void Scene::SetTestMode(bool f) } } +void Scene::SetShowCenter(bool f) +{ + cor_flag_=f; + RequestRedraw(); +} + void Scene::prep_glyphs() { glGenTextures(1,&glyph_tex_id_); @@ -1800,6 +1886,32 @@ void Scene::render_scene() impl::SceneFX::Instance().Preprocess(); #endif + if(cor_flag_) { + geom::Vec3 cen=transform_.GetCenter(); + glPushAttrib(GL_ENABLE_BIT | GL_LIGHTING_BIT | GL_LINE_BIT | GL_CURRENT_BIT); +#if OST_SHADER_SUPPORT_ENABLED + Shader::Instance().PushProgram(); + Shader::Instance().Activate(""); +#endif + glLineWidth(1.5); + glDisable(GL_LIGHTING); + glDisable(GL_COLOR_MATERIAL); + + glBegin(GL_LINES); + glColor3f(0.5,0.5,0.5); + glVertex3f(cen[0]-1.0,cen[1],cen[2]); + glVertex3f(cen[0]+1.0,cen[1],cen[2]); + glVertex3f(cen[0],cen[1]-1.0,cen[2]); + glVertex3f(cen[0],cen[1]+1.0,cen[2]); + glVertex3f(cen[0],cen[1],cen[2]-1.0); + glVertex3f(cen[0],cen[1],cen[2]+1.0); + glEnd(); + glPopAttrib(); +#if OST_SHADER_SUPPORT_ENABLED + Shader::Instance().PopProgram(); +#endif + } + root_node_->RenderGL(STANDARD_RENDER_PASS); glEnable(GL_BLEND); glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); @@ -1862,7 +1974,7 @@ void Scene::stereo_projection(int view) glFrustum(left,right,bot,top,zn,zf); Real dist = -transform_.GetTrans()[2]+stereo_distance_; glTranslated(0.0,0.0,-dist); - glRotated(180.0/M_PI*atan(0.1*ff/iod),0.0,1.0,0.0); + glRotated(-180.0/M_PI*atan(0.1*ff/iod),0.0,1.0,0.0); glTranslated(0.0,0.0,dist); } else { // correct off-axis frustims @@ -1871,10 +1983,12 @@ void Scene::stereo_projection(int view) // correction of near clipping plane to avoid extreme drifting // of left and right view +#if 0 if(iod*zn/fo<2.0) { zn=2.0*fo/iod; zf=std::max(zn+Real(0.2),zf); } +#endif Real sd = -ff*0.5*iod*zn/fo; left+=sd; @@ -1892,6 +2006,9 @@ void Scene::stereo_projection(int view) void Scene::render_stereo() { + glPushAttrib(GL_ALL_ATTRIB_BITS); + glPushClientAttrib(GL_ALL_ATTRIB_BITS); + int old_stereo_eye=stereo_eye_; stereo_eye_=-1; stereo_projection(-1); @@ -1909,6 +2026,7 @@ void Scene::render_stereo() stereo_eye_=1; stereo_projection(1); render_scene(); + glEnable(GL_TEXTURE_2D); #if OST_SHADER_SUPPORT_ENABLED if(OST_GL_VERSION_2_0) { @@ -1925,7 +2043,6 @@ void Scene::render_stereo() Shader::Instance().Activate(""); #endif - glPushAttrib(GL_ALL_ATTRIB_BITS); glDisable(GL_DEPTH_TEST); glDisable(GL_LIGHTING); glDisable(GL_COLOR_MATERIAL); @@ -1946,7 +2063,7 @@ void Scene::render_stereo() glLoadIdentity(); if(stereo_mode_==2) { - // draw interlace lines in stencil buffer + // draw interlaced lines in stencil buffer glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); glLineWidth(1.0); glEnable(GL_STENCIL_TEST); @@ -2011,10 +2128,14 @@ void Scene::render_stereo() glEnd(); // restore settings + glCopyTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 0, 0, 0, 0, 0); + glBindTexture(GL_TEXTURE_2D, 0); + glDisable(GL_TEXTURE_2D); glMatrixMode(GL_PROJECTION); glPopMatrix(); glMatrixMode(GL_MODELVIEW); glPopMatrix(); + glPopClientAttrib(); glPopAttrib(); #if OST_SHADER_SUPPORT_ENABLED Shader::Instance().PopProgram(); diff --git a/modules/gfx/src/scene.hh b/modules/gfx/src/scene.hh index bf093efaff7384f608ce2cac18e5a4b92c14c13e..a5868d0606581bff66c84b32b5d53f071bc44751 100644 --- a/modules/gfx/src/scene.hh +++ b/modules/gfx/src/scene.hh @@ -42,6 +42,7 @@ #include "scene_observer.hh" #include "gfx_prim.hh" #include "povray_fw.hh" +#include "exporter_fw.hh" namespace ost { namespace gfx { @@ -95,27 +96,25 @@ class DLLEXPORT_OST_GFX Scene { /// \brief turn fog on or off void SetFog(bool f); - /// \brief check fog status bool GetFog() const; - /// \brief set the fog color void SetFogColor(const Color& c); - /// \brief get the fog color Color GetFogColor() const; /// \brief turn shadow mapping on and off void SetShadow(bool f); - /// \brief get shadow mapping status bool GetShadow() const; - /// \brief shadow quality from 0 (low) to 3 (high), default=1 void SetShadowQuality(int q); - + /// \brief get shadow quality + int GetShadowQuality() const; /// \brief multiplier for shadow strength void SetShadowWeight(float w); + /// \brief get shadow strength + float GetShadowWeight() const; /// experimental feature void SetDepthDarkening(bool f); @@ -129,9 +128,15 @@ class DLLEXPORT_OST_GFX Scene { /// experimental feature void SetAmbientOcclusionWeight(float f); /// experimental feature + float GetAmbientOcclusionWeight() const; + /// experimental feature void SetAmbientOcclusionMode(uint m); /// experimental feature + uint GetAmbientOcclusionMode() const; + /// experimental feature void SetAmbientOcclusionQuality(uint q); + /// experimental feature + uint GetAmbientOcclusionQuality() const; /// \brief select shading mode /// one of fallback, basic, default, hf, toon1, toon2 @@ -249,13 +254,17 @@ class DLLEXPORT_OST_GFX Scene { /// if a main offscreen buffer is active (\sa StartOffscreenMode), then the /// dimensions here are ignored void Export(const String& fname, unsigned int w, - unsigned int h, bool transparent=true); + unsigned int h, bool transparent=false); /// \brief export snapshot of current scene - void Export(const String& fname, bool transparent=true); + void Export(const String& fname, bool transparent=false); /// \brief export scene into povray files named fname.pov and fname.inc void ExportPov(const std::string& fname, const std::string& wdir="."); + + /// \rbrief export scene via exporter + void Export(Exporter* ex) const; + //@} /// \brief entry point for gui events (internal use) void OnInput(const InputEvent& e); @@ -409,6 +418,17 @@ class DLLEXPORT_OST_GFX Scene { /// \brief stops offline rendering in interactive mode void StopOffscreenMode(); + /// \brief show center of rotation of true + void SetShowCenter(bool f); + + bool GetShowCenter() const {return cor_flag_;} + + /// \brief if true fix center of rotation upon input induced shift + void SetFixCenter(bool f) {fix_cor_flag_=f;} + + /// \brief return flag + bool GetFixCenter() const {return fix_cor_flag_;} + /// experimental feature void SetBlur(uint n); /// experimental feature @@ -472,7 +492,8 @@ private: Color light_diff_; Color light_spec_; - bool axis_flag_; + bool cor_flag_; + bool fix_cor_flag_; bool fog_flag_; Color fog_color_; bool auto_autoslab_; diff --git a/modules/gfx/src/vertex_array.cc b/modules/gfx/src/vertex_array.cc index c1c53d57fa29110368a7b1a5a2da28fb2c7c5612..b9c45e5a7ce54f274b2b1e0b029f100fd81772ec 100644 --- a/modules/gfx/src/vertex_array.cc +++ b/modules/gfx/src/vertex_array.cc @@ -30,6 +30,7 @@ #include "scene.hh" #include "vertex_array_helper.hh" #include "povray.hh" +#include "exporter.hh" #if OST_SHADER_SUPPORT_ENABLED #include "shader.hh" @@ -108,7 +109,7 @@ unsigned int IndexedVertexArray::GetFormat() void IndexedVertexArray::Cleanup() { if(initialized_) { - glDeleteTextures(1,&tex_id_); + //glDeleteTextures(1,&tex_id_); glDeleteLists(outline_mat_dlist_,1); #if OST_SHADER_SUPPORT_ENABLED glDeleteBuffers(7,buffer_id_); @@ -431,6 +432,12 @@ void IndexedVertexArray::RenderGL() glPushAttrib(GL_ALL_ATTRIB_BITS); glPushClientAttrib(GL_CLIENT_VERTEX_ARRAY_BIT); + + if(use_tex_) { + glEnable(GL_TEXTURE_2D); + } else { + glDisable(GL_TEXTURE_2D); + } if(outline_mode_>0) { LOG_TRACE("outline rendering"); @@ -654,6 +661,14 @@ void IndexedVertexArray::RenderPov(PovState& pov, const std::string& name) pov.inc() << "}\n"; } +void IndexedVertexArray::Export(Exporter* ex) const +{ + ex->WriteVertexData(entry_list_[0].v,entry_list_[0].n, entry_list_[0].c, entry_list_[0].t, sizeof(Entry), entry_list_.size()); + ex->WriteLineData(&line_index_list_[0],line_index_list_.size()/2); + ex->WriteTriData(&tri_index_list_[0],tri_index_list_.size()/3); + ex->WriteQuadData(&quad_index_list_[0],quad_index_list_.size()/4); +} + void IndexedVertexArray::Clear() { dirty_=true; @@ -685,7 +700,7 @@ void IndexedVertexArray::Reset() outline_exp_factor_=0.1; outline_exp_color_=Color(0,0,0); draw_normals_=false; - use_tex_=true; + use_tex_=false; } void IndexedVertexArray::FlagRefresh() diff --git a/modules/gfx/src/vertex_array.hh b/modules/gfx/src/vertex_array.hh index 1a945f7cf6094738b0a539bfad19d72ee1767d39..ee63c939aae475959cfa12963b730f7326392df6 100644 --- a/modules/gfx/src/vertex_array.hh +++ b/modules/gfx/src/vertex_array.hh @@ -39,6 +39,7 @@ #include "material.hh" #include "gfx_prim.hh" #include "povray_fw.hh" +#include "exporter_fw.hh" namespace ost { namespace gfx { @@ -107,10 +108,14 @@ class DLLEXPORT_OST_GFX IndexedVertexArray { void SetLineHalo(float lh); void SetOutlineMode(int m); + int GetOutlineMode() const {return outline_mode_;} void SetOutlineWidth(float f); + float GetOutlineWidth() const {return outline_width_;} void SetOutlineMaterial(const Material& m); void SetOutlineExpandFactor(float f); + float GetOutlineExpandFactor() const {return outline_exp_factor_;} void SetOutlineExpandColor(const Color& c); + Color GetOutlineExpandColor() const {return outline_exp_color_;} // vertex, normal, color and texcoord (T2F_C4F_N3F_V3F) VertexID Add(const geom::Vec3& vert, const geom::Vec3& norm, const Color& col, const geom::Vec2& tex=geom::Vec2()); @@ -158,6 +163,8 @@ class DLLEXPORT_OST_GFX IndexedVertexArray { // POVray export void RenderPov(PovState& pov, const std::string& name); + void Export(Exporter* ex) const; + // only removes the drawing elements void Clear(); // removes all elements and resets internal state to default diff --git a/modules/gfx/tests/test_gfx.py b/modules/gfx/tests/test_gfx.py index b6911eee12fc2a5401a11d1284dc14d1eb7e3f17..0ddeeab7e2961fd9187f7e7bb9414ab8191c1a0a 100644 --- a/modules/gfx/tests/test_gfx.py +++ b/modules/gfx/tests/test_gfx.py @@ -1,3 +1,22 @@ +#------------------------------------------------------------------------------ +# This file is part of the OpenStructure project <www.openstructure.org> +# +# Copyright (C) 2008-2011 by the OpenStructure authors +# +# This library is free software; you can redistribute it and/or modify it under +# the terms of the GNU Lesser General Public License as published by the Free +# Software Foundation; either version 3.0 of the License, or (at your option) +# any later version. +# This library is distributed in the hope that it will be useful, but WITHOUT +# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS +# FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more +# details. +# +# You should have received a copy of the GNU Lesser General Public License +# along with this library; if not, write to the Free Software Foundation, Inc., +# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA +#------------------------------------------------------------------------------ + import unittest if __name__== '__main__': import sys @@ -9,15 +28,44 @@ import ost.mol as mol import ost.gfx as gfx import ost.geom as geom +if ost.WITH_NUMPY: + has_numpy=True + try: + import numpy + except ImportError, e: + has_numpy=False +else: + has_numpy=False + def col_delta(c1,c2): return geom.Distance(geom.Vec3(c1[0],c1[1],c1[2]),geom.Vec3(c2[0],c2[1],c2[2])) +class MyGfxObj(gfx.GfxObj): + def __init__(self,name): + gfx.GfxObj.__init__(self,name) + self.rendered=False + + def CustomRenderGL(self,render_pass): + self.rendered=True + class TestGfx(unittest.TestCase): def runTest(self): self.test_gradient() self.test_color() self.test_primlist() self.test_entity_reset() + self.test_custom_gfx_obj() + self.test_gfxobj_conv() + + def test_gfxobj_conv(self): + e=mol.CreateEntity() + gfx.Scene().Add(gfx.Entity("foo2",e)) + gfx.Scene()["foo2"].SetColor(gfx.YELLOW) + + def test_custom_gfx_obj(self): + myobj=MyGfxObj("foo") + gfx.Scene().Add(myobj) + #self.assertTrue(myobj.rendered) def test_entity_reset(self): eh=mol.CreateEntity() @@ -32,7 +80,8 @@ class TestGfx(unittest.TestCase): def test_gradient(self): gs=[gfx.Gradient(), - gfx.Gradient({0.0: [1,0,0], 1.0: gfx.Color(0,1,0)})] + gfx.Gradient({0.0: [1,0,0], 1.0: gfx.Color(0,1,0)}), + gfx.Gradient([[1,0,0], gfx.Color(0,1,0)])] gs[0].SetColorAt(0.0,gfx.Color(1.0,0.0,0.0)) gs[0].SetColorAt(1.0,gfx.Color(0.0,1.0,0.0)) for g in gs: @@ -71,6 +120,16 @@ class TestGfx(unittest.TestCase): pl.AddCyl(geom.Vec3(0,0,0),geom.Vec3(1,2,3),radius1=0.5,radius2=0.1,color1=gfx.BLUE,color2=gfx.GREEN) pl.AddText("foo",[0,2,3]) pl.AddText("bar",[-2,0,0],color=gfx.WHITE,point_size=8) + if has_numpy: + pl.AddMesh(numpy.zeros((5,3),dtype=numpy.float32), + numpy.zeros((5,3),dtype=numpy.float32), + numpy.zeros((5,4),dtype=numpy.float32), + numpy.zeros((2,3),dtype=numpy.uint32)) + pl.AddMesh(numpy.zeros((7,3),dtype=numpy.float32), + None, + None, + numpy.zeros((4,3),dtype=numpy.uint32)) + if __name__== '__main__': unittest.main() diff --git a/modules/gfx/tests/test_gost_export.py b/modules/gfx/tests/test_gost_export.py new file mode 100644 index 0000000000000000000000000000000000000000..efb56861b18f52fae0b92d25e62477b06901fdfe --- /dev/null +++ b/modules/gfx/tests/test_gost_export.py @@ -0,0 +1,22 @@ +import desost_util as util + +e=io.LoadPDB("../../../examples/demos/data/sdh.pdb") + +s=util.CreateSurf(e.Select("chain=A"),density=4) + +scene.Add(gfx.Entity("trace",gfx.TUBE,e.Select("chain=A"))) +scene["trace"].tube_options.arc_detail=8 +scene["trace"].tube_options.spline_detail=8 +scene["trace"].tube_options.tube_radius=1.0 +grad=gfx.Gradient() +grad.SetColorAt(0.0,gfx.RED) +grad.SetColorAt(0.5,gfx.GREEN) +grad.SetColorAt(1.0,gfx.BLUE) +scene["trace"].ColorBy("rnum",grad) + +scene.Add(gfx.Surface("surf",s)) +scene["surf"].ColorBy("rnum",grad) + +if not gui_mode: + ge = gfx.GostExporter("test.gost") + scene.Export(ge) diff --git a/modules/gfx/tests/test_gost_import.py b/modules/gfx/tests/test_gost_import.py new file mode 100644 index 0000000000000000000000000000000000000000..deebd2d31d805c7c0cc190d5ad273262dc7728bf --- /dev/null +++ b/modules/gfx/tests/test_gost_import.py @@ -0,0 +1,15 @@ +import struct + +with open("test.gost","rb") as gf: + + header = gf.read(6) + if str(header[0:4]) != "GOST": + raise RuntimeError("file format mismatch") + raw = gf.read(16) + + while raw: + (type, subtype,size) = struct.unpack("iiL",raw) + print "found type=%d, subtype=%d and blocksize=%u"%(type,subtype,size) + if size>0: + data = gf.read(size) + raw = gf.read(16) diff --git a/modules/gui/src/CMakeLists.txt b/modules/gui/src/CMakeLists.txt index 7c8f6d640e5dd6c18d85d42b686a7eb82396ae80..c8dc99f72669ed86d28e8cdd768b59ff18b3ad63 100644 --- a/modules/gui/src/CMakeLists.txt +++ b/modules/gui/src/CMakeLists.txt @@ -471,5 +471,13 @@ if (NOT WIN32) set(LINK LINK ${BOOST_PROGRAM_OPTIONS_LIBRARIES}) endif() -executable(NAME gosty SOURCES gosty.cc ${OST_GOSTY_MOC} ${OST_QT_RESOURCE} +executable_libexec(NAME gosty SOURCES gosty.cc ${OST_GOSTY_MOC} ${OST_QT_RESOURCE} DEPENDS_ON ost_gui ${LINK}) + +file(GLOB MOC_CXX_FILES moc_*.cxx) + +if (MOC_CXX_FILES) + set_directory_properties(PROPERTIES ADDITIONAL_MAKE_CLEAN_FILES + "${MOC_CXX_FILES}") +endif() + diff --git a/modules/gui/src/data_viewer/mask_overlay.cc b/modules/gui/src/data_viewer/mask_overlay.cc index 6b52851831d44995a70eb3f6beffe518bada2447..c0c0e6560344c59f75cb95031a1a372086aba0ad 100644 --- a/modules/gui/src/data_viewer/mask_overlay.cc +++ b/modules/gui/src/data_viewer/mask_overlay.cc @@ -57,43 +57,46 @@ MaskOverlay::MaskOverlay(const MaskPtr& m): void MaskOverlay::OnDraw(QPainter& pnt, DataViewerPanel* dvp, bool is_active) { + QPainter::RenderHints render_hints=pnt.renderHints(); + pnt.setRenderHints(render_hints | QPainter::Antialiasing); for (int i=0;i<static_cast<int>(polygons_.size());++i){ if(is_active){ if(i==active_){ - pnt.setPen(QPen(QColor(255,255,0),2)); + pnt.setPen(QPen(QColor(255,255,0),1)); pnt.setBrush(QColor(255,255,0,30)); }else{ - pnt.setPen(QPen(QColor(255,0,0),2)); + pnt.setPen(QPen(QColor(255,0,0),1)); pnt.setBrush(QColor(255,0,0,30)); } }else{ - pnt.setPen(QPen(QColor(100,100,100),2)); + pnt.setPen(QPen(QColor(100,100,100),1)); pnt.setBrush(QColor(100,100,100,30)); } geom::Polygon2 pol=polygons_[i]; QPolygon qpol; for(int j=0;j<static_cast<int>(pol.GetNodeCount());++j){ qpol << dvp->FracPointToWinCenter(pol.GetNode(j)+shift_); - pnt.drawEllipse(qpol.back(),3,3); + pnt.drawEllipse(qpol.back(),4,4); } pnt.drawPolygon(qpol); } if(add_mode_) { if(is_active){ - pnt.setPen(QPen(QColor(255,0,255),3)); + pnt.setPen(QPen(QColor(255,0,255),1)); pnt.setBrush(QColor(255,0,255,30)); }else{ - pnt.setPen(QPen(QColor(100,100,100),2)); + pnt.setPen(QPen(QColor(100,100,100),1)); pnt.setBrush(QColor(100,100,100,30)); } QPolygon qpol; for(int j=0;j<static_cast<int>(new_poly_.GetNodeCount());++j){ qpol << dvp->FracPointToWinCenter(new_poly_.GetNode(j)+shift_); - pnt.drawEllipse(qpol.back(),3,3); + pnt.drawEllipse(qpol.back(),4,4); } pnt.drawPolygon(qpol); } + pnt.setRenderHints(render_hints); } bool MaskOverlay::OnMouseEvent(QMouseEvent* e, DataViewerPanel* dvp, @@ -118,7 +121,7 @@ bool MaskOverlay::OnMouseEvent(QMouseEvent* e, DataViewerPanel* dvp, if(active_>=0){ geom::Polygon2 pol=polygons_[active_]; for(unsigned int j=0;j<pol.GetNodeCount();++j){ - if(Length(mousepos-(pol.GetNode(j)+shift_))<3){ + if(Length(mousepos-(pol.GetNode(j)+shift_))<4){ active_node_=j; return true; } @@ -128,7 +131,7 @@ bool MaskOverlay::OnMouseEvent(QMouseEvent* e, DataViewerPanel* dvp, if(i!=active_){ geom::Polygon2 pol=polygons_[i]; for(unsigned int j=0;j<pol.GetNodeCount();++j){ - if(Length(mousepos-pol.GetNode(j))<3){ + if(Length(mousepos-(pol.GetNode(j)+shift_))<4){ active_=i; active_node_=j; return true; @@ -142,7 +145,7 @@ bool MaskOverlay::OnMouseEvent(QMouseEvent* e, DataViewerPanel* dvp, } } if(e->buttons() & Qt::LeftButton && active_>=0 && active_node_>=0 && ! (e->modifiers() & Qt::ShiftModifier)){ - polygons_[active_].SetNode(active_node_,mousepos); + polygons_[active_].SetNode(active_node_,mousepos-shift_); } return false; } diff --git a/modules/gui/src/data_viewer/overlay_manager_gui.cc b/modules/gui/src/data_viewer/overlay_manager_gui.cc index 74d24415c5bc1431389b8437becad5e4db400782..ba9d884cbd88b0f603c670a93dcfb995eb168177 100644 --- a/modules/gui/src/data_viewer/overlay_manager_gui.cc +++ b/modules/gui/src/data_viewer/overlay_manager_gui.cc @@ -135,6 +135,7 @@ void OverlayManagerGUI::OnAddOverlay(OverlayManager* m, int id) OverlayPtr ov = m->RetrieveOverlay(id); connect(ov.get(),SIGNAL(InfoTextChanged(const QString&)),this,SLOT(SetInfoText(const QString&))); OverlayEntry oe; + oe.row=0.0; oe.a=new OverlayCustomActCheckBox(id,m); connect(oe.a,SIGNAL(toggled(bool)),oe.a,SLOT(OnToggle(bool))); active_group_->addButton(oe.a); diff --git a/modules/gui/src/gosty.cc b/modules/gui/src/gosty.cc index cb1ed73843039048077f703cf36820dcf32cdc47..3ea2bdda6e64bb18677c0cb86ac08fb303bddf95 100644 --- a/modules/gui/src/gosty.cc +++ b/modules/gui/src/gosty.cc @@ -82,13 +82,27 @@ String get_ost_root() { QDir dir(QApplication::applicationDirPath()); +#if OST_DEBIAN_STYLE_LIBEXEC #ifdef _MSC_VER dir.cdUp(); dir.cdUp(); + dir.cdUp(); + dir.cdUp(); #else dir.cdUp(); + dir.cdUp(); + dir.cdUp(); #endif - +#else + #ifdef _MSC_VER + dir.cdUp(); + dir.cdUp(); + dir.cdUp(); + #else + dir.cdUp(); + dir.cdUp(); + #endif +#endif return dir.path().toStdString(); } @@ -186,10 +200,11 @@ void prepare_scripts(int argc, char** argv, PythonInterpreter& py) int main(int argc, char** argv) { int dummy_argc=1; + QApplication app(dummy_argc,argv); QCoreApplication::setOrganizationName("OpenStructure"); QCoreApplication::setOrganizationDomain("openstructure.org"); - QCoreApplication::setApplicationName(argv[0]); + QCoreApplication::setApplicationName(QString(argv[2])); app.setLibraryPaths(QStringList()); if (int rv=setup_resources(app)<0) { return rv; diff --git a/modules/io/pymod/export_map_io.cc b/modules/io/pymod/export_map_io.cc index beb7601bc63916a64e52e74035c853ebbb778662..afe494d1997b4d1720fe49592b35c36e51976980 100644 --- a/modules/io/pymod/export_map_io.cc +++ b/modules/io/pymod/export_map_io.cc @@ -27,6 +27,7 @@ #include <ost/io/img/map_io_dat_handler.hh> #include <ost/io/img/map_io_jpk_handler.hh> #include <ost/io/img/map_io_nanoscope_handler.hh> +#include <ost/io/img/map_io_ipl_handler.hh> #include <ost/io/img/image_format.hh> #include <ost/io/img/load_map.hh> @@ -79,18 +80,17 @@ void export_map_io() .export_values() ; - enum_<Subformat>("Format") + enum_<Subformat>("Subformat") .value("MRC_NEW_FORMAT", MRC_NEW_FORMAT) .value("MRC_OLD_FORMAT", MRC_OLD_FORMAT) .value("MRC_AUTO_FORMAT", MRC_AUTO_FORMAT) .export_values() ; + class_<ImageFormatBase>("ImageFormatBase",no_init) .def("GetMaximum", &ImageFormatBase::GetMaximum) - .def("SetMaximum", &ImageFormatBase::GetMaximum) .def("GetMinimum", &ImageFormatBase::GetMinimum) - .def("SetMinimum", &ImageFormatBase::GetMinimum) ; class_<DX, bases<ImageFormatBase> >("DX", init<bool>(arg("normalize_on_save") = false)) @@ -154,6 +154,13 @@ void export_map_io() .def("GetBitDepth", &DAT::GetBitDepth) ; + class_<IPL, bases<ImageFormatBase> >("IPL", init<bool,Format>((arg("normalize_on_save") = true,arg("format")=OST_DEFAULT_FORMAT))) + .def("SetNormalizeOnSave", &IPL::SetNormalizeOnSave) + .def("GetNormalizeOnSave", &IPL::GetNormalizeOnSave) + .def("SetBitDepth", &IPL::SetBitDepth) + .def("GetBitDepth", &IPL::GetBitDepth) + ; + class_<JPK, bases<TIF> >("JPK", init<boost::logic::tribool,Format,bool,bool,int> ((arg("normalize_on_save") = boost::logic::tribool(boost::logic::indeterminate),arg("format")=OST_DEFAULT_FORMAT,arg("signed")=false,arg("phasecolor")=false,arg("subimage") = -1))) ; diff --git a/modules/io/src/img/CMakeLists.txt b/modules/io/src/img/CMakeLists.txt index 8fa9a30ffd45564867fef83e5b17ef7bee0250b0..d17f46e8ec5e043b1a74c67ee900e5e01271ccd7 100644 --- a/modules/io/src/img/CMakeLists.txt +++ b/modules/io/src/img/CMakeLists.txt @@ -7,6 +7,7 @@ map_io_mrc_handler.cc map_io_dm3_handler.cc map_io_tiff_handler.cc map_io_dat_handler.cc +map_io_ipl_handler.cc map_io_jpk_handler.cc map_io_nanoscope_handler.cc map_io_png_handler.cc @@ -28,6 +29,7 @@ map_io_situs_handler.hh map_io_handler.hh map_io_mrc_handler.hh map_io_dat_handler.hh +map_io_ipl_handler.hh map_io_jpk_handler.hh map_io_nanoscope_handler.hh map_io_png_handler.hh diff --git a/modules/io/src/img/map_io_ipl_handler.cc b/modules/io/src/img/map_io_ipl_handler.cc new file mode 100644 index 0000000000000000000000000000000000000000..dd1fb2981a1f8c95f407331086508253a425f450 --- /dev/null +++ b/modules/io/src/img/map_io_ipl_handler.cc @@ -0,0 +1,416 @@ +//------------------------------------------------------------------------------ +// This file is part of the OpenStructure project <www.openstructure.org> +// +// Copyright (C) 2008-2011 by the OpenStructure authors +// Copyright (C) 2003-2010 by the IPLT authors +// +// This library is free software; you can redistribute it and/or modify it under +// the terms of the GNU Lesser General Public License as published by the Free +// Software FounIPLion; either version 3.0 of the License, or (at your option) +// any later version. +// This library is distributed in the hope that it will be useful, but WITHOUT +// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS +// FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more +// details. +// +// You should have received a copy of the GNU Lesser General Public License +// along with this library; if not, write to the Free Software FounIPLion, Inc., +// 51 Franklin Street, Fifth Floor, Boston, MA 02110String::npos301 USA +//------------------------------------------------------------------------------ +#include <cassert> +#include <ctime> +#include <iomanip> +#include <cstring> + +#include <boost/shared_array.hpp> +#include <boost/filesystem/operations.hpp> +#include <boost/filesystem/fstream.hpp> +#include <ost/stdint.hh> +#include <ost/units.hh> +#include <ost/log.hh> +#include <ost/img/image.hh> +#include <ost/img/alg/normalizer_factory.hh> +#include <ost/img/progress.hh> +#include <ost/io/io_exception.hh> +#include <ost/io/convert.hh> +#include <ost/io/converting_streams.hh> +#include <ost/img/alg/discrete_shrink.hh> + +#include "map_io_ipl_handler.hh" + +namespace ost { namespace io { + +String IPL::FORMAT_STRING = "defined_ipl"; + +IPL::IPL(bool normalize_on_save, Format bit_depth): + ImageFormatBase(FORMAT_STRING), + normalize_on_save_(normalize_on_save), + bit_depth_(OST_DEFAULT_FORMAT) +{ + this->SetBitDepth(bit_depth); +} + +Format IPL::GetBitDepth() const +{ + return bit_depth_; +} + +void IPL::SetBitDepth (Format bitdepth) +{ + if( ! (bitdepth==OST_BIT16_FORMAT || bitdepth==OST_BIT32_FORMAT || bitdepth==OST_DEFAULT_FORMAT)) + { + throw IOException("Unsupported bit depth for IPL file format."); + } + + bit_depth_ = bitdepth; +} + +bool IPL::GetNormalizeOnSave() const +{ + return normalize_on_save_; +} + +void IPL::SetNormalizeOnSave(bool normalize_on_save) +{ + normalize_on_save_ = normalize_on_save; +} + +Real IPL::GetMaximum() const +{ + switch(bit_depth_){ + case OST_BIT32_FORMAT: + return 4294967295.0; + default: + return 65535.0; + } +} + +Real IPL::GetMinimum() const +{ + return 0.0; +} + +bool MapIOIPLHandler::MatchContent(unsigned char* header) +{ + String magic_token("DITABIS micron Data File"); + if(magic_token.compare(0,magic_token.size(),reinterpret_cast<char*>(header),magic_token.size())==0) + { + return true; + } + return false; +} + +namespace detail{ + +class IPLHeader{ +public: + IPLHeader(): + date(), + header_length(2048), + size_x(), + size_y(), + bit_depth(), + resolution_x(), + resolution_y(), + magnification(1), + thumb_nail_zoom(10), + channel("PMT LOWSENS"), + params("dummy.set"), + format("2 2 2 2 Standard.fmt"), + laser(30), + gain(20000), + offset_correction(true), + offset(0), + comment() + {} + IPLHeader(const img::ConstImageHandle& im,Format bit_depth): + date(), + header_length(2048), + size_x(im.GetSize()[0]), + size_y(im.GetSize()[1]), + bit_depth(bit_depth==OST_BIT32_FORMAT ? 4: 2), + resolution_x(im.GetSpatialSampling()[0]), + resolution_y(im.GetSpatialSampling()[1]), + magnification(1), + thumb_nail_zoom(10), + channel("PMT LOWSENS"), + params("dummy.set"), + format("2 2 2 2 Standard.fmt"), + laser(30), + gain(20000), + offset_correction(true), + offset(0), + comment() + {} + String date; + int header_length; + int size_x; + int size_y; + int bit_depth; + Real resolution_x; + Real resolution_y; + int magnification; + int thumb_nail_zoom; + String channel; + String params; + String format; + int laser; + int gain; + bool offset_correction; + int offset; + String comment; +}; + +std::ostream& operator<< (std::ostream& out, const IPLHeader& h ) +{ + uint start_pos = out.tellp(); + out << "DITABIS micron Data File\r\n"; + time_t rawtime=time(NULL); + char * timestr = asctime(localtime(&rawtime)); + timestr[strlen(timestr)-1] = '\0'; + out << "CREATED = "<< timestr <<" \r\n"; + out << "HEADER = "<< h.header_length <<" \r\n"; + // x and y get swapped here (follows the behaviour of the original conversion software) + out << "YPIXEL = "<< h.size_x <<" \r\n"; + out << "XPIXEL = "<< h.size_y <<" \r\n"; + out << "BYTE PER PIXEL = "<< h.bit_depth <<" \r\n"; + // x and y get swapped here (follows the behaviour of the original conversion software) + out << "XRESOLUTION = "<< std::setprecision(0)<< h.resolution_y/Units::nm <<" (" << std::setprecision(2)<< h.resolution_y/Units::nm<<") \r\n"; + out << "YRESOLUTION = "<< std::setprecision(0)<< h.resolution_x/Units::nm <<" (" << std::setprecision(2)<< h.resolution_x/Units::nm<<") \r\n"; + out << "MAGNIFICATION = "<< h.magnification <<" \r\n"; + out << "THUMB-NAIL-ZOOM = "<< h.thumb_nail_zoom <<" \r\n"; + out << "CHANNEL = "<< h.channel <<" \r\n"; + out << "PARAMS = "<< h.params <<" \r\n"; + out << "FORMAT = "<< h.format <<" \r\n"; + out << "LASER = "<< h.laser <<" \r\n"; + out << "GAIN = "<< h.gain <<" \r\n"; + if(h.offset_correction){ + out << "OFFSET CORRECTION = YES \r\n"; + }else{ + out << "OFFSET CORRECTION = NO \r\n"; + } + out << "OFFSET = "<< h.offset <<" \r\n"; + out << "COMMENT = Created by OpenStructure \r\n"; + out << " \r\n"; + uint fillsize=h.header_length-out.tellp()+start_pos; + char empty[fillsize]; + std::fill_n(empty,fillsize,0); + out.write(empty,fillsize); + return out; +} + +std::istream& operator>> (std::istream& in, IPLHeader& h) +{ + String line; + uint start_pos = in.tellg(); + do{ + std::getline(in,line); + if(line.find("DITABIS micron Data File")!=String::npos){ + //ignore + }else if(line.find("CREATED")!=String::npos){ + h.date=line.substr(line.find("=")+2); + }else if(line.find("HEADER")!=String::npos){ + std::istringstream ( line.substr(line.find("=")+2) ) >> h.header_length; + // x and y get swapped here (follows the behaviour of the original conversion software) + }else if(line.find("XPIXEL")!=String::npos){ + std::istringstream ( line.substr(line.find("=")+2) ) >> h.size_y; + }else if(line.find("YPIXEL")!=String::npos){ + std::istringstream ( line.substr(line.find("=")+2) ) >> h.size_x; + }else if(line.find("BYTE PER PIXEL")!=String::npos){ + std::istringstream ( line.substr(line.find("=")+2) ) >> h.bit_depth; + // x and y get swapped here (follows the behaviour of the original conversion software) + }else if(line.find("XRESOLUTION")!=String::npos){ + std::istringstream ( line.substr(line.find("(")+1) ) >> h.resolution_y; + h.resolution_y*=Units::nm; + }else if(line.find("YRESOLUTION")!=String::npos){ + std::istringstream ( line.substr(line.find("(")+1) ) >> h.resolution_x; + h.resolution_x*=Units::nm; + }else if(line.find("MAGNIFICATION")!=String::npos){ + std::istringstream ( line.substr(line.find("=")+2) ) >> h.magnification; + }else if(line.find("THUMB-NAIL-ZOOM")!=String::npos){ + std::istringstream ( line.substr(line.find("=")+2) ) >> h.thumb_nail_zoom; + }else if(line.find("CHANNEL")!=String::npos){ + h.channel=line.substr(line.find("=")+2); + }else if(line.find("PARAMS")!=String::npos){ + h.params=line.substr(line.find("=")+2); + }else if(line.find("FORMAT")!=String::npos){ + h.format=line.substr(line.find("=")+2); + }else if(line.find("LASER")!=String::npos){ + std::istringstream ( line.substr(line.find("=")+2) ) >> h.laser; + }else if(line.find("GAIN")!=String::npos){ + std::istringstream ( line.substr(line.find("=")+2) ) >> h.gain; + }else if(line.find("OFFSET CORRECTION")!=String::npos){ + if(line.substr(line.find("=")+2).find("YES")!=String::npos){ + h.offset_correction=true; + }else{ + h.offset_correction=false; + } + }else if(line.find("OFFSET")!=String::npos){ + std::istringstream ( line.substr(line.find("=")+2) ) >> h.offset; + }else if(line.find("COMMENT")!=String::npos){ + h.comment=line.substr(line.find("=")+2); + }else if(line.find(" ")!=String::npos){ + //ignore + }else{ + LOG_ERROR("IPL import: unknown header line: " << line); + } + }while(in.peek()!=0); + uint fillsize=h.header_length-in.tellg()+start_pos; + char empty[h.header_length]; + std::fill_n(empty,fillsize,0); + in.read(empty,fillsize); + return in; +} + +}//ns + +bool MapIOIPLHandler::MatchType(const ImageFormatBase& type) +{ + if(type.GetFormatString()==IPL::FORMAT_STRING) { + return true; + } + return false; +} + +bool MapIOIPLHandler::MatchSuffix(const String& loc) +{ + if(detail::FilenameEndsWith(loc,".IPL") || detail::FilenameEndsWith(loc,".ipl") ) { + return true; + } + return false; +} + +void MapIOIPLHandler::Import(img::MapHandle& sh, const boost::filesystem::path& loc,const ImageFormatBase& formatstruct ) +{ + boost::filesystem::ifstream infile(loc, std::ios::binary); + if(!infile) { + throw IOException("could not open "+loc.string()); + } + this->Import(sh,infile,formatstruct); + infile.close(); +} + +template <typename DATATYPE> +void real_filler(img::image_state::RealSpatialImageState& isi, std::istream& file) +{ + BinaryIStream<OST_LITTLE_ENDIAN> file_bin(file); + img::Size size = isi.GetSize(); + char this_dummy; //create dummy variable to give to img::Progress as this + img::Progress::Instance().Register(&this_dummy,size[1],100); + for(unsigned int row=0;row<size[1];row++) { + for(unsigned int column=0;column<size[0];column++) { + DATATYPE value; + file_bin >> value; + isi.Value(img::Point(column,row))=static_cast<Real>(value); + } + img::Progress::Instance().AdvanceProgress(&this_dummy); + } + img::Progress::Instance().DeRegister(&this_dummy); +} + +template <typename DATATYPE> +void real_dumper( const img::ConstImageHandle& sh, std::ostream& file, const IPL& formatIPL, int shrinksize) +{ + img::image_state::RealSpatialImageState *isi=dynamic_cast<img::image_state::RealSpatialImageState*>(sh.ImageStatePtr().get()); + if(! isi){ + throw(IOException("IPL export: dynamic cast failed in real dumper.")); + } + BinaryOStream<OST_LITTLE_ENDIAN> file_bin(file); + img::alg::Normalizer norm = img::alg::CreateNoOpNormalizer(); + if (formatIPL.GetNormalizeOnSave() == true) { + norm = img::alg::CreateLinearRangeNormalizer(sh,formatIPL.GetMinimum(),formatIPL.GetMaximum()); + } + img::Size size = isi->GetSize(); + img::ImageHandle thumbnail=sh.Apply(img::alg::DiscreteShrink(img::Size(shrinksize,shrinksize,1))); + img::image_state::RealSpatialImageState *thumb_isi=dynamic_cast<img::image_state::RealSpatialImageState*>(thumbnail.ImageStatePtr().get()); + if(! thumb_isi){ + throw(IOException("IPL export: dynamic cast failed in real dumper.")); + } + + char this_dummy; //create dummy variable to give to img::Progress as this + img::Progress::Instance().Register(&this_dummy,size[1]+1,100); + for(unsigned int row=0;row<size[1];row++) { + for(unsigned int column=0;column<size[0];column++) + { + file_bin << static_cast<DATATYPE>(norm.Convert(isi->Value(ost::img::Point(column,row,0)))); + } + img::Progress::Instance().AdvanceProgress(&this_dummy); + } + img::Progress::Instance().AdvanceProgress(&this_dummy); + img::Size thumb_size = thumb_isi->GetSize(); + for(unsigned int row=0;row<thumb_size[1];row++) { + for(unsigned int column=0;column<thumb_size[0];column++) + { + file_bin << static_cast<DATATYPE>(norm.Convert(thumb_isi->Value(ost::img::Point(column,row,0)))); + } + img::Progress::Instance().AdvanceProgress(&this_dummy); + } + img::Progress::Instance().DeRegister(&this_dummy); +} + + +void MapIOIPLHandler::Import(img::MapHandle& sh, std::istream& file, const ImageFormatBase& formatstruct) +{ + + IPL form; + IPL& formatIPL = form; + if (formatstruct.GetFormatString()==IPL::FORMAT_STRING) { + formatIPL = formatstruct.As<IPL>(); + } else { + assert (formatstruct.GetFormatString()==UndefinedImageFormat::FORMAT_STRING); + } + + detail::IPLHeader header; + file >> header; + + sh.Reset(img::Extent(img::Point(0,0),img::Size(header.size_x,header.size_y)), img::REAL, img::SPATIAL); + sh.SetSpatialSampling(geom::Vec3(header.resolution_x,header.resolution_y,1.0)); + img::image_state::RealSpatialImageState * isi; + if(! (isi=dynamic_cast<img::image_state::RealSpatialImageState*>(sh.ImageStatePtr().get()))) { + throw IOException("internal error in IPL io: expected RealSpatialImageState"); + } + + if(header.bit_depth==4){ + real_filler<uint32_t>(*isi,file); + }else{ + real_filler<uint16_t>(*isi,file); + } +} + +void MapIOIPLHandler::Export(const img::MapHandle& mh2, + const boost::filesystem::path& loc,const ImageFormatBase& formatstruct) const +{ + boost::filesystem::ofstream outfile(loc, std::ios::binary); + if(!outfile) + { + throw IOException("could not open "+loc.string()); + } + this->Export(mh2,outfile,formatstruct); + outfile.close(); +} + +void MapIOIPLHandler::Export(const img::MapHandle& sh, std::ostream& file,const ImageFormatBase& formatstruct) const +{ + + IPL form; + IPL& formatIPL = form; + if (formatstruct.GetFormatString()==IPL::FORMAT_STRING) { + formatIPL = formatstruct.As<IPL>(); + } else { + assert (formatstruct.GetFormatString()==UndefinedImageFormat::FORMAT_STRING); + } + if (sh.GetSize()[2]!=1 || sh.GetDomain()!=img::SPATIAL || sh.GetType()!=img::REAL) { + throw IOException("IPL IO: IPL format only supports spatial 2D images."); + } + detail::IPLHeader header(sh,formatIPL.GetBitDepth()); + file << header; + if(header.bit_depth==4){ + real_dumper<uint32_t>(sh,file,formatIPL,header.thumb_nail_zoom); + }else{ + real_dumper<uint16_t>(sh,file,formatIPL,header.thumb_nail_zoom); + } +} + +}} // namespaces + + diff --git a/modules/io/src/img/map_io_ipl_handler.hh b/modules/io/src/img/map_io_ipl_handler.hh new file mode 100644 index 0000000000000000000000000000000000000000..3e76ac9895c0689defe002d0399359e03f3e09aa --- /dev/null +++ b/modules/io/src/img/map_io_ipl_handler.hh @@ -0,0 +1,78 @@ +//------------------------------------------------------------------------------ +// This file is part of the OpenStructure project <www.openstructure.org> +// +// Copyright (C) 2008-2011 by the OpenStructure authors +// Copyright (C) 2003-2010 by the IPLT authors +// +// This library is free software; you can redistribute it and/or modify it under +// the terms of the GNU Lesser General Public License as published by the Free +// Software Foundation; either version 3.0 of the License, or (at your option) +// any later version. +// This library is distributed in the hope that it will be useful, but WITHOUT +// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS +// FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more +// details. +// +// You should have received a copy of the GNU Lesser General Public License +// along with this library; if not, write to the Free Software Foundation, Inc., +// 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA +//------------------------------------------------------------------------------ +#ifndef OST_IO_MAP_IO_IPL_HANDLER_HH +#define OST_IO_MAP_IO_IPL_HANDLER_HH + + +/* +Andreas Schenk +*/ + +#include "map_io_handler.hh" + +namespace ost { namespace io { + +class DLLEXPORT_OST_IO IPL: public ImageFormatBase +{ + + public: + + IPL(bool normalize_on_save = true, Format bit_depth = OST_DEFAULT_FORMAT); + + Format GetBitDepth() const; + void SetBitDepth ( Format bitdepth); + + + bool GetNormalizeOnSave() const; + void SetNormalizeOnSave(bool normalize_on_save=true); + Real GetMaximum() const; + Real GetMinimum() const; + static String FORMAT_STRING; + + private: + bool normalize_on_save_; + Format bit_depth_; + +}; + +class DLLEXPORT_OST_IO MapIOIPLHandler: public MapIOHandler +{ + public: + /// \brief Map IO handler to read/write Ipl map files + /// + /// This map IO handler reads and writes Ipl formatted map files. + virtual void Import(img::MapHandle& sh, const boost::filesystem::path& loc,const ImageFormatBase& formatstruct ); + virtual void Import(img::MapHandle& sh, std::istream& loc, const ImageFormatBase& formatstruct); + virtual void Export(const img::MapHandle& sh, const boost::filesystem::path& loc, const ImageFormatBase& formatstruct) const; + virtual void Export(const img::MapHandle& sh, std::ostream& loc,const ImageFormatBase& formatstruct) const; + static bool MatchContent(unsigned char* header); + static bool MatchType(const ImageFormatBase& type); + static bool MatchSuffix(const String& loc); + static bool ProvidesImport() { return true; } + static bool ProvidesExport() { return true; } + static String GetFormatName() { return String("IPL"); } + static String GetFormatDescription() {return String("Ditabis Micron Image Plate Scanner Format");} +}; + +typedef MapIOHandlerFactory<MapIOIPLHandler> MapIOIPLHandlerFactory; + +}} // ns + +#endif diff --git a/modules/io/src/io_manager.cc b/modules/io/src/io_manager.cc index 12e714fd63a0170d32c676bf60bde007571ff6f6..071be5c11461382803e8a3704bdbd32ba760ed18 100644 --- a/modules/io/src/io_manager.cc +++ b/modules/io/src/io_manager.cc @@ -38,6 +38,7 @@ # include <ost/io/img/map_io_jpk_handler.hh> # include <ost/io/img/map_io_nanoscope_handler.hh> # include <ost/io/img/map_io_df3_handler.hh> +# include <ost/io/img/map_io_ipl_handler.hh> #endif namespace ost { namespace io { @@ -63,7 +64,8 @@ IOManager::IOManager() RegisterFactory(MapIOHandlerFactoryBasePtr(new MapIOJpkHandlerFactory)); RegisterFactory(MapIOHandlerFactoryBasePtr(new MapIODatHandlerFactory)); RegisterFactory(MapIOHandlerFactoryBasePtr(new MapIONanoscopeHandlerFactory)); - RegisterFactory(MapIOHandlerFactoryBasePtr(new MapIODF3HandlerFactory)); + RegisterFactory(MapIOHandlerFactoryBasePtr(new MapIODF3HandlerFactory)); + RegisterFactory(MapIOHandlerFactoryBasePtr(new MapIOIPLHandlerFactory)); #endif } diff --git a/modules/io/src/mol/entity_io_mae_handler.cc b/modules/io/src/mol/entity_io_mae_handler.cc index a60b913f378db4b65a6043dfdf7959ef155d236a..6a5306b055c44f7d6c6ccc82f5defa8c1acd1d35 100644 --- a/modules/io/src/mol/entity_io_mae_handler.cc +++ b/modules/io/src/mol/entity_io_mae_handler.cc @@ -143,7 +143,13 @@ void MAEReader::Import(mol::EntityHandle& ent) else if(line2=="r_m_z_coord") i_atom_zpos=pid; else if(line2=="s_m_pdb_residue_name") i_res_name=pid; else if(line2=="i_m_residue_number") i_res_num=pid; - else if(line2=="s_m_pdb_segment_name") i_chain_name=pid; + else if(line2=="s_m_chain_name") i_chain_name=pid; + else if(line2=="s_m_pdb_segment_name") { + // only use this one if s_m_chain_name is not present + if(i_chain_name<0) { + i_chain_name=pid; + } + } } } } diff --git a/modules/io/src/mol/pdb_reader.cc b/modules/io/src/mol/pdb_reader.cc index c136147a6d408e6c09a3b3a2c5414dc3108ccb2a..53433b1db8898a66fd614f8d916520b731868ee2 100644 --- a/modules/io/src/mol/pdb_reader.cc +++ b/modules/io/src/mol/pdb_reader.cc @@ -781,19 +781,21 @@ void PDBReader::ParseAndAddAtom(const StringRef& line, int line_num, << "residue with number " << res_num << " has more than one name."; throw IOException(ss.str()); } - if (!warned_name_mismatch_) { - if (alt_loc==' ') { - LOG_WARNING("Residue with number " << res_num << " has more than one name." - "Ignoring atoms for everything but the first"); - } else { - LOG_WARNING("Residue with number " << res_num - << " contains a microheterogeneity. Everything but atoms for " - << "the residue '" << curr_residue_.GetName() - << "' will be ignored"); + if(!profile_.quack_mode) { + if (!warned_name_mismatch_) { + if (alt_loc==' ') { + LOG_WARNING("Residue with number " << res_num << " has more than one name. " + "Ignoring atoms for everything but the first"); + } else { + LOG_WARNING("Residue with number " << res_num + << " contains a microheterogeneity. Everything but atoms for " + << "the residue '" << curr_residue_.GetName() + << "' will be ignored"); + } } + warned_name_mismatch_=true; + return; } - warned_name_mismatch_=true; - return; } if (alt_loc!=' ') { // Check if there is already a atom with the same name. diff --git a/modules/io/src/mol/star_parser.cc b/modules/io/src/mol/star_parser.cc index 069deac0eb23216b02cd3f61a4ed8ec460f03f97..d8903a9de0baac3dfc3c037c20f449f9cabaa2da 100644 --- a/modules/io/src/mol/star_parser.cc +++ b/modules/io/src/mol/star_parser.cc @@ -37,7 +37,7 @@ StarParser::StarParser(std::istream& stream, bool items_as_row): items_row_values_() { items_as_row_ = items_as_row; - + if (!stream) { file_open_ = false; } @@ -51,8 +51,6 @@ StarParser::StarParser(const String& filename, bool items_as_row): items_row_header_(), file_open_(true), items_row_columns_(), items_row_values_() { - items_as_row_ = items_as_row; - if (filename.length() >= 3 && filename.substr(filename.length() - 3) == ".gz") { stream_.push(boost::iostreams::gzip_decompressor()); diff --git a/modules/io/tests/test_io_img.cc b/modules/io/tests/test_io_img.cc index d8165dd76203ba7fcb1fc8e00fcce5a7df290a62..9f21257d3b942bef23e9043651bc0addf4f0232f 100644 --- a/modules/io/tests/test_io_img.cc +++ b/modules/io/tests/test_io_img.cc @@ -34,6 +34,7 @@ #include <ost/io/img/map_io_dat_handler.hh> #include <ost/io/img/map_io_jpk_handler.hh> #include <ost/io/img/map_io_nanoscope_handler.hh> +#include <ost/io/img/map_io_ipl_handler.hh> #include <ost/img/alg/normalizer_factory.hh> using namespace ost; @@ -82,6 +83,7 @@ BOOST_AUTO_TEST_CASE(test_io_img) } //int 16 formats std::map<String,ImageFormatBase*> int_formats; + int_formats["IPL (16 bit)"]=new IPL(true,OST_BIT16_FORMAT); int_formats["DAT (16 bit)"]=new DAT(true,OST_BIT16_FORMAT); int_formats["TIF (16 bit)"]=new TIF; int_formats["JPK (16 bit)"]=new JPK; @@ -108,6 +110,31 @@ BOOST_AUTO_TEST_CASE(test_io_img) delete it->second; } + //int 32 formats + std::map<String,ImageFormatBase*> int32_formats; + int32_formats["IPL (16 bit)"]=new IPL(true,OST_BIT32_FORMAT); + for(std::map<String,ImageFormatBase*>::iterator it=int32_formats.begin();it!=int32_formats.end();++it){ + ost::io::SaveImage(testimage,fname,*(it->second)); + ost::img::ImageHandle loadedimage=ost::io::LoadImage(fname,*(it->second)); + ost::img::alg::Normalizer norm=ost::img::alg::CreateLinearRangeNormalizer(testimage,0.0,4294967295.0); + ost::img::ImageHandle scaled_image=testimage.Apply(norm); + bool failed=false; + ost::img::ExtentIterator eit(scaled_image.GetExtent()); + for(;!eit.AtEnd();++eit) { + if( static_cast<int>(scaled_image.GetReal(eit))!=static_cast<int>(loadedimage.GetReal(eit))){ + failed=true; + break; + } + } + if(failed){ + BOOST_ERROR("Image IO failed for plugin " << it->first << " at point " + << ost::img::Point(eit)<< ". Should be " + << static_cast<int>(scaled_image.GetReal(eit)) << ", but " + << static_cast<int>(loadedimage.GetReal(eit)) << " found."); + } + delete it->second; + } + //byte formats std::map<String,ImageFormatBase*> byte_formats; byte_formats["DAT (byte)"]=new DAT(true,OST_BIT8_FORMAT); diff --git a/modules/mol/alg/pymod/export_trajectory_analysis.cc b/modules/mol/alg/pymod/export_trajectory_analysis.cc index 31377016a874dc6dcc42cc702d11a3a4058f0934..5671dbca091c49746976714679c04dd48a68fd36 100644 --- a/modules/mol/alg/pymod/export_trajectory_analysis.cc +++ b/modules/mol/alg/pymod/export_trajectory_analysis.cc @@ -46,4 +46,8 @@ void export_TrajectoryAnalysis() def("AnalyzeMinDistance", &AnalyzeMinDistance, (arg("traj"), arg("view1"), arg("view2"), arg("stride")=1)); def("AnalyzeMinDistanceBetwCenterOfMassAndView", &AnalyzeMinDistanceBetwCenterOfMassAndView, (arg("traj"), arg("view_cm"), arg("view_atoms"), arg("stride")=1)); def("AnalyzeAromaticRingInteraction", &AnalyzeAromaticRingInteraction, (arg("traj"), arg("view_ring1"), arg("view_ring2"), arg("stride")=1)); + def("AnalyzeAlphaHelixAxis", &AnalyzeAlphaHelixAxis, (arg("traj"), arg("protein_segment"), arg("directions"), arg("centers"), arg("stride")=1)); + def("AnalyzeBestFitLine", &AnalyzeBestFitLine, (arg("traj"), arg("protein_segment"), arg("directions"), arg("centers"), arg("stride")=1)); + def("AnalyzeHelicity", &AnalyzeHelicity, (arg("traj"), arg("protein_segment"), arg("stride")=1)); + def("CreateMeanStructure", &CreateMeanStructure, (arg("traj"), arg("selection"), arg("from")=0, arg("to")=-1, arg("stride")=1 )); } diff --git a/modules/mol/alg/src/trajectory_analysis.cc b/modules/mol/alg/src/trajectory_analysis.cc index 2c1225e753ba76adacfa3ccfd8dc6a2ccce18a95..7f81b91d13a68edaff14e5ea2fd3a20806443192 100644 --- a/modules/mol/alg/src/trajectory_analysis.cc +++ b/modules/mol/alg/src/trajectory_analysis.cc @@ -25,7 +25,9 @@ #include <ost/geom/vec3.hh> #include <ost/base.hh> #include <ost/geom/geom.hh> +#include <ost/gfx/entity.hh> #include <ost/mol/entity_view.hh> +#include <ost/mol/view_op.hh> #include <ost/mol/coord_group.hh> #include "trajectory_analysis.hh" @@ -230,4 +232,104 @@ std::vector<Real> AnalyzeAromaticRingInteraction(const CoordGroupHandle& traj, c } return dist; } + + void AnalyzeAlphaHelixAxis(const CoordGroupHandle& traj, const EntityView& prot_seg, geom::Vec3List& directions, + geom::Vec3List& centers, unsigned int stride) + { + CheckHandleValidity(traj); + if (prot_seg.GetAtomCount()==0){ + throw std::runtime_error("EntityView is empty"); + } + std::vector<unsigned long> indices_ca; + geom::Line3 axis; + directions.reserve(ceil(traj.GetFrameCount()/float(stride))); + centers.reserve(ceil(traj.GetFrameCount()/float(stride))); + GetCaIndices(prot_seg, indices_ca); + for (size_t i=0; i<traj.GetFrameCount(); i+=stride) { + CoordFramePtr frame=traj.GetFrame(i); + axis=frame->FitCylinder(indices_ca); + directions.push_back(axis.GetDirection()); + centers.push_back(axis.GetOrigin()); + } + return; + } + + //std::vector<geom::Line3> AnalyzeBestFitLine(const CoordGroupHandle& traj, const EntityView& prot_seg, + // unsigned int stride) + void AnalyzeBestFitLine(const CoordGroupHandle& traj, const EntityView& prot_seg, geom::Vec3List& directions, + geom::Vec3List& centers, unsigned int stride) + { + CheckHandleValidity(traj); + if (prot_seg.GetAtomCount()==0){ + throw std::runtime_error("EntityView is empty"); + } + std::vector<unsigned long> indices_ca; + geom::Line3 axis; + directions.reserve(ceil(traj.GetFrameCount()/float(stride))); + centers.reserve(ceil(traj.GetFrameCount()/float(stride))); + GetCaIndices(prot_seg, indices_ca); + for (size_t i=0; i<traj.GetFrameCount(); i+=stride) { + CoordFramePtr frame=traj.GetFrame(i); + axis=frame->GetODRLine(indices_ca); + directions.push_back(axis.GetDirection()); + centers.push_back(axis.GetOrigin()); + } + return; + } + + std::vector<Real> AnalyzeHelicity(const CoordGroupHandle& traj, const EntityView& prot_seg, + unsigned int stride) + { + CheckHandleValidity(traj); + if (prot_seg.GetAtomCount()==0){ + throw std::runtime_error("EntityView is empty"); + } + std::vector<unsigned long> indices_c,indices_o, indices_n, indices_ca; + std::vector<Real> helicity; + helicity.reserve(ceil(traj.GetFrameCount()/float(stride))); + GetCaCONIndices(prot_seg, indices_ca, indices_c, indices_o, indices_n); + for (size_t i=0; i<traj.GetFrameCount(); i+=stride) { + CoordFramePtr frame=traj.GetFrame(i); + helicity.push_back(frame->GetAlphaHelixContent(indices_ca,indices_c,indices_o,indices_n)); + } + return helicity; + } + + //This function constructs mean structures from a trajectory + EntityHandle CreateMeanStructure(const CoordGroupHandle& traj, const EntityView& selection, + int from, int to, unsigned int stride) + { + CheckHandleValidity(traj); + if (to==-1)to=traj.GetFrameCount(); + unsigned int n_atoms=selection.GetAtomCount(); + if (to<from) { + throw std::runtime_error("to smaller than from"); + } + unsigned int n_frames=to-from; + if (n_atoms==0){ + throw std::runtime_error("EntityView is empty"); + } + if (n_frames<=stride) { + throw std::runtime_error("number of frames is too small"); + } + std::vector<unsigned long> indices; + std::vector<geom::Vec3> mean_positions; + EntityHandle eh; + eh=CreateEntityFromView(selection,1); + GetIndices(selection,indices); + mean_positions.assign(n_atoms,geom::Vec3(0.0,0.0,0.0)); + for (int i=from; i<to; i+=stride) { + CoordFramePtr frame=traj.GetFrame(i); + for (unsigned int j=0; j<n_atoms; ++j) { + mean_positions[j]+=(*frame)[indices[j]]; + } + } + mol::XCSEditor edi=eh.EditXCS(mol::BUFFERED_EDIT); + AtomHandleList atoms=eh.GetAtomList(); + for (unsigned int j=0; j<n_atoms; ++j) { + edi.SetAtomPos(atoms[j],mean_positions[j]/Real(n_frames)); + } + return eh; + } + }}} //ns diff --git a/modules/mol/alg/src/trajectory_analysis.hh b/modules/mol/alg/src/trajectory_analysis.hh index faa6c8ea06d657afe169ac688c8cd8e6b8148b11..d2ba49b6eb2862bb1f8fb7ec4a42da2d564aad26 100644 --- a/modules/mol/alg/src/trajectory_analysis.hh +++ b/modules/mol/alg/src/trajectory_analysis.hh @@ -43,5 +43,9 @@ namespace ost { namespace mol { namespace alg { std::vector<Real> DLLEXPORT_OST_MOL_ALG AnalyzeMinDistance(const CoordGroupHandle& traj, const EntityView& view1, const EntityView& view2,unsigned int stride=1); std::vector<Real> DLLEXPORT_OST_MOL_ALG AnalyzeMinDistanceBetwCenterOfMassAndView(const CoordGroupHandle& traj, const EntityView& view_cm, const EntityView& view_atoms,unsigned int stride=1); std::vector<Real> DLLEXPORT_OST_MOL_ALG AnalyzeAromaticRingInteraction(const CoordGroupHandle& traj, const EntityView& view_ring1, const EntityView& view_ring2,unsigned int stride=1); + void DLLEXPORT_OST_MOL_ALG AnalyzeAlphaHelixAxis(const CoordGroupHandle& traj, const EntityView& prot_seg, geom::Vec3List& directions, geom::Vec3List& centers, unsigned int stride=1); + void DLLEXPORT_OST_MOL_ALG AnalyzeBestFitLine(const CoordGroupHandle& traj, const EntityView& prot_seg, geom::Vec3List& directions, geom::Vec3List& centers, unsigned int stride=1); + EntityHandle DLLEXPORT_OST_MOL_ALG CreateMeanStructure(const CoordGroupHandle& traj, const EntityView& selection, int from=0, int to=-1, unsigned int stride=1); + std::vector<Real> DLLEXPORT_OST_MOL_ALG AnalyzeHelicity(const CoordGroupHandle& traj, const EntityView& prot_seg, unsigned int stride=1); }}}//ns #endif diff --git a/modules/mol/base/pymod/export_coord_frame.cc b/modules/mol/base/pymod/export_coord_frame.cc index fdb41fce60b8032ecb6f527256b4b9c90d7cc5e1..6636421ad702ab8dc41f88f865ae8de3fd2ab451 100644 --- a/modules/mol/base/pymod/export_coord_frame.cc +++ b/modules/mol/base/pymod/export_coord_frame.cc @@ -34,7 +34,7 @@ geom::Vec3 (CoordFrame::*get_cm)(const mol::EntityView& sele) = &CoordFrame::Get Real (CoordFrame::*get_dist_cm)(const mol::EntityView& sele1, const mol::EntityView& sele2) = &CoordFrame::GetDistanceBetwCenterOfMass; Real (CoordFrame::*get_rmsd)(const mol::EntityView& Reference_View, const mol::EntityView& sele_View) = &CoordFrame::GetRMSD; Real (CoordFrame::*get_min_dist)(const mol::EntityView& view1, const mol::EntityView& view2) = &CoordFrame::GetMinDistance; - +Real (CoordFrame::*get_alpha)(const mol::EntityView& segment) = &CoordFrame::GetAlphaHelixContent; void export_CoordFrame() { class_<CoordFrame>("CoordFrame",no_init) @@ -46,6 +46,8 @@ void export_CoordFrame() .def("GetDistanceBetwCenterOfMass", get_dist_cm) .def("GetRMSD",get_rmsd) .def("GetMinDistance",get_min_dist) + .def("GetODRLine",&geom::Vec3List::GetODRLine) + .def("GetAlphaHelixContent",get_alpha) ; def("CreateCoordFrame",CreateCoordFrame); } diff --git a/modules/mol/base/pymod/export_residue.cc b/modules/mol/base/pymod/export_residue.cc index c4c43e5d89ca06505a65a7b39035692d7150681e..75d74bdb577c618094ee18223102dfa56f932abe 100644 --- a/modules/mol/base/pymod/export_residue.cc +++ b/modules/mol/base/pymod/export_residue.cc @@ -43,15 +43,34 @@ namespace { void set_sec_struct1(ResidueBase* b, const SecStructure& s) {b->SetSecStructure(s);} void set_sec_struct2(ResidueBase* b, char c) {b->SetSecStructure(SecStructure(c));} - void set_chemclass1(ResidueBase* b, const ChemClass& cc) {b->SetChemClass(cc);} - void set_chemclass2(ResidueBase* b, char c) {b->SetChemClass(ChemClass(c));} + void set_chemclass(ResidueBase* b, object po) + { + extract<ChemClass> ex1(po); + if(ex1.check()) { + b->SetChemClass(ex1()); + } + extract<char> ex2(po); + if(ex2.check()) { + b->SetChemClass(ChemClass(ex2())); + } + std::string st=extract<std::string>(po); + if(st.empty()) { + throw Error("expected non-empty string as chem class"); + } + b->SetChemClass(ChemClass(st[0])); + } } -//BOOST_PYTHON_MEMBER_FUNCTION_OVERLOADS(X_insert_overloads, -// ResidueHandle::InsertAtom, 2, 3) void export_Residue() { + class_<ChemClass>("ChemClass", init<char>(args("chem_class"))) + .def(self!=self) + .def(self==self) + .def("IsPeptideLinking", &ChemClass::IsPeptideLinking) + .def("IsNucleotideLinking", &ChemClass::IsNucleotideLinking) + ; + implicitly_convertible<char, ChemClass>(); class_<ResNum>("ResNum", init<int>(args("num"))) .def(init<int,char>(args("num", "ins_code"))) @@ -125,6 +144,11 @@ void export_Residue() .def("IsPeptideLinking", &ResidueBase::IsPeptideLinking) .add_property("peptide_linking", &ResidueBase::IsPeptideLinking) + .def("GetCentralAtom", &ResidueBase::GetCentralAtom) + .def("SetCentralAtom", &ResidueBase::SetCentralAtom) + .add_property("central_atom", &ResidueBase::GetCentralAtom, &ResidueBase::SetCentralAtom) + .add_property("central_normal", &ResidueBase::GetCentralNormal) + .def("GetKey", &ResidueBase::GetKey, return_value_policy<copy_const_reference>()) .def("GetName", &ResidueBase::GetName, @@ -132,8 +156,8 @@ void export_Residue() .def("GetNumber", &ResidueBase::GetNumber, return_value_policy<copy_const_reference>()) .def("GetChemClass", &ResidueBase::GetChemClass) - .def("SetChemClass", set_chemclass1) - .def("SetChemClass", set_chemclass2) + .add_property("chem_class", &ResidueBase::GetChemClass, set_chemclass) + .def("SetChemClass", set_chemclass) .add_property("is_ligand", &ResidueBase::IsLigand, &ResidueBase::SetIsLigand) .def("IsLigand", &ResidueBase::IsLigand) .def("SetIsLigand", &ResidueBase::SetIsLigand) @@ -186,7 +210,6 @@ void export_Residue() .def("GetCenterOfMass", &ResidueHandle::GetCenterOfMass) .def("GetCenterOfAtoms", &ResidueHandle::GetCenterOfAtoms) .def("GetGeometricCenter", geom_center<ResidueHandle>) - .def("GetCentralAtom", &ResidueHandle::GetCentralAtom) .add_property("mass", &ResidueHandle::GetMass) .add_property("center_of_mass", &ResidueHandle::GetCenterOfMass) .add_property("center_of_atoms", &ResidueHandle::GetCenterOfAtoms) diff --git a/modules/mol/base/src/coord_frame.cc b/modules/mol/base/src/coord_frame.cc index 80ef4f58f3ea3aed2b1ae691b6cc35c70107faf0..efeb37e20fc086ebb425751b258e74334f86d3d1 100644 --- a/modules/mol/base/src/coord_frame.cc +++ b/modules/mol/base/src/coord_frame.cc @@ -28,6 +28,7 @@ #include <ost/mol/view_op.hh> #include <ost/mol/mol.hh> #include "coord_frame.hh" +#include <ost/base.hh> namespace ost { namespace mol { @@ -84,7 +85,52 @@ namespace ost { namespace mol { indices.push_back(i->GetIndex()); } } + + void GetCaIndices(const EntityView& segment, std::vector<unsigned long>& indices_ca){ + mol::AtomView ca; + ResidueViewList residues=segment.GetResidueList(); + indices_ca.reserve(residues.size()); + //for (ResidueViewList::const_iterator res=residues.begin()+1, + // e=residues.end(); res!=e-1; ++res){ + // if (!InSequence((*res).GetHandle(),(*(res+1)).GetHandle())) throw std::runtime_error("Residues are not in a continuous sequence"); + //} + for (ResidueViewList::const_iterator res=residues.begin(), + e=residues.end(); res!=e; ++res) { + ca=res->FindAtom("CA"); + CheckHandleValidity(ca); + indices_ca.push_back(ca.GetIndex()); + } + } + void GetCaCONIndices(const EntityView& segment, std::vector<unsigned long>& indices_ca, + std::vector<unsigned long>& indices_c, std::vector<unsigned long>& indices_o, std::vector<unsigned long>& indices_n){ + mol::AtomView a,n,c,o; + ResidueViewList residues=segment.GetResidueList(); + indices_ca.reserve(residues.size()); + indices_n.reserve(residues.size()); + indices_c.reserve(residues.size()); + indices_o.reserve(residues.size()); + for (ResidueViewList::const_iterator res=residues.begin()+1, + e=residues.end(); res!=e-1; ++res){ + if (!InSequence((*res).GetHandle(),(*(res+1)).GetHandle())) throw std::runtime_error("Residues are not in a continuous sequence"); + } + for (ResidueViewList::const_iterator res=residues.begin(), + e=residues.end(); res!=e; ++res) { + a=res->FindAtom("CA"); + CheckHandleValidity(a); + indices_ca.push_back(a.GetIndex()); + c=res->FindAtom("C"); + CheckHandleValidity(c); + indices_c.push_back(c.GetIndex()); + o=res->FindAtom("O"); + CheckHandleValidity(o); + indices_o.push_back(o.GetIndex()); + n=res->FindAtom("N"); + CheckHandleValidity(n); + indices_n.push_back(n.GetIndex()); + } + } + void GetMasses(const EntityView& sele, std::vector<Real>& masses){ // This function returns a vector containing the atom masses of the atoms in an EntityView // It is used together with GetIndices to accelerate the extraction of RMSD from a trajectory @@ -218,5 +264,110 @@ namespace ost { namespace mol { GetIndicesAndMasses(view_cm,indices_cm,masses_cm); return this->GetMinDistBetwCenterOfMassAndView(indices_cm,masses_cm,indices_atoms); } + + geom::Line3 CoordFrame::GetODRLine(std::vector<unsigned long>& indices_ca){ + //Returns the best fit line to atoms with indices in indices_ca + geom::Vec3List atoms_pos_list; + atoms_pos_list.reserve(indices_ca.size()); + for (std::vector<unsigned long>::const_iterator i1=indices_ca.begin(),e=indices_ca.end(); i1!=e; ++i1) { + atoms_pos_list.push_back((*this)[*i1]); + } + return atoms_pos_list.GetODRLine(); + } + + geom::Line3 CoordFrame::FitCylinder(std::vector<unsigned long>& indices_ca){ + //Returns a line which is the axis of a fitted cylinder to the atoms with indices given in indices_ca + geom::Vec3List atoms_pos_list; + atoms_pos_list.reserve(indices_ca.size()); + for (std::vector<unsigned long>::const_iterator i1=indices_ca.begin(),e=indices_ca.end(); i1!=e; ++i1) { + atoms_pos_list.push_back((*this)[*i1]); + } + return atoms_pos_list.FitCylinder(); + } + + Real CoordFrame::GetAlphaHelixContent(const mol::EntityView& segment){ + //Returns the percentage of residues in the EntityView (segment) that are in an alpha-helix + //Each residue is assigned as being in an alpha-helix or not, based on and backbone torsion angles + //and the hydrogen bonding (O-N) (this term is used only if the segment contains at least 8 residues + //The entity view should be a single segment with no gaps and no missing N,CA,C,O backbone atoms + //the first and last residues will not be asessed for helicity + CheckHandleValidity(segment); + std::vector<unsigned long> indices_c, indices_n, indices_ca, indices_o; + GetCaCONIndices(segment, indices_ca, indices_c, indices_o, indices_n); + return CoordFrame::GetAlphaHelixContent(indices_ca,indices_c,indices_o,indices_n); + } + + Real Eval2AngleDist(Real phi, Real phi0, Real psi, Real psi0, Real delta){ + //Returns a score between 0 and 1 measuring the distance between + //a pair of angles and a pair of reference angles + Real d1,d2,d; + d1=abs(phi-phi0); + d2=abs(psi-psi0); + if (d1>M_PI) d1=abs(d1-2.*M_PI); + if (d2>M_PI) d1=abs(d2-2.*M_PI); + d=(pow(d1,2.)+pow(d2,2.))/pow(delta,2.); + return 1./(1+d); + } + + Real CoordFrame::GetAlphaHelixContent(std::vector<unsigned long>& indices_ca, std::vector<unsigned long>& indices_c, + std::vector<unsigned long>& indices_o, std::vector<unsigned long>& indices_n){ + //See CoordFrame::GetAlphaHelixContent(const mol::EntityView) above. + unsigned long n_atoms=indices_ca.size(); + geom::Vec3 c_previous,n,ca,c,n_next; + Real phi,psi,phi_0=-1.2,psi_0=-0.785,delta=0.8,d_0=3.3; + unsigned long n_helical_res=0; + std::vector<Real> score,dist,score2,dist2; + score.reserve(n_atoms-2); + score2.reserve(n_atoms-2); + dist.reserve(n_atoms-2); + dist2.reserve(n_atoms-2); + if (n_atoms!=indices_n.size()||n_atoms!=indices_c.size()||n_atoms!=indices_o.size()){ + throw std::runtime_error("not same numbers of CA, C, O and N atoms in the selection"); + } + if (n_atoms<=5){ + throw std::runtime_error("At least five residues are needed to calulate an alpha helix similarity"); + } + c=(*this)[indices_c[0]]; + n_next=(*this)[indices_n[1]]; + for (unsigned long i=1; i!=n_atoms-1; ++i){ + c_previous=c; + n=n_next; + ca=(*this)[indices_ca[i]]; + c=(*this)[indices_c[i]]; + n_next=(*this)[indices_n[i+1]]; + phi=geom::DihedralAngle(c_previous,n,ca,c); + psi=geom::DihedralAngle(n,ca,c,n_next); + score.push_back(Eval2AngleDist(phi,phi_0,psi,psi_0,delta)); + } + score2[0]=pow(score[0]*score[1],3./2.); + score2[n_atoms-3]=pow(score[n_atoms-3]*score[n_atoms-4],3./2.); + for (unsigned long i=1; i!=n_atoms-3; ++i){ + score2[i]=score[i-1]*score[i]*score[i+1]; + } + if (n_atoms>=8){ + for (unsigned long i=1; i!=n_atoms-1; ++i){ + if (i<n_atoms-4){ + dist.push_back(geom::Distance((*this)[indices_o[i]],(*this)[indices_n[i+4]])); + if (i>=5) { + dist2.push_back(std::min(dist[i-1],dist[i-5])); + } + else dist2.push_back(dist[i-1]); + } + else dist2.push_back(geom::Distance((*this)[indices_n[i]],(*this)[indices_o[i-4]])); + } + for (unsigned long i=0; i!=n_atoms-2; ++i){ + if (dist2[i]<=d_0 || score2[i]>=0.3)n_helical_res+=1; + } + } + else { + for (unsigned long i=0; i!=n_atoms-2; ++i){ + if (score2[i]>=0.3)n_helical_res+=1; + } + } + return Real(n_helical_res)/Real(n_atoms-2); + } + + + }}//ns diff --git a/modules/mol/base/src/coord_frame.hh b/modules/mol/base/src/coord_frame.hh index 8b34cc52acb31086b8ee02d074fe0aac526e22f8..db9645dc688ca66db3111d56f158bd9ae0d77766 100644 --- a/modules/mol/base/src/coord_frame.hh +++ b/modules/mol/base/src/coord_frame.hh @@ -60,13 +60,21 @@ public: Real GetMinDistBetwCenterOfMassAndView(std::vector<unsigned long>& indices_cm, std::vector<Real>& masses_cm, std::vector<unsigned long>& indices_atoms); Real GetMinDistBetwCenterOfMassAndView(const mol::EntityView& view_cm, const mol::EntityView& view_atoms); + geom::Line3 GetODRLine(std::vector<unsigned long>& indices_ca); + geom::Line3 FitCylinder(std::vector<unsigned long>& indices_ca); + Real GetAlphaHelixContent(std::vector<unsigned long>& indices_ca, std::vector<unsigned long>& indices_c, + std::vector<unsigned long>& indices_o, std::vector<unsigned long>& indices_n); + Real GetAlphaHelixContent(const mol::EntityView& segment); }; void GetIndices(const EntityView& sele, std::vector<unsigned long>& indices); void GetMasses(const EntityView& sele, std::vector<Real>& masses); void GetIndicesAndMasses(const EntityView& sele, std::vector<unsigned long>& indices,std::vector<Real>& masses); void GetPositions(const EntityView& sele, std::vector<geom::Vec3>& ref_pos); - + void GetCaIndices(const EntityView& segment, std::vector<unsigned long>& indices_ca); + void GetCaCONIndices(const EntityView& segment, std::vector<unsigned long>& indices_ca, std::vector<unsigned long>& indices_c, + std::vector<unsigned long>& indices_o, std::vector<unsigned long>& indices_n); + typedef boost::shared_ptr<CoordFrame> CoordFramePtr; typedef std::vector<CoordFramePtr> CoordFrameList; diff --git a/modules/mol/base/src/impl/residue_impl.cc b/modules/mol/base/src/impl/residue_impl.cc index d8ce7f6d3f97b6c0bfe9e452d0c2760d54bbd01c..28f0cc6f9047616848e8d0a334da946a6fdfea9f 100644 --- a/modules/mol/base/src/impl/residue_impl.cc +++ b/modules/mol/base/src/impl/residue_impl.cc @@ -43,7 +43,8 @@ ResidueImpl::ResidueImpl(const EntityImplPtr& ent, atom_list_(), sec_structure_(SecStructure::COIL), olc_('?'), - protein_(false), ligand_(false) + protein_(false), ligand_(false), + central_atom_() { } @@ -163,6 +164,7 @@ EntityImplPtr ResidueImpl::GetEntity() const AtomImplPtr ResidueImpl::GetCentralAtom() const { + if(central_atom_) return central_atom_; if (chem_class_.IsNucleotideLinking()) { for (AtomImplList::const_iterator it=atom_list_.begin(); it!=atom_list_.end();++it) { @@ -178,6 +180,12 @@ AtomImplPtr ResidueImpl::GetCentralAtom() const return AtomImplPtr(); } +void ResidueImpl::SetCentralAtom(const AtomImplPtr& a) +{ + central_atom_=a; +} + + char ResidueImpl::GetOneLetterCode() const { return olc_; diff --git a/modules/mol/base/src/impl/residue_impl.hh b/modules/mol/base/src/impl/residue_impl.hh index 560571f87d1ac8f9c492704a54d5b3dcfe6bee15..8b01d32d2f3d8873f8098805dbe62028334dc2ec 100644 --- a/modules/mol/base/src/impl/residue_impl.hh +++ b/modules/mol/base/src/impl/residue_impl.hh @@ -72,6 +72,13 @@ public: ChainImplPtr GetChain() const; AtomImplPtr GetCentralAtom() const; + /*! + explicitely set central atom + + if this is set, it will override the heuristic encoded + in GetCentralAtom; pass an invalid ptr to deactivate again + */ + void SetCentralAtom(const AtomImplPtr& a); geom::Vec3 GetCentralNormal() const; @@ -209,6 +216,7 @@ private: void AddAltAtom(const String& group, const AtomImplPtr& atom, const geom::Vec3& position); void RemoveAltPositionsForAtom(const AtomImplPtr& atom); + String curr_group_; AtomEntryGroups alt_groups_; EntityImplW ent_; @@ -221,8 +229,13 @@ private: ChemClass chem_class_; char olc_; // whether the residue is part of the protein. + // TODO: this should be fixed to be a enum'ed type aka + // RESIDUE_TYPE type_; + // where enum is one of protein, ligand, dna, lipid, etc bool protein_; bool ligand_; + AtomImplPtr central_atom_; + }; }}} // ns diff --git a/modules/mol/base/src/residue_base.cc b/modules/mol/base/src/residue_base.cc index a1d321dee00bf9a43b1a92634d88897099831ba7..7d15ad5f6fff00b62a223b8f41417f25d0703d8d 100644 --- a/modules/mol/base/src/residue_base.cc +++ b/modules/mol/base/src/residue_base.cc @@ -44,6 +44,23 @@ const GenericPropContainerImpl* ResidueBase::GpImpl() const return Impl().get(); } +AtomHandle ResidueBase::GetCentralAtom() const +{ + this->CheckValidity(); + return AtomHandle(Impl()->GetCentralAtom()); +} + +void ResidueBase::SetCentralAtom(const AtomHandle& a) +{ + this->CheckValidity(); + impl_->SetCentralAtom(a.Impl()); +} + +geom::Vec3 ResidueBase::GetCentralNormal() const +{ + this->CheckValidity(); + return impl_->GetCentralNormal(); +} const ResNum& ResidueBase::GetNumber() const { this->CheckValidity(); diff --git a/modules/mol/base/src/residue_base.hh b/modules/mol/base/src/residue_base.hh index ea5a5f01081787d3fe6e177894f288cfb8699f99..c994b9a3098b48479300c811d55583cc213ad16c 100644 --- a/modules/mol/base/src/residue_base.hh +++ b/modules/mol/base/src/residue_base.hh @@ -19,6 +19,8 @@ #ifndef OST_RESIDUE_BASE_HH #define OST_RESIDUE_BASE_HH +#include <ost/geom/geom.hh> + #include <ost/mol/module_config.hh> #include <ost/mol/residue_prop.hh> #include <ost/mol/impl/residue_impl_fw.hh> @@ -90,6 +92,20 @@ public: /// residue name and residue number String GetQualifiedName() const; + /// \brief returns main atom, ie CA for amino acids + AtomHandle GetCentralAtom() const; + + /*! + \brief set explicit central atom + + overrides the heuristic of GetCentralAtom to explicitely + use the given one as the central atom; passing in an + invalid handle reverts back to the heurstic determination + */ + void SetCentralAtom(const AtomHandle& a); + + /// \return return specific normal of residue, usually CA-CB dir for AA + geom::Vec3 GetCentralNormal() const; /// \brief whether the residue can form peptide bonds bool IsPeptideLinking() const; diff --git a/modules/mol/base/src/residue_handle.cc b/modules/mol/base/src/residue_handle.cc index 809dbb8c64b9a1d604753e2feaa79174a8f71c96..d2ef00da17cd22fed12270d1dc783e9d8cc5cbe4 100644 --- a/modules/mol/base/src/residue_handle.cc +++ b/modules/mol/base/src/residue_handle.cc @@ -130,18 +130,6 @@ bool ResidueHandle::operator!=(const ResidueHandle& ref) const return Impl()!=ref.Impl(); } -AtomHandle ResidueHandle::GetCentralAtom() const -{ - this->CheckValidity(); - return AtomHandle(Impl()->GetCentralAtom()); -} - -geom::Vec3 ResidueHandle::GetCentralNormal() const -{ - this->CheckValidity(); - return Impl()->GetCentralNormal(); -} - int ResidueHandle::GetIndex() const { this->CheckValidity(); diff --git a/modules/mol/base/src/residue_handle.hh b/modules/mol/base/src/residue_handle.hh index 54b9092a001e34a45aacdfffddf0ac33cc389665..5048a0804c960f535a7213b2a93c2e7324dac241 100644 --- a/modules/mol/base/src/residue_handle.hh +++ b/modules/mol/base/src/residue_handle.hh @@ -61,21 +61,15 @@ public: : ResidueBase(impl) {} EntityHandle GetEntity() const; - /// \brief returns main atom, ie CA for amino acids - AtomHandle GetCentralAtom() const; - - /// \return return specific normal of residue, usually CA-CB dir for AA - geom::Vec3 GetCentralNormal() const; - - /// \brief Get entity's mass + /// \brief Get residue's mass double GetMass() const; - /// \brief Get entity's center of mass (mass weighted) + /// \brief Get residue's center of mass (mass weighted) geom::Vec3 GetCenterOfMass() const; - /// \brief Get entity's center of atoms (not mass weighted) + /// \brief Get residue's center of atoms (not mass weighted) /// - /// Returns the center of all the atoms in an entity. This is + /// Returns the center of all the atoms in this residue. This is /// similar to GetCenterOfMass(), but the atoms are not mass weighted geom::Vec3 GetCenterOfAtoms() const; diff --git a/modules/mol/base/src/residue_view.hh b/modules/mol/base/src/residue_view.hh index 8c95c81c1fe372151a69a17f213ff6c398827072..8efe0c97f8739a5e8c64a1d1f84f3db357e94835 100644 --- a/modules/mol/base/src/residue_view.hh +++ b/modules/mol/base/src/residue_view.hh @@ -155,22 +155,20 @@ public: /// \brief get parent chain view. ChainView GetChain() const; - - /// \brief Get entity's mass + /// \brief Get residue's mass double GetMass() const; - /// \brief Get entity's center of mass (mass weighted) + /// \brief Get residue's center of mass (mass weighted) geom::Vec3 GetCenterOfMass() const; - /// \brief Get entity's center of atoms (not mass weighted) + /// \brief Get residue's center of atoms (not mass weighted) /// - /// Returns the center of all the atoms in an entity. This is + /// Returns the center of all the atoms in this residue. This is /// similar to GetCenterOfMass(), but the atoms are not mass weighted geom::Vec3 GetCenterOfAtoms() const; - /// \brief Get entity's axis-aligned bounding box + /// \brief Get residue's axis-aligned bounding box geom::AlignedCuboid GetBounds() const; - /// \brief return view based on a query object /// \sa Query diff --git a/modules/mol/base/tests/test_numpy.py b/modules/mol/base/tests/test_numpy.py index 14496c0c0ef2d3cb3632ebbb620890d4a9e126a0..217ed89dd7adb6380b6fea22719e49f310b2c2cb 100644 --- a/modules/mol/base/tests/test_numpy.py +++ b/modules/mol/base/tests/test_numpy.py @@ -1,17 +1,25 @@ import unittest -from ost import * +if __name__== '__main__': + import sys + sys.path.insert(0,"../../../../stage/lib64/openstructure/") + sys.path.insert(0,"../../../../stage/lib/openstructure/") + +import ost -has_numpy=True -try: - import numpy -except ImportError: +if ost.WITH_NUMPY: + has_numpy=True + try: + import numpy + except ImportError, e: + has_numpy=False +else: has_numpy=False def v2v(v): - return geom.Vec3(float(v[0]),float(v[1]),float(v[2])) + return ost.geom.Vec3(float(v[0]),float(v[1]),float(v[2])) def dd(v1,v2): - return geom.Distance(v1,v2)<1e-8 + return ost.geom.Distance(v1,v2)<1e-8 class TestNumpy(unittest.TestCase): def setUp(self): @@ -20,46 +28,46 @@ class TestNumpy(unittest.TestCase): def test_(self): if not has_numpy: return - entity=mol.CreateEntity() + entity=ost.mol.CreateEntity() ed=entity.EditXCS() ch=ed.InsertChain("X") re=ed.AppendResidue(ch,"ALA") - a0=ed.InsertAtom(re,"A",geom.Vec3(0,0,0)) + a0=ed.InsertAtom(re,"A",ost.geom.Vec3(0,0,0)) self.assertEqual(a0.GetIndex(),0) - a1=ed.InsertAtom(re,"B",geom.Vec3(1,0,0)) + a1=ed.InsertAtom(re,"B",ost.geom.Vec3(1,0,0)) self.assertEqual(a1.GetIndex(),1) - a2=ed.InsertAtom(re,"C",geom.Vec3(2,0,0)) + a2=ed.InsertAtom(re,"C",ost.geom.Vec3(2,0,0)) self.assertEqual(a2.GetIndex(),2) - a3=ed.InsertAtom(re,"D",geom.Vec3(3,0,0)) + a3=ed.InsertAtom(re,"D",ost.geom.Vec3(3,0,0)) self.assertEqual(a3.GetIndex(),3) - self.assertTrue(dd(a0.pos,geom.Vec3(0,0,0))) - self.assertTrue(dd(a1.pos,geom.Vec3(1,0,0))) - self.assertTrue(dd(a2.pos,geom.Vec3(2,0,0))) - self.assertTrue(dd(a3.pos,geom.Vec3(3,0,0))) + self.assertTrue(dd(a0.pos,ost.geom.Vec3(0,0,0))) + self.assertTrue(dd(a1.pos,ost.geom.Vec3(1,0,0))) + self.assertTrue(dd(a2.pos,ost.geom.Vec3(2,0,0))) + self.assertTrue(dd(a3.pos,ost.geom.Vec3(3,0,0))) ed.SetAtomTransformedPos(entity.GetAtomList(), numpy.array([[0,1,0],[0,2,0],[0,3,0],[0,4,0]], dtype=numpy.float32)) - self.assertTrue(dd(a0.pos,geom.Vec3(0,1,0))) - self.assertTrue(dd(a1.pos,geom.Vec3(0,2,0))) - self.assertTrue(dd(a2.pos,geom.Vec3(0,3,0))) - self.assertTrue(dd(a3.pos,geom.Vec3(0,4,0))) + self.assertTrue(dd(a0.pos,ost.geom.Vec3(0,1,0))) + self.assertTrue(dd(a1.pos,ost.geom.Vec3(0,2,0))) + self.assertTrue(dd(a2.pos,ost.geom.Vec3(0,3,0))) + self.assertTrue(dd(a3.pos,ost.geom.Vec3(0,4,0))) na=entity.positions - self.assertTrue(dd(v2v(na[0]),geom.Vec3(0,1,0))) - self.assertTrue(dd(v2v(na[1]),geom.Vec3(0,2,0))) - self.assertTrue(dd(v2v(na[2]),geom.Vec3(0,3,0))) - self.assertTrue(dd(v2v(na[3]),geom.Vec3(0,4,0))) + self.assertTrue(dd(v2v(na[0]),ost.geom.Vec3(0,1,0))) + self.assertTrue(dd(v2v(na[1]),ost.geom.Vec3(0,2,0))) + self.assertTrue(dd(v2v(na[2]),ost.geom.Vec3(0,3,0))) + self.assertTrue(dd(v2v(na[3]),ost.geom.Vec3(0,4,0))) ed.SetAtomTransformedPos([3,99,2], numpy.array([[0,0,-3],[-1,-1,-1],[0,0,-2]], dtype=numpy.float32)) - self.assertTrue(dd(a0.pos,geom.Vec3(0,1,0))) - self.assertTrue(dd(a1.pos,geom.Vec3(0,2,0))) - self.assertTrue(dd(a2.pos,geom.Vec3(0,0,-2))) - self.assertTrue(dd(a3.pos,geom.Vec3(0,0,-3))) + self.assertTrue(dd(a0.pos,ost.geom.Vec3(0,1,0))) + self.assertTrue(dd(a1.pos,ost.geom.Vec3(0,2,0))) + self.assertTrue(dd(a2.pos,ost.geom.Vec3(0,0,-2))) + self.assertTrue(dd(a3.pos,ost.geom.Vec3(0,0,-3))) if __name__== '__main__': unittest.main() diff --git a/scripts/CMakeLists.txt b/scripts/CMakeLists.txt index 6a936d2822952a53e1237dc26403718a23c303a8..f71f153277224ae97a8e7155b15e653ec504123d 100644 --- a/scripts/CMakeLists.txt +++ b/scripts/CMakeLists.txt @@ -1,4 +1,4 @@ -set(SUBST_DICT BUILD_TYPE=${CMAKE_BUILD_TYPE} PYTHON_BINARY=${PYTHON_BINARY} LIBDIR=${LIB_DIR}) +set(SUBST_DICT BUILD_TYPE=${CMAKE_BUILD_TYPE} PYTHON_BINARY=${PYTHON_BINARY} LIBDIR=${LIB_DIR} LIBEXEC_PATH=${LIBEXEC_PATH}) message("${BUILD_TYPE}") add_custom_target(ost_scripts ALL) @@ -19,7 +19,7 @@ if(WIN32) script(NAME gipltng.bat INPUT gipltng.bat.in SUBSTITUTE ${SUBST_DICT}) else() script(NAME ost_config INPUT ost_config.in SUBSTITUTE ${SUBST_DICT} - TARGET ost_scripts OUTPUT_DIR libexec/openstructure) + TARGET ost_scripts OUTPUT_DIR ${LIBEXEC_PATH}) script(NAME ost INPUT ost.in SUBSTITUTE ${SUBST_DICT} TARGET ost_scripts) if (ENABLE_GUI) diff --git a/scripts/dng.in b/scripts/dng.in index e78b6511fa811758e7d42babe69437d2f0e19fd2..41e31bd636c0193f83bb87671df25e0feed39733 100755 --- a/scripts/dng.in +++ b/scripts/dng.in @@ -26,6 +26,6 @@ else SCRIPT_NAME="$0" fi BIN_DIR=`dirname "$SCRIPT_NAME"` -source $BIN_DIR/../libexec/openstructure/ost_config +source $BIN_DIR/../@LIBEXEC_PATH@/ost_config -$DNG_BINDIR/gosty $DNG_INITDIR/init.py ost $opts +$BIN_DIR/../@LIBEXEC_PATH@/gosty $DNG_INITDIR/init.py dng $opts diff --git a/scripts/ost.in b/scripts/ost.in index 3cf716f00d7e026ec9bbd92e7aa29bd6fa34d578..2891d37c28597c2fbdee3dbb05b1bd7bf20aca5c 100755 --- a/scripts/ost.in +++ b/scripts/ost.in @@ -29,7 +29,7 @@ else fi BIN_DIR=`dirname "$SCRIPT_NAME"` -source $BIN_DIR/../libexec/openstructure/ost_config +source $BIN_DIR/../@LIBEXEC_PATH@/ost_config $pyexec $interactive "$DNG_ROOT/@LIBDIR@/openstructure/init_cl.py" $opts RC=$? diff --git a/scripts/ost_config.in b/scripts/ost_config.in index bfd79f436a092a15e1909c1e616fface963b1b5a..b7b8b7c3ef001947e5310375c787e43e5d936aa6 100644 --- a/scripts/ost_config.in +++ b/scripts/ost_config.in @@ -26,10 +26,10 @@ export DNG_BINDIR="$DNG_ROOT/bin" export DNG_LIBDIR="$DNG_ROOT/@LIBDIR@" export DNG_INITDIR="$DNG_LIBDIR/openstructure" -#export PATH="$DNG_BINDIR:$PATH" -#export DYLD_FRAMEWORK_PATH="$BIN_LIBDIR:${DYLD_FRAMEWORK_PATH}" -#export DYLD_LIBRARY_PATH="$BIN_LIBDIR:${DYLD_LIBRARY_PATH}" -#export LD_LIBRARY_PATH="$DNG_LIBDIR:$LD_LIBRARY_PATH" +export PATH="$DNG_BINDIR:$PATH" +export DYLD_FRAMEWORK_PATH="$BIN_LIBDIR:${DYLD_FRAMEWORK_PATH}" +export DYLD_LIBRARY_PATH="$BIN_LIBDIR:${DYLD_LIBRARY_PATH}" +export LD_LIBRARY_PATH="$DNG_LIBDIR:$LD_LIBRARY_PATH" # set QT_PLUGIN_PATH PYTHONHOME and PYTHONPATH for bundle (commented except in linux bundles) # set QT_PLUGIN_PATH and pythonpath for bundle (commented except in linux bundles) #export QT_PLUGIN_PATH="$BIN_DIR/plugins"