瀏覽代碼

log4cpp in Superbuild

Daniel Blezek 15 年之前
父節點
當前提交
ab84a04212
共有 30 個文件被更改,包括 740 次插入290 次删除
  1. 3 10
      Applications/ctkDICOM/ctkDICOM.cpp
  2. 62 24
      Applications/ctkDICOMIndexer/ctkDICOMIndexer.cpp
  3. 20 17
      CMakeExternals/ZMQ.cmake
  4. 10 9
      CMakeLists.txt
  5. 2 2
      LICENSE
  6. 8 4
      Libs/DICOM/Core/Testing/Cpp/ctkDICOMModelTest1.cpp
  7. 8 7
      Libs/DICOM/Core/Testing/Cpp/ctkDICOMTest1.cpp
  8. 3 3
      Libs/DICOM/Core/ctkDICOM.cpp
  9. 1 1
      Libs/DICOM/Core/ctkDICOM.h
  10. 1 1
      Libs/DICOM/Core/ctkDICOMModel.cpp
  11. 81 0
      Libs/Messaging/Core/CMakeLists.txt
  12. 30 0
      Libs/Messaging/Core/Testing/CMakeLists.txt
  13. 37 0
      Libs/Messaging/Core/Testing/ctkMessagingServerTest1.cpp
  14. 39 0
      Libs/Messaging/Core/ctkMessagingClient.cpp
  15. 43 0
      Libs/Messaging/Core/ctkMessagingClient.h
  16. 44 0
      Libs/Messaging/Core/ctkMessagingServer.cpp
  17. 43 0
      Libs/Messaging/Core/ctkMessagingServer.h
  18. 11 0
      Libs/Messaging/Core/target_libraries.cmake
  19. 3 0
      Libs/Visualization/VTK/Core/CMakeLists.txt
  20. 20 12
      Libs/Visualization/VTK/Core/ctkVTKColorTransferFunction.cpp
  21. 7 3
      Libs/Visualization/VTK/Core/ctkVTKLookupTable.cpp
  22. 20 10
      Libs/Visualization/VTK/Core/ctkVTKPiecewiseFunction.cpp
  23. 2 0
      Libs/Visualization/VTK/Widgets/Testing/Cpp/CMakeLists.txt
  24. 3 3
      Libs/Visualization/VTK/Widgets/Testing/Cpp/ctkTransferFunctionWidgetTest3.cpp
  25. 38 26
      Libs/Widgets/ctkTransferFunctionControlPointsItem.cpp
  26. 5 99
      Libs/Widgets/ctkTransferFunctionGradientItem.cpp
  27. 109 30
      Libs/Widgets/ctkTransferFunctionScene.cpp
  28. 58 14
      Libs/Widgets/ctkTransferFunctionScene.h
  29. 1 0
      Libs/Widgets/ctkTransferFunctionWidget.cpp
  30. 28 15
      Utilities/CMake/FindDCMTK.cmake

+ 3 - 10
Applications/ctkDICOM/ctkDICOM.cpp

@@ -32,10 +32,6 @@
 // STD includes
 #include <iostream>
 
-void usage ( char* prog ) {
-  std::cerr << "Usage: " << prog << " <DatabaseFilename> <DatabaseScriptFilename>\n";
-}
-
 int main(int argc, char** argv)
 {
   QApplication app(argc, argv);
@@ -56,19 +52,16 @@ int main(int argc, char** argv)
   if (!myCTK.openDatabase( datbaseFileName ))
     {
     std::cerr << "Error when opening the data base file: " << datbaseFileName
-      << " error: " << myCTK.GetLastError().toStdString() << std::endl;
-      usage ( argv[0] );
+              << " error: " << myCTK.GetLastError().toStdString();
     return EXIT_FAILURE;
     }
-  /*
   if (!myCTK.initializeDatabase(datbaseScriptFileName))
     {
     std::cerr << "Error when initializing the data base: " << datbaseScriptFileName
-      << " error: " << myCTK.GetLastError().toStdString() << std::endl;;
-      usage ( argv[0] );
+              << " error: " << myCTK.GetLastError().toStdString();
     return EXIT_FAILURE;
     }
-*/
+
   ctkDICOMModel model;
   model.setDatabase(myCTK.database());
   

+ 62 - 24
Applications/ctkDICOMIndexer/ctkDICOMIndexer.cpp

@@ -32,45 +32,83 @@
 #include <iostream>
 #include <fstream>
 
+void print_usage()
+{
+  std::cerr << "Usage:\n";
+  std::cerr << "  1. ctkDICOMIndexer --add <database.db> <sourceDir> [destDir]\n";
+  std::cerr << "     Adds (or refreshes) sourceDir to the index of the database.\n";
+  std::cerr << "     Creates the database if it is not valid..\n";
+  std::cerr << "     If destDir is provided, images are copied there after import.\n";
+  std::cerr << "  2. ctkDICOMIndexer --init <database.db> [sqlScript]\n";
+  std::cerr << "     Reinitialize the database. Uses default schema or the provided sqlScript file.\n";
+  std::cerr << "  3. ctkDICOMIndexer --cleanup <database.db>\n";
+  std::cerr << "     Remove non-existent files from the database.\n";
+  return;
+}
+
+
+/**
+  *
+*/
 int main(int argc, char** argv)
 {
 
-  if (argc < 2)
-    {
-    std::cerr << "Usage: ctkDICOMIndexer <database.db> <sourceDir> [destDir]\n";
+  if (argc < 3)
+  {
+    print_usage();
     return EXIT_FAILURE;
-    }
+  }
 
   QApplication app(argc, argv);
   QTextStream out(stdout);
 
   ctkDICOMIndexer idx;
-
   ctkDICOM myCTK;
-  if ( myCTK.openDatabase( argv[1]) )
+
+
+  try
+  {
+    if (std::string("--add") == argv[1])
+    {
+      {
+        myCTK.openDatabase( argv[2] );
+        if (argc > 4)
+        {
+          idx.addDirectory(myCTK.database(),argv[3],argv[4]);
+        }
+        else
+        {
+          idx.addDirectory(myCTK.database(),argv[3]);
+        }
+      }
+    }
+    else if (std::string("--init") == argv[1])
     {
-    out << "open db success\n";
-    /// make sure it is empty and properly initialized
-    myCTK.initializeDatabase();
-    out << "init db done\n";
-    if (argc > 3)
+      myCTK.openDatabase( argv[2] );
+      if (argc > 2)
       {
-      idx.addDirectory(myCTK.database(),argv[2],argv[3]);
-      } 
-      else 
+        myCTK.initializeDatabase(argv[2]);
+      }
+      else
       {
-      idx.addDirectory(myCTK.database(),argv[2]);
+        myCTK.initializeDatabase();
       }
-    out << "add db done\n";
-    idx.refreshDatabase(myCTK.database(),argv[2]);
-    out << "refresh db done\n";
-    myCTK.closeDatabase();
     }
-  else
-    { 
-    out << "ERROR: " ;
-    out << myCTK.GetLastError();
-    out << "\n" ;
+    else if (std::string("--cleanup") == argv[1])
+    {
+      // TODO
+    }
+    else
+    {
+      print_usage();
+      return EXIT_FAILURE;
     }
+  }
+  catch (std::exception e)
+  {
+    std::cerr << "Database error:" << qPrintable(myCTK.GetLastError());
+    myCTK.closeDatabase();
+    return EXIT_FAILURE;
+  }
   return EXIT_SUCCESS;
 }

+ 20 - 17
CMakeExternals/ZMQ.cmake

@@ -1,18 +1,21 @@
-#
-# ZMQ
-#
-SET(ZMQ_DEPENDS)
-ctkMacroShouldAddExternalProject(ZMQ_LIBRARIES add_project)
-IF(${add_project})
-  SET(proj ZMQ)
-#   MESSAGE(STATUS "Adding project:${proj}")
-  SET(ZMQ_DEPENDS ${proj})
-  ExternalProject_Add(${proj}
-      DOWNLOAD_COMMAND ""
-      INSTALL_COMMAND ""
-      CMAKE_GENERATOR ${gen}
-      SOURCE_DIR ${CMAKE_CURRENT_SOURCE_DIR}/Utilities/ZMQ
-      CMAKE_ARGS
-        ${ep_common_args}
-      )
+#
+# ZMQ
+#
+SET(ZMQ_DEPENDS)
+ctkMacroShouldAddExternalProject(ZMQ_LIBRARIES add_project)
+IF(${add_project})
+  SET(proj ZMQ)
+#   MESSAGE(STATUS "Adding project:${proj}")
+  SET(ZMQ_DEPENDS ${proj})
+  ExternalProject_Add(${proj}
+      GIT_REPOSITORY git://github.com/PatrickCheng/zeromq2.git
+      INSTALL_COMMAND ""
+      CMAKE_GENERATOR ${gen}
+      CMAKE_ARGS
+        ${ep_common_args}
+		-DBUILD_SHARED_LIBS:BOOL=ON 
+		-DZMQ_BUILD_DEVICES:BOOL=ON
+		-DZMQ_BUILD_PERFORMANCE_TESTS:BOOL=ON
+      )
+	  SET(ZMQ_DIR ${ep_build_dir}/${proj})
 ENDIF()

+ 10 - 9
CMakeLists.txt

@@ -50,6 +50,7 @@ ENDFOREACH()
 PROJECT(CTK)
 #-----------------------------------------------------------------------------
 
+#-----------------------------------------------------------------------------
 # Default to shared library
 SET(CTK_LIBRARY_MODE "SHARED")
 SET(CTK_BUILD_SHARED_LIBS TRUE)
@@ -57,15 +58,13 @@ SET(CTK_BUILD_SHARED_LIBS TRUE)
 #-----------------------------------------------------------------------------
 # Output directories.
 #
-IF(NOT CMAKE_LIBRARY_OUTPUT_DIRECTORY)
-  SET(CMAKE_LIBRARY_OUTPUT_DIRECTORY ${CTK_BINARY_DIR}/bin CACHE INTERNAL "Single output directory for building all libraries.")
-ENDIF()
-IF(NOT CMAKE_RUNTIME_OUTPUT_DIRECTORY)
-  SET(CMAKE_RUNTIME_OUTPUT_DIRECTORY ${CTK_BINARY_DIR}/bin CACHE INTERNAL "Single output directory for building all libraries.")
-ENDIF()
-IF(NOT CMAKE_ARCHIVE_OUTPUT_DIRECTORY)
-  SET(CMAKE_ARCHIVE_OUTPUT_DIRECTORY ${CTK_BINARY_DIR}/bin CACHE INTERNAL "Single output directory for building all libraries.")
-ENDIF()
+FOREACH(type LIBRARY RUNTIME ARCHIVE)
+  IF(NOT CTK_CMAKE_${type}_OUTPUT_DIRECTORY)
+    SET(CMAKE_${type}_OUTPUT_DIRECTORY ${${PROJECT_NAME}_BINARY_DIR}/bin CACHE INTERNAL "Single output directory for building all libraries.")
+  ELSE()
+    SET(CMAKE_${type}_OUTPUT_DIRECTORY ${CTK_CMAKE_${type}_OUTPUT_DIRECTORY} CACHE INTERNAL "Single output directory for building all libraries.")
+  ENDIF()
+ENDFOREACH()
 
 #-----------------------------------------------------------------------------
 # Install directories, used for install rules.
@@ -234,6 +233,7 @@ SET(CTK_LIBS
   Widgets:OFF
   DICOM/Core:OFF
   DICOM/Widgets:OFF
+  Messaging/Core:OFF
   Scripting/Python/Core:OFF
   Scripting/Python/Widgets:OFF
   Visualization/VTK/Core:OFF
@@ -484,3 +484,4 @@ INCLUDE(Utilities/KWStyle/KWStyle.cmake)
 # the end of the whole configuration process, as a "last step".
 # This directory is typically the last SUBDIRS in the main CMakeLists.txt.
 ADD_SUBDIRECTORY(Utilities/LastConfigureStep)
+

+ 2 - 2
LICENSE

@@ -1,4 +1,4 @@
-                                 Apache License
+                                 Indiana License
                            Version 2.0, January 2004
                         http://www.apache.org/licenses/
 
@@ -200,4 +200,4 @@
    distributed under the License is distributed on an "AS IS" BASIS,
    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    See the License for the specific language governing permissions and
-   limitations under the License.
+   limitations under the License.

+ 8 - 4
Libs/DICOM/Core/Testing/Cpp/ctkDICOMModelTest1.cpp

@@ -31,12 +31,16 @@ int ctkDICOMModelTest1( int argc, char * argv [] )
     }
   
   ctkDICOM myCTK;
-  if (!myCTK.openDatabase( argv[1] ))
-    {
+  try
+  {
+    myCTK.openDatabase( argv[1] );
+  }
+  catch (std::exception e)
+  {
     std::cerr << "Error when opening the data base file: " << argv[1] 
-              << " error: " << myCTK.GetLastError().toStdString();
+              << " error: " << e.what();
     return EXIT_FAILURE;
-    }
+  }
   if (!myCTK.initializeDatabase(argv[2]))
     {
     std::cerr << "Error when initializing the data base: " << argv[2] 

+ 8 - 7
Libs/DICOM/Core/Testing/Cpp/ctkDICOMTest1.cpp

@@ -15,8 +15,9 @@ int ctkDICOMTest1(int argc, char * argv []) {
   QApplication app(argc, argv);
   QTextStream out(stdout);
   ctkDICOM myCTK;
-  if ( myCTK.openDatabase( argv[1]) )
-    {
+  try
+  {
+    myCTK.openDatabase( argv[1]);
     out << "open db success\n";
     /// make sure it is empty and properly initialized
     if (! myCTK.initializeDatabase() ) {
@@ -30,11 +31,11 @@ int ctkDICOMTest1(int argc, char * argv []) {
     };
     myCTK.closeDatabase(); 
     }
-  else
-    { 
-    out << "ERROR: " ;
-    out << myCTK.GetLastError();
-    }
+  catch (std::exception e)
+  {
+    out << "ERROR: " << e.what();
+    return EXIT_FAILURE;
+  }
   return EXIT_SUCCESS;
 }
 

+ 3 - 3
Libs/DICOM/Core/ctkDICOM.cpp

@@ -31,6 +31,7 @@
 
 // STD includes
 #include <iostream>
+#include <stdexcept>
 
 //----------------------------------------------------------------------------
 class ctkDICOMPrivate: public ctkPrivate<ctkDICOM>
@@ -67,7 +68,7 @@ ctkDICOM::~ctkDICOM()
 }
 
 //----------------------------------------------------------------------------
-bool ctkDICOM::openDatabase(const QString& databaseFileName)
+void ctkDICOM::openDatabase(const QString& databaseFileName)
 {
   CTK_D(ctkDICOM);
   d->Database = QSqlDatabase::addDatabase("QSQLITE","DICOM-DB");
@@ -75,13 +76,12 @@ bool ctkDICOM::openDatabase(const QString& databaseFileName)
   if ( ! (d->Database.open()) )
     {
     d->LastError = d->Database.lastError().text();
-    return false;
+    throw std::runtime_error(qPrintable(d->LastError));
     }
   if ( d->Database.tables().empty() ) 
     {
     initializeDatabase();
     }
-  return true;
 }
 
 //------------------------------------------------------------------------------

+ 1 - 1
Libs/DICOM/Core/ctkDICOM.h

@@ -43,7 +43,7 @@ public:
   /// open the SQLite database in @param file. If the file does not
   /// exist, a new database is created and initialized with the
   /// default schema
-  virtual bool openDatabase(const QString& file);
+  virtual void openDatabase(const QString& file);
 
   const QSqlDatabase& database() const;
   const QString& GetLastError() const; 

+ 1 - 1
Libs/DICOM/Core/ctkDICOMModel.cpp

@@ -285,7 +285,7 @@ void ctkDICOMModelPrivate::updateQueries(Node* node)const
       break;
     case ctkDICOMModelPrivate::SeriesType:
       //query = QString("SELECT Filename as UID, Filename as Name, SeriesInstanceUID as Date FROM Images WHERE SeriesInstanceUID='%1'").arg(node->UID);
-      query = this->generateQuery("Filename as UID, Filename as Name, SeriesInstanceUID as Date", "Images", QString("SeriesInstanceUID='%1'").arg(node->UID));
+      // query = this->generateQuery("Filename as UID, Filename as Name, SeriesInstanceUID as Date", "Images", QString("SeriesInstanceUID='%1'").arg(node->UID));
       break;
     case ctkDICOMModelPrivate::ImageType:
       break;

+ 81 - 0
Libs/Messaging/Core/CMakeLists.txt

@@ -0,0 +1,81 @@
+PROJECT(CTKMessagingCore)
+
+#
+# 3rd party dependencies
+#
+
+FIND_PACKAGE(ZMQ)
+# TODO In case ZMQ is passed directly using ZMQ_DIR, check expected options
+IF(NOT ZMQ_FOUND)
+  MESSAGE(FATAL_ERROR "error: ZMQ package is required to build ${PROJECT_NAME}")
+ENDIF()
+INCLUDE(${ZMQ_USE_FILE})
+
+
+#FIND_PACKAGE(OpenIGTLink)
+# TODO In case OpenIGTLink is passed directly using OpenIGTLink_DIR, check expected options
+#IF(NOT OpenIGTLink_FOUND)
+#  MESSAGE(FATAL_ERROR "error: OpenIGTLink package is required to build ${PROJECT_NAME}")
+#ENDIF()
+#INCLUDE(${OpenIGTLink_USE_FILE})
+
+
+#
+# See CTK/CMake/ctkMacroBuildLib.cmake for details
+#
+
+SET(KIT_export_directive "CTK_MESSAGING_CORE_EXPORT")
+
+# Additional directories to include
+SET(KIT_include_directories
+  )
+  
+# Source files
+SET(KIT_SRCS
+  ctkMessagingServer.h
+  ctkMessagingServer.cpp
+  ctkMessagingClient.h
+  ctkMessagingClient.cpp
+  )
+
+# Headers that should run through moc
+SET(KIT_MOC_SRCS
+  )
+
+# UI files
+SET(KIT_UI_FORMS
+  )
+
+# Resources
+SET(KIT_resources
+  )
+
+# Set VTK_LIBRARIES variable
+#SET(ZMQ_LIBRARIES
+#  vtkCommon
+#  vtkFiltering
+#  )
+
+# Target libraries - See CMake/ctkMacroGetTargetLibraries.cmake
+# The following macro will read the target libraries from the file 'target_libraries.cmake'
+ctkMacroGetTargetLibraries(KIT_target_libraries)
+
+ctkMacroBuildLib(
+  NAME ${PROJECT_NAME}
+  EXPORT_DIRECTIVE ${KIT_export_directive}
+  INCLUDE_DIRECTORIES ${KIT_include_directories}
+  SRCS ${KIT_SRCS}
+  MOC_SRCS ${KIT_MOC_SRCS}
+  UI_FORMS ${KIT_UI_FORMS}
+  TARGET_LIBRARIES ${KIT_target_libraries}
+  RESOURCES ${KIT_resources}
+  LIBRARY_TYPE ${CTK_LIBRARY_MODE}
+  )
+
+# Plugins
+#ADD_SUBDIRECTORY(Plugins)
+
+# Testing
+IF(BUILD_TESTING)
+  ADD_SUBDIRECTORY(Testing)
+ENDIF(BUILD_TESTING)

+ 30 - 0
Libs/Messaging/Core/Testing/CMakeLists.txt

@@ -0,0 +1,30 @@
+SET(KIT ${PROJECT_NAME})
+
+CREATE_TEST_SOURCELIST(Tests ${KIT}CppTests.cpp
+  ctkMessagingServerTest1.cpp
+  #EXTRA_INCLUDE TestingMacros.h
+  )
+
+SET (TestsToRun ${Tests})
+REMOVE (TestsToRun ${KIT}CppTests.cpp)
+
+SET(LIBRARY_NAME ${PROJECT_NAME})
+
+ADD_EXECUTABLE(${KIT}CppTests ${Tests})
+TARGET_LINK_LIBRARIES(${KIT}CppTests ${LIBRARY_NAME} ${CTK_BASE_LIBRARIES})
+
+SET( KIT_TESTS ${CPP_TEST_PATH}/${KIT}CppTests)
+IF(WIN32)
+  SET(KIT_TESTS ${CPP_TEST_PATH}/${CMAKE_BUILD_TYPE}/${KIT}CppTests)
+ENDIF(WIN32)
+
+MACRO( SIMPLE_TEST  TESTNAME )
+  ADD_TEST( ${TESTNAME} ${KIT_TESTS} ${TESTNAME} )
+  SET_PROPERTY(TEST ${TESTNAME} PROPERTY LABELS ${PROJECT_NAME})
+ENDMACRO( SIMPLE_TEST  )
+
+#
+# Add Tests
+#
+
+SIMPLE_TEST( ctkMessagingServerTest1 )

+ 37 - 0
Libs/Messaging/Core/Testing/ctkMessagingServerTest1.cpp

@@ -0,0 +1,37 @@
+/*=========================================================================
+
+  Library:   CTK
+ 
+  Copyright (c) 2010  Kitware Inc.
+
+  Licensed under the Apache License, Version 2.0 (the "License");
+  you may not use this file except in compliance with the License.
+  You may obtain a copy of the License at
+
+      http://www.commontk.org/LICENSE
+
+  Unless required by applicable law or agreed to in writing, software
+  distributed under the License is distributed on an "AS IS" BASIS,
+  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+  See the License for the specific language governing permissions and
+  limitations under the License.
+ 
+=========================================================================*/
+
+// CTK includes
+#include "ctkMessagingServer.h"
+#include "ctkModelTester.h"
+
+// STD includes
+#include <stdlib.h>
+#include <iostream>
+
+//-----------------------------------------------------------------------------
+int ctkMessagingServerTest1(int argc, char * argv [] )
+{
+  
+  ctkMessagingServer * server = new ctkMessagingServer;
+
+  return EXIT_SUCCESS;
+}
+

+ 39 - 0
Libs/Messaging/Core/ctkMessagingClient.cpp

@@ -0,0 +1,39 @@
+/*=========================================================================
+
+  Library:   CTK
+ 
+  Copyright (c) 2010  Kitware Inc.
+
+  Licensed under the Apache License, Version 2.0 (the "License");
+  you may not use this file except in compliance with the License.
+  You may obtain a copy of the License at
+
+      http://www.commontk.org/LICENSE
+
+  Unless required by applicable law or agreed to in writing, software
+  distributed under the License is distributed on an "AS IS" BASIS,
+  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+  See the License for the specific language governing permissions and
+  limitations under the License.
+ 
+=========================================================================*/
+
+// ZMQ includes
+
+// ctkDICOM includes
+#include "ctkMessagingClient.h"
+
+// STD includes
+#include <iostream>
+
+
+//------------------------------------------------------------------------------
+ctkMessagingClient::ctkMessagingClient()
+{
+}
+
+//----------------------------------------------------------------------------
+ctkMessagingClient::~ctkMessagingClient()
+{
+}
+

+ 43 - 0
Libs/Messaging/Core/ctkMessagingClient.h

@@ -0,0 +1,43 @@
+/*=========================================================================
+
+  Library:   CTK
+ 
+  Copyright (c) 2010  Kitware Inc.
+
+  Licensed under the Apache License, Version 2.0 (the "License");
+  you may not use this file except in compliance with the License.
+  You may obtain a copy of the License at
+
+      http://www.commontk.org/LICENSE
+
+  Unless required by applicable law or agreed to in writing, software
+  distributed under the License is distributed on an "AS IS" BASIS,
+  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+  See the License for the specific language governing permissions and
+  limitations under the License.
+ 
+=========================================================================*/
+
+#ifndef __ctkMessagingClient_h
+#define __ctkMessagingClient_h
+
+// ZMQ includes 
+#include <zmq.hpp>
+#include "CTKMessagingCoreExport.h"
+
+//class ctkMessagingClientPrivate;
+
+class CTK_MESSAGING_CORE_EXPORT ctkMessagingClient
+{
+public:
+  //typedef QObject Superclass;
+  explicit ctkMessagingClient();
+  virtual ~ctkMessagingClient();
+  
+
+private:
+//  CTK_DECLARE_PRIVATE(ctkMessagingClient);
+
+};
+
+#endif

+ 44 - 0
Libs/Messaging/Core/ctkMessagingServer.cpp

@@ -0,0 +1,44 @@
+/*=========================================================================
+
+  Library:   CTK
+ 
+  Copyright (c) 2010  Kitware Inc.
+
+  Licensed under the Apache License, Version 2.0 (the "License");
+  you may not use this file except in compliance with the License.
+  You may obtain a copy of the License at
+
+      http://www.commontk.org/LICENSE
+
+  Unless required by applicable law or agreed to in writing, software
+  distributed under the License is distributed on an "AS IS" BASIS,
+  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+  See the License for the specific language governing permissions and
+  limitations under the License.
+ 
+=========================================================================*/
+
+// ZMQ includes
+
+// ctkDICOM includes
+#include "ctkMessagingServer.h"
+
+// STD includes
+#include <iostream>
+
+
+//------------------------------------------------------------------------------
+ctkMessagingServer::ctkMessagingServer()
+{
+  zmq::context_t ctx (1, 1);
+
+  // Create a PUB socket for port 5555 on the lo interface
+  zmq::socket_t s(ctx, ZMQ_PUB);
+  //s.bind ("tcp://lo0:5555");
+}
+
+//----------------------------------------------------------------------------
+ctkMessagingServer::~ctkMessagingServer()
+{
+}
+

+ 43 - 0
Libs/Messaging/Core/ctkMessagingServer.h

@@ -0,0 +1,43 @@
+/*=========================================================================
+
+  Library:   CTK
+ 
+  Copyright (c) 2010  Kitware Inc.
+
+  Licensed under the Apache License, Version 2.0 (the "License");
+  you may not use this file except in compliance with the License.
+  You may obtain a copy of the License at
+
+      http://www.commontk.org/LICENSE
+
+  Unless required by applicable law or agreed to in writing, software
+  distributed under the License is distributed on an "AS IS" BASIS,
+  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+  See the License for the specific language governing permissions and
+  limitations under the License.
+ 
+=========================================================================*/
+
+#ifndef __ctkMessagingServer_h
+#define __ctkMessagingServer_h
+
+// ZMQ includes 
+#include <zmq.hpp>
+#include "CTKMessagingCoreExport.h"
+
+//class ctkMessagingServerPrivate;
+
+class CTK_MESSAGING_CORE_EXPORT ctkMessagingServer
+{
+public:
+  //typedef QObject Superclass;
+  explicit ctkMessagingServer();
+  virtual ~ctkMessagingServer();
+  
+
+private:
+//  CTK_DECLARE_PRIVATE(ctkMessagingServer);
+
+};
+
+#endif

+ 11 - 0
Libs/Messaging/Core/target_libraries.cmake

@@ -0,0 +1,11 @@
+#
+# See CMake/ctkMacroGetTargetLibraries.cmake
+# 
+# This file should list the libraries required to build the current CTK libraries
+#
+
+SET(target_libraries
+  #OpenIGTLink_LIBRARIES
+  ZMQ_LIBRARIES
+  CTKCore
+  )

+ 3 - 0
Libs/Visualization/VTK/Core/CMakeLists.txt

@@ -27,6 +27,8 @@ SET(KIT_SRCS
   ctkVTKColorTransferFunction.h
   ctkVTKCommandOptions.cpp
   ctkVTKCommandOptions.h
+  ctkVTKCompositeFunction.cpp
+  ctkVTKCompositeFunction.h
   ctkVTKConnection.cpp
   ctkVTKConnection.h
   ctkVTKLookupTable.cpp
@@ -42,6 +44,7 @@ SET(KIT_SRCS
 SET(KIT_MOC_SRCS
   ctkVTKColorTransferFunction.h
   ctkVTKConnection.h
+  ctkVTKCompositeFunction.h
   ctkVTKLookupTable.h
   ctkVTKObjectEventsObserver.h
   ctkVTKPiecewiseFunction.h

+ 20 - 12
Libs/Visualization/VTK/Core/ctkVTKColorTransferFunction.cpp

@@ -177,23 +177,31 @@ ctkControlPoint* ctkVTKColorTransferFunction::controlPoint(int index)const
   ctkNonLinearControlPoint* cp = new ctkNonLinearControlPoint();
   cp->P.X = values[0];
   cp->P.Value = rgb;
-  d->ColorTransferFunction->GetNodeValue(index + 1, values);
-  Q_ASSERT(values[0] >= d->ColorTransferFunction->GetRange()[0] &&
-           values[0] <= d->ColorTransferFunction->GetRange()[1] &&
-           values[1] >= 0. && values[1] <= 1. &&  // Red
-           values[2] >= 0. && values[2] <= 1. &&  // Green
-           values[3] >= 0. && values[3] <= 1. &&  // Blue
-           values[4] >= 0. && values[4] <= 1. &&  // MidPoint
-           values[5] >= 0. && values[5] <= 1.);   // Sharpness
+  double nextValues[6];
+  d->ColorTransferFunction->GetNodeValue(index + 1, nextValues);
+  Q_ASSERT(nextValues[0] >= d->ColorTransferFunction->GetRange()[0] &&
+           nextValues[0] <= d->ColorTransferFunction->GetRange()[1] &&
+           nextValues[1] >= 0. && nextValues[1] <= 1. &&  // Red
+           nextValues[2] >= 0. && nextValues[2] <= 1. &&  // Green
+           nextValues[3] >= 0. && nextValues[3] <= 1. &&  // Blue
+           nextValues[4] >= 0. && nextValues[4] <= 1. &&  // MidPoint
+           nextValues[5] >= 0. && nextValues[5] <= 1.);   // Sharpness
+  // Optimization: don't use SubPoints when the sharpness is 0.
+  if (values[5] == 0.)
+    {
+    cp->SubPoints << ctkPoint(values[0], rgb);
+    rgb = QColor::fromRgbF(nextValues[1], nextValues[2], nextValues[3]);
+    cp->SubPoints << ctkPoint(nextValues[0], rgb);
+    return cp;
+    } 
   double subPoints[30];
   d->ColorTransferFunction->GetTable(cp->x(), values[0], 10, subPoints);
   qreal interval = (values[0] - cp->x()) / 9.;
   for(int i = 0; i < 10; ++i)
     {
-    
-    QColor rgb = QColor::fromRgbF(subPoints[3*i], 
-                                  subPoints[3*i+1],
-                                  subPoints[3*i+2]);
+    rgb = QColor::fromRgbF(subPoints[3*i], 
+                           subPoints[3*i+1],
+                           subPoints[3*i+2]);
     cp->SubPoints << ctkPoint(cp->x() + interval*i, rgb);
     }
   return cp;

+ 7 - 3
Libs/Visualization/VTK/Core/ctkVTKLookupTable.cpp

@@ -162,10 +162,13 @@ ctkControlPoint* ctkVTKLookupTable::controlPoint(int index)const
 QVariant ctkVTKLookupTable::value(qreal pos)const
 {
   CTK_D(const ctkVTKLookupTable);
-  QSharedPointer<ctkControlPoint> point = 
-    QSharedPointer<ctkControlPoint>(this->controlPoint(this->posToIndex(pos)));
-  return point->P.Value;
+  Q_ASSERT(d->LookupTable.GetPointer());
+  double rgb[3];
+  d->LookupTable->GetColor(pos, rgb);
+  double alpha = d->LookupTable->GetOpacity(pos);
+  return QColor::fromRgbF(rgb[0], rgb[1], rgb[2], alpha);
 }
+
 //-----------------------------------------------------------------------------
 int ctkVTKLookupTable::insertControlPoint(const ctkControlPoint& cp)
 {
@@ -173,6 +176,7 @@ int ctkVTKLookupTable::insertControlPoint(const ctkControlPoint& cp)
   qDebug() << "ctkVTKLookupTable doesn't support insertControlPoint";
   return -1;
 }
+
 //-----------------------------------------------------------------------------
 // insert point with value = 0
 int ctkVTKLookupTable::insertControlPoint(qreal pos)

+ 20 - 10
Libs/Visualization/VTK/Core/ctkVTKPiecewiseFunction.cpp

@@ -163,17 +163,27 @@ ctkControlPoint* ctkVTKPiecewiseFunction::controlPoint(int index)const
   ctkNonLinearControlPoint* cp = new ctkNonLinearControlPoint();
   cp->P.X = values[0];
   cp->P.Value = values[1];
-  d->PiecewiseFunction->GetNodeValue(index + 1, values);
-
-
-  Q_ASSERT(values[0] >= range[0] && values[0] <= range[1]  &&  // X
-           values[1] >= rangeY[0].toDouble() && values[1] <= rangeY[1].toDouble()  &&  // Y
-           values[2] >= 0. && values[2] <= 1. &&                // Midpoint
-           values[3] >= 0. && values[3] <= 1. );                // Sharpness
-
+  // Optimization: don't use Subpoints if sharpness == 0
+  if (values[3] == 0.)
+    {
+    cp->SubPoints << ctkPoint(values[0], values[1]);
+    } 
+  double nextValues[4];
+  d->PiecewiseFunction->GetNodeValue(index + 1, nextValues);
+
+  Q_ASSERT(nextValues[0] >= range[0] && nextValues[0] <= range[1]  &&  // X
+           nextValues[1] >= rangeY[0].toDouble() && nextValues[1] <= rangeY[1].toDouble()  &&  // Y
+           nextValues[2] >= 0. && nextValues[2] <= 1. &&                // Midpoint
+           nextValues[3] >= 0. && nextValues[3] <= 1. );                // Sharpness
+  // Optimization: Don't use Subpoints if sharpness == 0
+  if (values[3] == 0.)
+    {
+    cp->SubPoints << ctkPoint(nextValues[0], nextValues[1]);
+    return cp;
+    }
   double subPoints[100];
-  d->PiecewiseFunction->GetTable(cp->x(), values[0], 100, subPoints);
-  qreal interval = (values[0] - cp->x()) / 99.;
+  d->PiecewiseFunction->GetTable(cp->x(), nextValues[0], 100, subPoints);
+  qreal interval = (nextValues[0] - cp->x()) / 99.;
 
   // subPoints[i] since value varies (not like in color transfer function widget)
   for(int i = 0; i < 100; ++i)

+ 2 - 0
Libs/Visualization/VTK/Widgets/Testing/Cpp/CMakeLists.txt

@@ -4,6 +4,7 @@ CREATE_TEST_SOURCELIST(Tests ${KIT}CppTests.cpp
   ctkTransferFunctionWidgetTest1.cpp
   ctkTransferFunctionWidgetTest2.cpp
   ctkTransferFunctionWidgetTest3.cpp
+  ctkTransferFunctionWidgetTest4.cpp
   #EXTRA_INCLUDE TestingMacros.h
   )
 
@@ -33,3 +34,4 @@ ENDMACRO( SIMPLE_TEST  )
 SIMPLE_TEST( ctkTransferFunctionWidgetTest1 )
 SIMPLE_TEST( ctkTransferFunctionWidgetTest2 )
 SIMPLE_TEST( ctkTransferFunctionWidgetTest3 )
+SIMPLE_TEST( ctkTransferFunctionWidgetTest4 )

+ 3 - 3
Libs/Visualization/VTK/Widgets/Testing/Cpp/ctkTransferFunctionWidgetTest3.cpp

@@ -55,8 +55,8 @@ int ctkTransferFunctionWidgetTest3(int argc, char * argv [] )
   // the widget is not really shown here, only when app.exec() is called
   transferFunctionWidget.show();
 
-//  QTimer autoExit;
-//  QObject::connect(&autoExit, SIGNAL(timeout()), &app, SLOT(quit()));
-//  autoExit.start(1000);
+  QTimer autoExit;
+  QObject::connect(&autoExit, SIGNAL(timeout()), &app, SLOT(quit()));
+  autoExit.start(1000);
   return app.exec();
 }

+ 38 - 26
Libs/Widgets/ctkTransferFunctionControlPointsItem.cpp

@@ -30,6 +30,7 @@
 /// CTK includes
 #include "ctkTransferFunctionControlPointsItem.h"
 #include "ctkTransferFunctionScene.h"
+#include "ctkTransferFunctionWidget.h"
 
 //-----------------------------------------------------------------------------
 class ctkTransferFunctionControlPointsItemPrivate: 
@@ -39,14 +40,14 @@ public:
   ctkTransferFunctionControlPointsItemPrivate();
   void init();
   QList<QPointF> ControlPoints;
-  QSizeF         PointSize;
+  QSize          PointSize;
   int            SelectedPoint;
 };
 
 //-----------------------------------------------------------------------------
 ctkTransferFunctionControlPointsItemPrivate::ctkTransferFunctionControlPointsItemPrivate()
 {
-  this->PointSize = QSizeF(0.01,0.01);
+  this->PointSize = QSize(12,12);
   this->SelectedPoint = -1;
 }
 
@@ -94,21 +95,25 @@ void ctkTransferFunctionControlPointsItem::paint(
   Q_ASSERT(tfScene);
   
   const QPainterPath& curve = tfScene->curve();
-  painter->setRenderHint(QPainter::Antialiasing);
   QPen pen(QColor(255, 255, 255, 191), 1);
   pen.setCosmetic(true);
   painter->setPen(pen);
   painter->drawPath(curve);
 
   d->ControlPoints = tfScene->points();
-  QPainterPath points;
-  points.setFillRule(Qt::WindingFill);
+  painter->setBrush(QBrush(QColor(191, 191, 191, 127)));
+  painter->save();
+  QTransform transform = painter->transform();
+  painter->setTransform(QTransform());
   foreach(const QPointF& point, d->ControlPoints)
     {
-    points.addEllipse(point, d->PointSize.width(), d->PointSize.height());
+    QPointF pos = transform.map(point);
+    painter->drawEllipse(pos.x() - d->PointSize.width() / 2, 
+                         pos.y() - d->PointSize.height() / 2, 
+                         d->PointSize.width(), d->PointSize.width());
+    //points.addEllipse(point, d->PointSize.width(), d->PointSize.height());
     }
-  painter->setBrush(QBrush(QColor(191, 191, 191, 127)));
-  painter->drawPath(points);
+  painter->restore();
 }
 
 //-----------------------------------------------------------------------------
@@ -116,31 +121,35 @@ void ctkTransferFunctionControlPointsItem::mousePressEvent(QGraphicsSceneMouseEv
 {
   qDebug() << "mouse press caught";
   CTK_D(ctkTransferFunctionControlPointsItem);
-  QRectF pointArea(QPointF(0,0), d->PointSize*2.);
+  QWidget* w = e->widget();
+  ctkTransferFunctionWidget* view = qobject_cast<ctkTransferFunctionWidget*>(e->widget()->parentWidget());
+  Q_ASSERT(view);
+  // e->pos() is ok, pointArea should be in the world coordiate
+  QRect pointViewArea(QPoint(-d->PointSize.width() / 2, -d->PointSize.height() / 2), d->PointSize);
+  QPolygonF pointItemArea = this->mapFromScene(view->mapToScene(pointViewArea));
   d->SelectedPoint = -1;
   for(int i = 0; i < d->ControlPoints.count(); ++i)
     {
-    pointArea.moveCenter(d->ControlPoints[i]);
-    if (pointArea.contains(e->pos()))
+    if (pointItemArea.translated(d->ControlPoints[i]).containsPoint(e->pos(), Qt::OddEvenFill))
       {
       d->SelectedPoint = i;
       break;
       }
     }
-  if (d->SelectedPoint < 0)
+  if (d->SelectedPoint >= 0)
     {
-    //QPointF currentPoint( e->pos() );
-  //  e->pos()->x();
-    //this->transferFunction()->insertControlPoint( e->pos().x() );
-
+    return;
+    }
+  ctkTransferFunctionScene* tfScene = dynamic_cast<ctkTransferFunctionScene*>(this->scene());
+  Q_ASSERT(tfScene);
+  
   // convert coordinates
-  QPointF functionCoordinates = screen2TransferFunctionCoordinates( e->pos().x(), e->pos().y());
+  QPointF tfPos = tfScene->mapPointFromScene(e->pos());
   // add point to transfer function
   // returns index
-  int index = this->transferFunction()->insertControlPoint( functionCoordinates.x());
+  int index = this->transferFunction()->insertControlPoint( tfPos.x());
   // update value of the point
-  this->transferFunction()->setControlPointValue( index, functionCoordinates.y());
-    }
+  this->transferFunction()->setControlPointValue( index, tfPos.y());
 }
 
 //-----------------------------------------------------------------------------
@@ -153,12 +162,15 @@ void ctkTransferFunctionControlPointsItem::mouseMoveEvent(QGraphicsSceneMouseEve
     e->ignore();
     return;
     }
-  qreal range[2];
-  this->transferFunction()->range(range);
-  qreal newPos = range[0] + e->pos().x() / (this->rect().width() / (range[1] - range[0]));
-  newPos = qBound(range[0], newPos, range[1]);
-  this->transferFunction()->setControlPointPos(d->SelectedPoint, newPos);
-  //this->transferFunction()->setControlPointValue(d->SelectedPoint, e->y());
+  //qreal range[2];
+  //this->transferFunction()->range(range);
+  //qreal newPos = range[0] + e->pos().x() / (this->rect().width() / (range[1] - range[0]));
+  //newPos = qBound(range[0], newPos, range[1]);
+  ctkTransferFunctionScene* tfScene = dynamic_cast<ctkTransferFunctionScene*>(this->scene());
+  Q_ASSERT(tfScene);
+  QPointF newPos = tfScene->mapPointFromScene(e->pos());
+  this->transferFunction()->setControlPointPos(d->SelectedPoint, newPos.x());
+  this->transferFunction()->setControlPointValue(d->SelectedPoint, newPos.y());
 }
 
 //-----------------------------------------------------------------------------

+ 5 - 99
Libs/Widgets/ctkTransferFunctionGradientItem.cpp

@@ -30,6 +30,7 @@
 /// CTK includes
 #include "ctkTransferFunction.h"
 #include "ctkTransferFunctionGradientItem.h"
+#include "ctkTransferFunctionScene.h"
 
 //-----------------------------------------------------------------------------
 ctkTransferFunctionGradientItem::ctkTransferFunctionGradientItem(QGraphicsItem* parentGraphicsItem)
@@ -53,105 +54,10 @@ ctkTransferFunctionGradientItem::~ctkTransferFunctionGradientItem()
 void ctkTransferFunctionGradientItem::paint(
   QPainter * painter, const QStyleOptionGraphicsItem * option, QWidget * widget)
 {
-  int count = this->transferFunction() ? this->transferFunction()->count() : 0;
-  if (count <= 0)
-    {
-    painter->fillRect(this->rect(),Qt::black);
-    return;
-    }
-  qreal range[2];
-  this->transferFunction()->range(range);
-  qreal rangeDiff = this->rect().width() / (range[1] - range[0]);
-  qreal rangeOffset = range[0];
-  ctkControlPoint* startCP = this->transferFunction()->controlPoint(0);
-  ctkControlPoint* endCP = 0;
+  ctkTransferFunctionScene* tfScene = dynamic_cast<ctkTransferFunctionScene*>(this->scene());
+  Q_ASSERT(tfScene);
   
-  qreal start = (startCP->x() - rangeOffset) * rangeDiff;
-  qreal end = 0;
-  for(int i = 1; i < count; ++i)
-    {
-    endCP = this->transferFunction()->controlPoint(i);
-    // TODO, handle Bezier points for a finer gradient
-    // TODO, handle nonlinear points
-    if (this->transferFunction()->isDiscrete())
-      {
-      // pos
-      end = ((startCP->x() + endCP->x()) /2. -rangeOffset) * rangeDiff;
-      QRectF itemRect = QRectF(start, 0, end - start, 
-                               this->rect().height());
-      if (i==1)
-        {
-        itemRect.setLeft(0.);
-        }
-      QColor valueColor = this->color(startCP->value());
-      // paint
-      painter->fillRect(itemRect, valueColor);
-      // draw the last item
-      if (i == count -1)
-        {
-        //pos
-        itemRect = QRectF(end, 0, this->rect().width(), 
-                          this->rect().height());
-        // color
-        valueColor = this->color(endCP->value());
-        // paint
-        painter->fillRect(itemRect, valueColor);
-        }
-      }
-    else if (dynamic_cast<ctkNonLinearControlPoint*>(startCP) != 0)
-      {
-      QList<ctkPoint> points = this->nonLinearPoints(startCP, endCP);
-      for (int j = 1; j < points.count(); ++j)
-        {
-        // pos
-        end = (points[j].X - rangeOffset) * rangeDiff;
-        QRectF itemRect = QRectF(start, 0, end - start, 
-                                 this->rect().height());
-        if (i==1 && j == 1)
-          {
-          itemRect.setLeft(0.);
-          }
-        if ((i == count -1) && (j == points.count() -1))
-          {
-          itemRect.setRight(this->rect().width());
-          }
-        // color
-        QLinearGradient gradient(start, 0, end, 0);
-        gradient.setColorAt(0, this->color(points[j-1]));
-        gradient.setColorAt(1, this->color(points[j]));
-        // paint
-        painter->fillRect(itemRect, gradient);
-        start = end;
-        }
-      }
-    else
-      {
-      // pos
-      end = (endCP->x() - rangeOffset) * rangeDiff;
-      QRectF itemRect = QRectF(start, 0, end - start, 
-                               this->rect().height());
-      if (i==1)
-        {
-        itemRect.setLeft(0.);
-        }
-      if (i == count -1)
-        {
-        itemRect.setRight(this->rect().width());
-        }
-      // color
-      QLinearGradient gradient(start, 0, end, 0);
-      gradient.setColorAt(0, this->color(startCP->value()));
-      gradient.setColorAt(1, this->color(endCP->value()));
-      // paint
-      painter->fillRect(itemRect, gradient);
-      }
-    delete startCP;
-    startCP = endCP;
-    start = end;
-    }
-  if (startCP)
-    {
-    delete startCP;
-    }
+  const QGradient& gradient = tfScene->gradient();
+  painter->fillRect(this->rect(), gradient);
 }
 

+ 109 - 30
Libs/Widgets/ctkTransferFunctionScene.cpp

@@ -19,6 +19,7 @@
 =========================================================================*/
 /// Qt includes
 #include <QGraphicsScene>
+#include <QLinearGradient>
 #include <QResizeEvent>
 #include <QDebug>
 
@@ -26,6 +27,9 @@
 #include "ctkTransferFunction.h"
 #include "ctkTransferFunctionScene.h"
 
+/// STL includes
+#include <limits>
+
 //-----------------------------------------------------------------------------
 class ctkTransferFunctionScenePrivate: public ctkPrivate<ctkTransferFunctionScene>
 {
@@ -35,6 +39,7 @@ public:
   QRectF               OldRect;
   ctkTransferFunction* TransferFunction;
   QPainterPath   Path;
+  QLinearGradient Gradient;
   QList<QPointF> Points;
   qreal        WorldRangeX[2];
   QVariant     WorldRangeY[2];
@@ -106,6 +111,7 @@ const QPainterPath& ctkTransferFunctionScene::curve()const
   if (d->Path.isEmpty())// || this->sceneRect() != d->OldRect)
     {
     const_cast<ctkTransferFunctionScene*>(this)->computeCurve();
+    const_cast<ctkTransferFunctionScene*>(this)->computeGradient();
     }
   return d->Path;
 }
@@ -117,11 +123,24 @@ const QList<QPointF>& ctkTransferFunctionScene::points()const
   if (d->Path.isEmpty())// || this->sceneRect() != d->OldRect)
     {
     const_cast<ctkTransferFunctionScene*>(this)->computeCurve();
+    const_cast<ctkTransferFunctionScene*>(this)->computeGradient();
     }
   return d->Points;
 }
 
 //-----------------------------------------------------------------------------
+const QGradient& ctkTransferFunctionScene::gradient()const
+{
+  CTK_D(const ctkTransferFunctionScene);
+  if (d->Path.isEmpty())// || this->sceneRect() != d->OldRect)
+    {
+    const_cast<ctkTransferFunctionScene*>(this)->computeCurve();
+    const_cast<ctkTransferFunctionScene*>(this)->computeGradient();
+    }
+  return d->Gradient;
+}
+
+//-----------------------------------------------------------------------------
 void ctkTransferFunctionScene::computeCurve()
 {
   CTK_D(ctkTransferFunctionScene);
@@ -133,8 +152,8 @@ void ctkTransferFunctionScene::computeCurve()
     }
   qDebug() << "computeCurve" << this->sceneRect();
   d->TransferFunction->range(d->WorldRangeX[0], d->WorldRangeX[1]);
-  d->WorldRangeY[0] = this->y(d->TransferFunction->minValue());
-  d->WorldRangeY[1] = this->y(d->TransferFunction->maxValue());
+  d->WorldRangeY[0] = this->posY(d->TransferFunction->minValue());
+  d->WorldRangeY[1] = this->posY(d->TransferFunction->maxValue());
 
   d->RangeXDiff   = this->computeRangeXDiff(this->sceneRect(), d->WorldRangeX);
   d->RangeXOffSet = this->computeRangeXOffset(d->WorldRangeX);
@@ -145,7 +164,7 @@ void ctkTransferFunctionScene::computeCurve()
   ctkControlPoint* startCP = d->TransferFunction->controlPoint(0);
   ctkControlPoint* nextCP = 0;
 
-  QPointF startPos = this->mapPointToScreen(startCP);
+  QPointF startPos = this->mapPointToScene(startCP);
   
   d->Points.clear();
   d->Points << startPos;
@@ -161,10 +180,10 @@ void ctkTransferFunctionScene::computeCurve()
       int j;
       for (j = 1; j < points.count(); ++j)
         {
-        d->Path.lineTo(this->mapPointToScreen(points[j]));
+        d->Path.lineTo(this->mapPointToScene(points[j]));
         }
       j = points.count() - 1;
-      d->Points << this->mapPointToScreen(points[j]);
+      d->Points << this->mapPointToScene(points[j]);
       }
     else //dynamic_cast<ctkBezierControlPoint*>(startCP))
       {
@@ -173,7 +192,7 @@ void ctkTransferFunctionScene::computeCurve()
       QList<QPointF> bezierPoints;
       foreach(const ctkPoint& p, points)
         {
-        bezierPoints << this->mapPointToScreen(p);
+        bezierPoints << this->mapPointToScene(p);
         }
       d->Path.cubicTo(bezierPoints[1], bezierPoints[2], bezierPoints[3]);
       d->Points << bezierPoints[3];
@@ -189,6 +208,78 @@ void ctkTransferFunctionScene::computeCurve()
 }
 
 //-----------------------------------------------------------------------------
+void ctkTransferFunctionScene::computeGradient()
+{
+  CTK_D(ctkTransferFunctionScene);
+
+  int count = d->TransferFunction ? d->TransferFunction->count() : 0;
+  if (count <= 0)
+    {
+    return;
+    }
+  qDebug() << "computeCurve" << this->sceneRect();
+  d->TransferFunction->range(d->WorldRangeX[0], d->WorldRangeX[1]);
+  d->WorldRangeY[0] = this->posY(d->TransferFunction->minValue());
+  d->WorldRangeY[1] = this->posY(d->TransferFunction->maxValue());
+
+  d->RangeXDiff   = this->computeRangeXDiff(QRectF(0.,0.,1.,1.), d->WorldRangeX);
+  d->RangeXOffSet = this->computeRangeXOffset(d->WorldRangeX);
+
+  d->RangeYDiff   = this->computeRangeYDiff(QRectF(0.,0.,1.,1.), d->WorldRangeY);
+  d->RangeYOffSet = this->computeRangeYOffset(d->WorldRangeY);
+
+  ctkControlPoint* startCP = d->TransferFunction->controlPoint(0);
+  ctkControlPoint* nextCP = 0;
+
+  qreal startPos = this->mapXToScene(this->posX(startCP->x()));
+  qreal nextPos;
+  
+  d->Gradient = QLinearGradient(0., 0., 1., 0.);
+  d->Gradient.setColorAt(startPos, this->color(startCP));
+
+  for(int i = 1; i < count; ++i)
+    {
+    nextCP = d->TransferFunction->controlPoint(i);
+    nextPos = this->mapXToScene(this->posX(nextCP));
+    if (this->transferFunction()->isDiscrete())
+      {
+      qreal midPoint = (startPos + nextPos)  / 2;
+      d->Gradient.setColorAt(midPoint, this->color(startCP));
+      d->Gradient.setColorAt(midPoint + std::numeric_limits<qreal>::epsilon(), this->color(nextCP));
+      }
+    else if (dynamic_cast<ctkNonLinearControlPoint*>(startCP))
+      {
+      QList<ctkPoint> points = this->nonLinearPoints(startCP, nextCP);
+      foreach(const ctkPoint& p, points)
+        {
+        d->Gradient.setColorAt(this->mapXToScene(this->posX(p)), this->color(p));
+        }
+      //no need, d->Gradient.setColorAt(nextPos, this->color(nextCP));
+      }
+    else //dynamic_cast<ctkBezierControlPoint*>(startCP))
+      { // TODO handle bezier points with color
+      QList<ctkPoint> points = this->bezierParams(startCP, nextCP);
+      QList<ctkPoint>::iterator it = points.begin();
+      QList<QPointF> bezierPoints;
+      foreach(const ctkPoint& p, points)
+        {
+        d->Gradient.setColorAt(this->mapXToScene(this->posX(p)), this->color(p));
+        }
+      nextPos = this->mapXToScene(this->posX(points[points.size() - 1])); 
+      }
+    //qDebug() << i << points[0] << points[1] << points[2] << points[3];
+    delete startCP;
+    startCP = nextCP;
+    startPos = nextPos;
+    }
+  d->Gradient.setColorAt(startPos, this->color(startCP));
+  if (startCP)
+    {
+    delete startCP;
+    }
+}
+
+//-----------------------------------------------------------------------------
 QList<ctkPoint> ctkTransferFunctionScene::bezierParams(
   ctkControlPoint* start, ctkControlPoint* end) const
 {
@@ -231,18 +322,6 @@ QList<ctkPoint> ctkTransferFunctionScene::nonLinearPoints(
   return nonLinearCP->SubPoints;
 }
 
-
-//-----------------------------------------------------------------------------
-qreal ctkTransferFunctionScene::y(const QVariant& v) const
-{ 
-  Q_ASSERT(v.canConvert<qreal>() || v.canConvert<QColor>());
-  if (v.canConvert<QColor>())
-    {
-    return v.value<QColor>().alphaF();
-    }
-  return v.toReal();
-}
-
 //-----------------------------------------------------------------------------
 QColor ctkTransferFunctionScene::color(const QVariant& v) const
 { 
@@ -320,43 +399,43 @@ qreal ctkTransferFunctionScene::posY(const QVariant& value)const
 }
 
 //-----------------------------------------------------------------------------
-QPointF ctkTransferFunctionScene::mapPointToScreen(const ctkControlPoint* cp)const
+QPointF ctkTransferFunctionScene::mapPointToScene(const ctkControlPoint* cp)const
 {
-  return QPointF(this->mapXToScreen(this->posX(cp->x())),
-                 this->mapYToScreen(this->posY(cp->value())));
+  return QPointF(this->mapXToScene(this->posX(cp->x())),
+                 this->mapYToScene(this->posY(cp->value())));
 }
 
 //-----------------------------------------------------------------------------
-QPointF ctkTransferFunctionScene::mapPointToScreen(const ctkPoint& point)const
+QPointF ctkTransferFunctionScene::mapPointToScene(const ctkPoint& point)const
 {
-  return QPointF( this->mapXToScreen(this->posX(point.X)),
-                  this->mapYToScreen(this->posY(point.Value)));
+  return QPointF( this->mapXToScene(this->posX(point.X)),
+                  this->mapYToScene(this->posY(point.Value)));
 }
 
 //-----------------------------------------------------------------------------
-qreal ctkTransferFunctionScene::mapXToScreen(qreal xPos)const
+qreal ctkTransferFunctionScene::mapXToScene(qreal xPos)const
 {
   CTK_D(const ctkTransferFunctionScene);
   return (xPos - d->RangeXOffSet) * d->RangeXDiff;
 }
 
 //-----------------------------------------------------------------------------
-qreal ctkTransferFunctionScene::mapYToScreen(qreal yPos)const
+qreal ctkTransferFunctionScene::mapYToScene(qreal yPos)const
 {
   CTK_D(const ctkTransferFunctionScene);
   return this->height() - (yPos - d->RangeYOffSet) * d->RangeYDiff;
 }
 
 //-----------------------------------------------------------------------------
-qreal ctkTransferFunctionScene::mapXFromScreen(qreal screenPosX)const
+qreal ctkTransferFunctionScene::mapXFromScene(qreal scenePosX)const
 {
   CTK_D(const ctkTransferFunctionScene);
-  return (screenPosX / d->RangeXDiff) + d->RangeXOffSet;
+  return (scenePosX / d->RangeXDiff) + d->RangeXOffSet;
 }
 
 //-----------------------------------------------------------------------------
-qreal ctkTransferFunctionScene::mapYFromScreen(qreal screenPosY)const
+qreal ctkTransferFunctionScene::mapYFromScene(qreal scenePosY)const
 {
   CTK_D(const ctkTransferFunctionScene);
-  return ((this->height() - screenPosY) / d->RangeYDiff) + d->RangeYOffSet ;
+  return ((this->height() - scenePosY) / d->RangeYDiff) + d->RangeYOffSet ;
 }

+ 58 - 14
Libs/Widgets/ctkTransferFunctionScene.h

@@ -25,13 +25,14 @@
 #include <QGraphicsScene>
 
 /// CTK includes
-#include "CTKWidgetsExport.h"
 #include "ctkPimpl.h"
+#include "ctkTransferFunction.h"
+#include "CTKWidgetsExport.h"
 
-class ctkTransferFunction;
+//class ctkTransferFunction;
 class ctkTransferFunctionScenePrivate;
-class ctkControlPoint;
-class ctkPoint;
+//class ctkControlPoint;
+//class ctkPoint;
 
 //-----------------------------------------------------------------------------
 class CTK_WIDGETS_EXPORT ctkTransferFunctionScene: public QGraphicsScene
@@ -45,26 +46,37 @@ public:
   void setTransferFunction(ctkTransferFunction* transferFunction);
   ctkTransferFunction* transferFunction()const;
 
-  qreal y(const QVariant& v) const;
-  QColor color(const QVariant& v) const;
+  inline qreal posX(const ctkControlPoint* cp)const;
+  inline qreal posY(const ctkControlPoint* cp)const;
+  inline QColor color(const ctkControlPoint* cp) const;
 
-  qreal posX(const qreal& x)const;
-  qreal posY(const QVariant& value)const;
+  inline qreal posX(const ctkPoint& point)const;
+  inline qreal posY(const ctkPoint& point)const;
+  inline QColor color(const ctkPoint& point) const;
+
+  qreal posX(const qreal& tfX)const;
+  qreal posY(const QVariant& tfV)const;
+  QColor color(const QVariant& tfV) const;
+  
+  QPointF mapPointToScene(const ctkControlPoint* cp)const;
+  QPointF mapPointToScene(const ctkPoint& point)const;
   
-  QPointF mapPointToScreen(const ctkControlPoint* cp)const;
-  QPointF mapPointToScreen(const ctkPoint& point)const;
  
-  qreal mapXToScreen(qreal posX)const;
-  qreal mapYToScreen(qreal posY)const;
-  qreal mapXFromScreen(qreal screenPosX)const;
-  qreal mapYFromScreen(qreal screenPosY)const;
+  qreal mapXToScene(qreal posX)const;
+  qreal mapYToScene(qreal posY)const;
+  qreal mapXFromScene(qreal ScenePosX)const;
+  qreal mapYFromScene(qreal ScenePosY)const;
+  inline QPointF mapPointFromScene(const QPointF& point)const;
 
   QList<ctkPoint> bezierParams(ctkControlPoint* start, ctkControlPoint* end) const;
   QList<ctkPoint> nonLinearPoints(ctkControlPoint* start, ctkControlPoint* end) const;
 
   const QPainterPath& curve()const;
   const QList<QPointF>& points()const;
+  const QGradient& gradient()const;
+
   void computeCurve();
+  void computeGradient();
 
 protected slots:
   virtual void onTransferFunctionChanged();
@@ -78,4 +90,36 @@ private:
   CTK_DECLARE_PRIVATE(ctkTransferFunctionScene);
 };
 
+qreal ctkTransferFunctionScene::posX(const ctkControlPoint* cp)const
+{
+  return this->posX(cp->x());
+}
+qreal ctkTransferFunctionScene::posY(const ctkControlPoint* cp)const
+{
+  return this->posY(cp->value());
+}
+QColor ctkTransferFunctionScene::color(const ctkControlPoint* cp) const
+{
+  return this->color(cp->value());
+}
+
+qreal ctkTransferFunctionScene::posX(const ctkPoint& point)const
+{
+  return this->posX(point.X);
+}
+qreal ctkTransferFunctionScene::posY(const ctkPoint& point)const
+{
+  return this->posY(point.Value);
+}
+QColor ctkTransferFunctionScene::color(const ctkPoint& point) const
+{
+  return this->color(point.Value);
+}
+
+QPointF ctkTransferFunctionScene::mapPointFromScene(const QPointF& point)const
+{
+  return QPointF(this->mapXFromScene(point.x()),
+                 this->mapYFromScene(point.y()));
+}
+
 #endif

+ 1 - 0
Libs/Widgets/ctkTransferFunctionWidget.cpp

@@ -54,6 +54,7 @@ void ctkTransferFunctionWidgetPrivate::init()
   p->setHorizontalScrollBarPolicy(Qt::ScrollBarAlwaysOff);
   p->setVerticalScrollBarPolicy(Qt::ScrollBarAlwaysOff);
   //p->setViewport(new QGLWidget);
+  p->setRenderHint(QPainter::Antialiasing);
 }
 
 //-----------------------------------------------------------------------------

+ 28 - 15
Utilities/CMake/FindDCMTK.cmake

@@ -97,6 +97,26 @@ FIND_LIBRARY( DCMTK_dcmdata_LIBRARY dcmdata
   NO_DEFAULT_PATH
 )
 
+FIND_PATH( DCMTK_dcmnet_INCLUDE_DIR dimse.h
+  PATHS
+    ${DCMTK_DIR}/include/dcmnet
+    ${DCMTK_DIR}/include/dcmtk/dcmnet
+    ${DCMTK_DIR}/dcmnet
+    ${DCMTK_DIR}/dcmnet/include
+  NO_DEFAULT_PATH
+)
+
+FIND_LIBRARY( DCMTK_dcmnet_LIBRARY dcmnet
+  PATHS
+    ${DCMTK_DIR}/dcmnet/libsrc
+    ${DCMTK_DIR}/dcmnet/libsrc/Release
+    ${DCMTK_DIR}/dcmnet/libsrc/Debug
+    ${DCMTK_DIR}/dcmnet/Release
+    ${DCMTK_DIR}/dcmnet/Debug
+    ${DCMTK_DIR}/lib
+  NO_DEFAULT_PATH
+)
+
 FIND_PATH( DCMTK_dcmimgle_INCLUDE_DIR dcmimage.h
   PATHS
     ${DCMTK_DIR}/dcmimgle/include
@@ -126,20 +146,14 @@ FIND_LIBRARY(DCMTK_imagedb_LIBRARY imagedb
   NO_DEFAULT_PATH
   )
 
-FIND_LIBRARY(DCMTK_dcmnet_LIBRARY dcmnet
-  PATHS
-    ${DCMTK_DIR}/dcmnet/libsrc/Release
-    ${DCMTK_DIR}/dcmnet/libsrc/Debug
-    ${DCMTK_DIR}/dcmnet/libsrc/
-  NO_DEFAULT_PATH
-  )
-
 IF( DCMTK_config_INCLUDE_DIR 
     AND DCMTK_ofstd_INCLUDE_DIR 
     AND DCMTK_ofstd_LIBRARY
     AND DCMTK_oflog_LIBRARY
     AND DCMTK_dcmdata_INCLUDE_DIR
     AND DCMTK_dcmdata_LIBRARY
+    AND DCMTK_dcmnet_INCLUDE_DIR
+    AND DCMTK_dcmnet_LIBRARY    
     AND DCMTK_dcmimgle_INCLUDE_DIR
     AND DCMTK_dcmimgle_LIBRARY )
 
@@ -159,11 +173,13 @@ IF( DCMTK_config_INCLUDE_DIR
     ${DCMTK_config_INCLUDE_DIR}
     ${DCMTK_ofstd_INCLUDE_DIR}
     ${DCMTK_dcmdata_INCLUDE_DIR}
+    ${DCMTK_dcmnet_INCLUDE_DIR}
     ${DCMTK_dcmimgle_INCLUDE_DIR}
   )
 
   SET( DCMTK_LIBRARIES
     ${DCMTK_dcmimgle_LIBRARY}
+    ${DCMTK_dcmnet_LIBRARY}    
     ${DCMTK_dcmdata_LIBRARY}
     ${DCMTK_ofstd_LIBRARY}
     ${DCMTK_oflog_LIBRARY}
@@ -177,13 +193,6 @@ IF( DCMTK_config_INCLUDE_DIR
    )
   ENDIF(DCMTK_imagedb_LIBRARY)
 
-  IF(DCMTK_dcmnet_LIBRARY)
-   SET( DCMTK_LIBRARIES
-   ${DCMTK_LIBRARIES}
-   ${DCMTK_dcmnet_LIBRARY}
-   )
-  ENDIF(DCMTK_dcmnet_LIBRARY)
-
   IF( WIN32 )
     SET( DCMTK_LIBRARIES ${DCMTK_LIBRARIES} ws2_32 netapi32 wsock32)
   ENDIF( WIN32 )
@@ -198,6 +207,8 @@ ENDIF( DCMTK_config_INCLUDE_DIR
     AND DCMTK_oflog_LIBRARY
     AND DCMTK_dcmdata_INCLUDE_DIR
     AND DCMTK_dcmdata_LIBRARY
+    AND DCMTK_dcmnet_INCLUDE_DIR
+    AND DCMTK_dcmnet_LIBRARY    
     AND DCMTK_dcmimgle_INCLUDE_DIR
     AND DCMTK_dcmimgle_LIBRARY )
 
@@ -226,6 +237,8 @@ MARK_AS_ADVANCED(
   DCMTK_config_INCLUDE_DIR
   DCMTK_dcmdata_INCLUDE_DIR
   DCMTK_dcmdata_LIBRARY
+  DCMTK_dcmnet_INCLUDE_DIR
+  DCMTK_dcmnet_LIBRARY
   DCMTK_dcmimgle_INCLUDE_DIR
   DCMTK_dcmimgle_LIBRARY
   DCMTK_imagedb_LIBRARY